LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
Jim_Kring

"Enumerated Variant" Data Type (like Rust and Zig have)

Status: New

See this github repository for a more complete proposal and an example implementation that gets us c....

Some languages like Rust and Zig have a feature called Tagged Enums (or Sum Types) that allow you to create a data type that can be one of a few different types where there is a name associated with each type. In LabVIEW, however, Enums are limited to consecutive numeric integer values -- there's no way to associate a type with each named value.

 

The power of combining an Enum with a data type for each value is that we could potentially use a Case Structure as a switch statement with type assertion and data conversion built in! This would allow us to create robust, type-safe code that is easier to maintain and understand.

 

example_equipment_variant.png

See this github repository for a more complete proposal and an example implementation that gets us c....

19 Comments
Jim_Kring
Trusted Enthusiast

Here are some better screenshots of what this might look like if it were a natively feature in LabVIEW.

 

2024-03-24_00-12-36.png

 

2024-03-24_00-31-45.png2024-03-24_00-34-14.png

 

I think it should be related to an LVLib or LVClass in the sense that it should be allowed to have methods associated with it. It might even make sense to allow it to inherit from Interfaces (which it could implement and do static dispatching inside a Case Structure in the method).

raphschru
Active Participant

Hi Jim,

 

What about using classes entirely and replacing your case structure with a dynamic dispatch method?

I guess your idea would avoid the need to wrap all your types in classes, right?

 

Also, how would you get your enumerated variant back as an output of the case structure? A special output tunnel? Or maybe a new type of structure that would be an hybrid between a case structure and an IPE structure? Otherwise, you would need a "To Equipement Enumerated Variant" inside all your case diagrams...

 

Regards,

Raphaël.

Jim_Kring
Trusted Enthusiast

Hi Raphaël,

> What about using classes entirely and replacing your case structure with a dynamic dispatch method?

I guess your idea would avoid the need to wrap all your types in classes, right?

 

That's a great question.  You're right that the Enumerated Variant idea I suggested avoids needing to create a wrapper/adapter class around each type to be included in the enumeration (some of which may be classes/interfaces, themselves) -- that would get very "heavy" with boilerplate code (an lvclass + a method for each type).

The fact is, inheritance and dynamic dispatch are great features, yet there are also many cases where it's advantageous to statically define a set of types.

 

If we don't really need the our set of types to be "plug ins" (e.g. we don't have a real use case for dynamic loading and abstraction), then why pay for the extra development and runtime performance overhead of dynamic dispatch?

> Also, how would you get your enumerated variant back as an output of the case structure? A special output tunnel? Or maybe a new type of structure that would be an hybrid between a case structure and an IPE structure? Otherwise, you would need a "To Equipement Enumerated Variant" inside all your case diagrams...

Yes, you're right about that, too.

Either (A) LabVIEW would need to enhance the Case Select Terminal to do the type conversion automatically, so that we get the specific type on the inner terminal of each case frame like this:

2024-03-24_00-12-36.png

Or, (B) we need to have some utility VIs (in our in our Enumerated Variant class) to do the type checking and conversion ourselves, as shown here:

 

2024-03-24_00-24-11.png

 

raphschru
Active Participant

> Either (A) LabVIEW would need to enhance the Case Select Terminal to do the type conversion automatically [...]

Or, (B) we need to have some utility VIs (in our in our Enumerated Variant class) to do the type checking and conversion ourselves [...]

 

I had well understood how you would want the case structure input to be, I asked about a potential output in case you modify the value inside the case structure and you want an enumerated variant out of the case structure. In the same way as for the input, you would either need a special tunnel or use a conversion VI in each case:

 

raphschru_1-1711308516824.png

 

Or:

raphschru_2-1711309069462.png

 

 

 

Jim_Kring
Trusted Enthusiast

Note: I just did a pretty big rewrite of the proposal and example code, to make it more clear and also to address some of the questions about "why not just use dynamic dispatch"

 

Proposal and Example Here:

https://github.com/JKISoftware/enumerated-variant-labview-idea

wiebe@CARYA
Knight of NI
Jim_Kring
Trusted Enthusiast

Hi Wiebe.  I think that the Wire Class To Case Selector idea is similar in some ways, yet is fundamentally different than what I'm proposing.

 

An "Enumerated Variant" (as I've proposed) could be a set of any datatypes -- i.e. it's not limited to classes and is not coupled to dynamic dispatch or inheritance.

 

Rather, it allows users to create sets of types without the runtime performance overhead and edit-time dependency bloat of class inheritance (in cases where there isn't much benefit of using inheritance and dynamic dispatch).

Intaris
Proven Zealot

I'm generally open to new ideas in LabVIEW, a presentation of Rust in NXG clothes was extremely interesting, but here I'm left asking myself: "What is the problem this is going to solve?" i.e. "Is solving this problem worth adding this to the language?"

 

That aside: I see this as being much more of an extension of variant rather than LVOOP. I realise the LVOOP approach may be provided simply for illustration.... but I would see a new datatype as essentially a "Typed Variant". This can have a "Type Enum" with associated datatypes. This would essentially be a new datatype. We could then have a streamlined API for variant to allow writing and reading the types according to the particular "Type Enum" used to create the "Typed Variant" .It's pure syntactic sugar, essentially encapsulating the variant & Enum approach of the original post. By encapsulating it away from the user, the type safety can be enforced.

 

Adding LVOOP to this idea just opens a few different cans of worms with regard to run-time checking and serialisation / deserialisation (due to long.standing LV design choices that I've refused to be thrilled about for 10 years now). Don't know if that was actually part of the suggestion, just giving my 2c on that aspect.

Jim_Kring
Trusted Enthusiast

Hi Intaris. You’re right,

My proposal is to allow associating a data type with each element of an enum. its benefit is performance of static typing and not requiring the bloat of classes when taking an inheritance with dynamic dispatch approach. This feature would, of course support classes and interfaces, which is why I used a class, an interface, and a visa resource as the difference subtypes in my example.

 

the proof of concept implementation does use a class to encapsulate the boiler plate code required to implement some thing that “feels” as close to the feature/idea as possible.

 

I think this feature doesn’t provide you with anything much “new” That you can’t do already. it would just allow it to be done with minimal boiler plate, code and minimal classes/dependencies to bloat your project. it would probably also result in much more readable code, since there is no dynamic indirection and all the code exists inside of case structure frames for handling different type variants.

wiebe@CARYA
Knight of NI

Could this be: when a cluster is wired to a case selector, use the first enum?

 

Maybe only if the first element is an enum?

 

And maybe also for a class: if the (parent's) private data has an enum as first element, allow us to wire it to a case selector.. (That might be more exposure than we'd like).

 

This might be easier than a new type, a special trick for existing types.