LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
0 Kudos
cbutcher

Create an "Optional" input type wrapper in the style of C++17's std::optional

Currently, we can make inputs to subVIs optional (or indeed recommended) and not wire them - in this case, the default value for the input terminal is used. By default, this is the default value for the type, but it can be easily changed to another value (at least for terminals you can easily set).

 

Since there is no "optional" type, this leads to code potentially like

Example_VI_BD.png

If -1 is always an invalid value here, this might not be so terrible. The issue becomes more pervasive with, for example, empty strings (or string constants) when an empty string or that constant might conceivably be a valid value.

 

Class objects could be an additional problem, especially if a hierarchy is considered, because you might want to wire an uninitialized child object to an Init Object method, and it would fail an equality check vs the terminal type. You might then mistakenly conclude that it was already partially/fully initialized, and carry out the incorrect processing (in this exact case, probably dynamic dispatch followed by an equality check against the specific child, then calls to a static dispatch "Init Object_internal.vi" in the parent might work).

 

We can work around this if needed by using a boolean clustered with the value, and then checking the boolean, but this makes wiring the subVI and creating its inputs more frustrating.

 

I would like to see an optional terminal type that could be checked using a primitive to indicate if it was wired by the caller or not.

Example_VI_BD.png

(Apologies for the ugly icon, and probably dubious naming)

 

 

For the draft of the proposing paper in C++ for the std::​optional type, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3672.html


GCentral
15 Comments
AristosQueue (NI)
NI Employee (retired)

Hm... it just occurred to me that I have a VIM shipping example in the upcoming LabVIEW 2018 that essentially does exactly what Wiebe proposes. I hadn't really thought about it as implementing a "do this if unwired", but that's the result. It does rely upon the fact that the default type is not a used type. And, as Wiebe notes, it doesn't do anything to prevent computation of unwired outputs. Having said that, because the VIMs are inlined, dead code elimination in the compiler will remove code for unused outputs if those outputs are computed without side effects, but I think that level of removal requires debugging be disabled in the caller VI. Note: I've never investigated just how much DCE can affect on inlined VIs (where debugging is always off) when embedded in a caller (where debugging is on). It might already work, if anyone has time to test and find out. Even so, this wouldn't help outputs whose computation does have side effects, like outputs computed based on reading a file on disk.

cbutcher
Trusted Enthusiast

Although I can't attach a project/VI/VIM to this post, using a flat sequence structure, two High-Res Relative Seconds and an array indicator along with a VIM that in the first frame uses

"To Double" > "Initialize Array" with 5e7 elements > "Shuffle 1D Array.vim" > output to DBL Array

and in the second uses

"Get Variant Attribute" (blank, no outputs wired), Initialize Array (0 with 1 element) > output to DBL array

 

I get 

~0.13 seconds with input wired to Random Number, no output wired.

~4e-7 seconds with no input, no output (note, have to wire a variant to reset if previously wired double)

~2e-5 seconds with no input, wired output

~4.2 seconds with input and output both wired.

 

The calling VI is non-reentrant, with debugging enabled. The tests were carried out a few times, but by hand, and I guess/averaged the times - there was no For loop etc...

 

Looks like if you can find a type you don't need, you can create what's effectively an Optional-type input for a VIM (and arguably an output too, but perhaps that depends on the situation a little more).

 

As Wiebe noted, this requires you have a type you can use as the default that you don't need, but that's quite a bit easier than a value in your type you don't need.

 

It's worth highlighting that it won't reset when you delete the input wire though - in my example I wired a variant constant to reset the VIM. Otherwise, it takes a default value double input (and does the expensive generate/shuffle).

 

Edit: If you want to play, my 2 VI project can be found at https://github.com/chrisb2244/LabVIEW-OptionalTypeTest


GCentral
AristosQueue (NI)
NI Employee (retired)

> It's worth highlighting that it won't reset when you delete the input wire though

 

I've been asked in beta forums to change that behavior. In LV 2017 SP1, I made non-required terminals revert when unwired. In 2018, if I have time, I'll broaden that to all the terminals, per user feedback. The window for 2018 changes is closing fast, so I may not have a chance.

cbutcher
Trusted Enthusiast

> I've been asked ... to change that behaviour.

 

Sounds great. Now that I'm more awake, I've also realised that I can just create a new class to use as the default type, and then I don't need to give up a type I might want to use.

 

I also figured why not being able to have an optional output would potentially be a shame, but probably in a lot of the cases I'd imagine there, an additional boolean output, or cluster, or just an error on the error wire would suffice. Maybe I'll realise some way in which this is stupid later... at the moment, unchangeable connector panes and contracts on error output are all that come to mind (but it seems like any optional type would be a connector pane change or worse in some of the earlier discussion)


GCentral
TomOrr0W
Member

Looking at the discussion on this idea (I realize I am 8 months late), this brought me to the idea of adding some syntax to implement this as either a void control on a vim (black wire).  If the void wire is a step too far, maybe when an input is designated [truly optional - need a better term here], add a black outline to the wire and terminal.

 

Either way, the vim would treat this wire like a void wire with one exception: the wire doesn't break if only wired to the border of a type specialization structure (the portion going from the border to a node inside the structure would still be broken).  So, the structure would only use frames where it is not wired if nothing is wired to the default input.  If something is wired to the input, it would behave like a normal vim and use the cases where the wired type is valid.  See image below (using a undefined array as a placeholder for the void/truly optional control).

 

Void Input.png

 

I can't think of a good way to make this work in normal vis, but the type specialization structure can be put in normal vis if someone else does.