LabVIEW Idea Exchange

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

“Preserve Run-Time Type” for Variants (in analogy to “Preserve Run-Time Class” for Objects)

Status: Declined

 I propose a “Preserve Run-Time Type” primitive for Variants that is analogous to “Preserve Run-Time Class” for Objects.  Below I illustrate, using a system of messages that I'm working on.  Two message types carry either Variants or Objects (LVObject).  In each case I must convert to a specific type (data type or child class) in order to use the messages data.  For this I can use "Variant to Data" or "To More Specific Class", but I need to do the conversion outside my "Read Message" subVIs (top two examples below).

 

However, with Objects I can make a cleaner implementation (third example) where I use "Preserve Run-Time Class" to do the same thing inside the "Read" subVI.  I would like to be able to do the same thing with my Variants but I cannot (but I've faked what it would look like in the forth example).

Preserve Run-Time Type.png

 

The object subVI that uses Preserve Run-Time Class looks like this:

PRTC.png

A subVI using “Preserve Run-Time Type” would look similar, just with Variants in place of Objects.

 

In addition to cleaner code, “Preserve Run-Time Type” would allow additional logic to be built into the Variant to type conversion.  For example, I like to use numerics with units in my messages, as a safety device against message sender and receiver using different units, or confusing what the message represents.  However, one can always convert a numeric with units to a numeric without units by using "Variant to Data" with a non-unit type input.  This defeats some of the safety (eg, sender could send "output" in Watts, but receiver thinks it's in Volts).  I would like to make a message type that performs unit consistency checks inside the "Read" subVI, throwing an error on any mismatch; a “Preserve Run-Time Type" would allow this.

21 Comments
AristosQueue (NI)
NI Employee (retired)

I do not see how this provides any benefit to code. The preservation on objects allows the compiler to know the type safety will hold. But the type safety of Variant To Data is already guaranteed -- nothing can come out of an Int32 terminal other than an Int32. Can you draw a diagram where this primitive you propose would be better than Variant To Data?

 

The poly VI that you build for the Double case, in the picture shown, would alreay suffice to guarantee the type of double coming out.

drjdpowell
Trusted Enthusiast

>I do not see how this provides any benefit to code. The preservation on objects allows the compiler to know the type safety will hold.

>But the type safety of Variant To Data is already guaranteed -- nothing can come out of an Int32 terminal other than an Int32

 

Ah, but I don't want an I32 terminal; I want a Variant terminal.   I want the compiler to know that the datatype exiting a Variant output terminal is the same as the wire type connected to the input Variant terminal, and then use that wire type on the output terminal.  Analogous to how it works with a child wire type and parent class terminals.  A polymorphic VI is not a substitute as it can't handle arbitrary types like clusters and enums and numerics with units, and is prohibitively expensive to code just the simple types plus 1D and 2D arrays thereof.

drjdpowell
Trusted Enthusiast

>Can you draw a diagram where this primitive you propose would be better than Variant To Data?

I guess you're not impressed by the bottom (4th) example being clearer and quicker to wire (and thus better) than the top one?

 

Here, for example, is a VI that sets an arbitrary cluster from a JSON string.  The User has to wire up a "Variant to Data" after the VI.  They have to wire the cluster to two places (with some possibility of miswiring).  Ugly.  And time consuming.

VariantClusterWork.png 

 

I would much rather have it look like this:

ClusterVariantWish.png

Wouldn't that be better?

mawodorfer
Member

A good example for that can by found in the OpenG palette. Take the array functions. When used with standard data types like int or dbl it works fine because it is polymorph. But when using a cluster or typedef you always get a variant as output and not the initial typdef or cluster.

 

That is quite annoying... So I would also like this functionality!

Best Regards
Martin
GregSands
Active Participant

Ahh, yes!  I can see a potential rebirth of the Generic terminal phoenix.  And it would be much easier than creating an XNode (which can achieve the same thing, just not as cleanly).

AristosQueue (NI)
NI Employee (retired)

> Ah, but I don't want an I32 terminal; I want a Variant terminal. 

 

Oh. Then the Preserve Run Time Data Type For Variant primitive won't help you because we couldn't change the terminal output anyway. The only reason that works for classes is that no recompilation of the VI is needed regardless of the actual data type. But one VI can't be compiled for both integers and doubles, for example. You'd need a feature that we've been working on for a while that would let a VI compile in multiple different ways or script new versions of itself or some other variation that we come up with in the future. Unfortunately, that feature is stuck in a research loop -- we've implemented a few variations and they've all sucked in some major way, but we're continuing to work on it. Check back in a couple years. And you won't need the primitive you propose to make it work because other types do not have the same run time type ambiguity that classes have. For that reason, I'm going to ask the forum to decline this idea.

drjdpowell
Trusted Enthusiast

> The only reason that works for classes is that no recompilation of the VI is needed regardless of the actual data type.

> But one VI can't be compiled for both integers and doubles, for example.

 

But surely a variant doesn't require recompiling regardless of actual data type.  Variants have "run time type ambiguity", same as classes.  I only need the subVI compiled for variants, not for any specific type.  The feature you're describing is not what I'm after.  

 

I want two things: (1) a VI that takes two variants and ensures that one contains the same datatype as the other (or throws an error); and (2) the compiler to be able to use this to identify subVI output datatype must match input type and thus do the automatic variant-to-data conversion on the output at compile time.  

drjdpowell
Trusted Enthusiast

Note to whoever marks ideas "declined": please do not confuse this idea with what sounds to be a much, MUCH more complex idea inside NI.  I do not want the subVI modified or recompiled in any way.  The subVI is written with variants, and is otherwise standard except for one new primitive that allows one to ensure that a particular variant output must contain the same data type as a particular input, in direct analogy to "Preserve Run-Time Class" for objects.  

 

Like PRTC, the new primitive would output a default value of the required type, along with an error, if the types do not match.  Then I want the compiler, in compiling the subVI's callers, to be able to use the fact that it knows the type at compile time to implicitly adapt the output wire type (eg. we connected a wire of type XYZ to the input, so we can use a wire of type XYZ on the output).  The compiler already does the same thing with child-class wires and parent-class subVI terminals.  Note that his change is in compiling the caller of the subVI; there is no change in the subVI itself and this has nothing to do with the ideas AQ mentioned.

 

Anyway, please don't decline this idea without consulting developers of the compiler.  I don't think this idea would be that complex to implement.  There are quite  lot of variant-based tools whose APIs would be significantly improved with this feature.

SteenSchmidt
Trusted Enthusiast

@drjdpowell wrote:
I want two things: (1) a VI that takes two variants and ensures that one contains the same datatype as the other (or throws an error); and (2) the compiler to be able to use this to identify subVI output datatype must match input type and thus do the automatic variant-to-data conversion on the output at compile time.

Isn't this exactly what Variant To Data does today? I can't get my head around to see the difference?

 

I'd positively love to participate in the development of the scripted-typed terminal for LabVIEW btw. It's such a shame I don't live in Austin to apply for a job in R&D Smiley Sad Oh well...

 

Cheers,

Steen

CLA, CTA, CLED & LabVIEW Champion
fabric
Active Participant

drjd: When I initially read your idea I really wanted to believe but it didn't quite click. Now it does! Thanks for hanging in there 🙂

 

Steen: Yes, just like Variant to Data... but with the added superpower of being able to transmit its type through the sub VI boundary! The end result is something like the mythical generic terminal, but the beauty is that the underlying code is all just variants.

 

AQ: If this were implemented, then my deep desire for generic/shape-shifter/adaptive/holy-grail VIs would be reduced significantly. This seems like it would help to address one of the main goals of that quest: the annihilation of polymorphics.