Introduction and Disclaimer
LabVIEW 2014 has removed the Stacked Sequence Structure (SSS) from the palettes, and my guess is in just a few years the phrase “Stacked Sequence Structure” will be totally gone from our vocabulary. Before that happens, I would like to officially state my position on SSSs. I realize that by doing this I risk my reputation in the LabVIEW community, so let me make it absolutely clear right now that:
- I agree with NI’s decision to remove the SSS from the palette,
- I agree that SSSs can contribute to less readable and less manageable code
- I agree with NI’s decision not to allocate resources to improve SSSs by adding a shift register as suggested by this idea, but only on the basis that NI has to prioritize limited resources, not on the principle that it would be a bad addition to the language.
Sequence structures serve an important role in LabVIEW, to enforce execution order when there is no directly corresponding data dependency. Sequence Structures, either Stacked or Flat, are the most simple way to achieve this. The primary difference between Stacked Sequences and Flat Sequences is that SSSs make the language more 3-dimensional, while Flat Sequence Structures (FSSs) give preference to reader-friendly, 2-dimensional layout.
Readability is very important, but LabVIEW is still an inherently 3D language, removing SSSs doesn’t change that fact. Case Structures, Event Structures, Conditional Diagram Structures, subVIs, the fact that objects on the diagram have a z-order that needs to be managed, all of these contribute to the 3D nature of graphical programming. Therefore I think SSSs have been unfairly villainized as the cause of bad code in the same way that global variables have been villainized. There is a time and place where these programming constructs can be used responsibly. (Here’s a great blog written by Darren Nattinger on valid uses of global variables. I wish I written that blog, as I have long secretly felt the same way but dared not speak in defense of the reviled global variables.)
I agree that SSSs can be overused, and truthfully I don’t use sequence structures of either type very often, stacked or flat. But when I do, I’d say it’s probably an even 50/50 on whether I choose stacked or flat, given the specific situation.
Before I describe what I believe are valid uses for SSSs, let me first give further credence that Stacked Structures have been villainized. Ever seen code like this?
I’ve seen code that uses this for loop + case structure combination specifically as a means to avoid using SSSs. Sorry people, what we have here is a convoluted SSS, you’ve just disguised it. The compiled code this creates is less efficient, it’s less intuitive to the reader, and the writer has to remember that the valid frames are 0 through 6, not 7. Should Default be its own case? Does it matter? What should Default do if it’s reached?
Yes it’s true that this tricked out SSS does provide two potential features that the stock SSS does not provide: a linear shift register, and the option to abort the sequence early using a conditional stop terminal. And as I said earlier, I think those would be great additions to the SSS if resources were not limited. What I don’t understand is why the comments posted on this idea are so visceral, so negative, like the author just asked for a gold plated gun that he, or other innocent LabVIEW newbies, might use to shoot themselves. One of the comments on the post states specifically that LabVIEW R&D has rejected this idea because it would make Stacked Sequences more desirable to use, thereby encouraging bad practice. Yes, using State Machines is a better way to code, but it still hides code (3D), it requires many more clicks to create, and it may be a more complex solution than what a specific situation may require.
I do agree with critics that Sequence Locals are an abomination because they require the use of backward wires and passing data from frame to frame to frame is obnoxious, especially if you need to support modifying the value in multiple frames. I would be fully in favor of removing Sequence Locals after adding shift registers to the SSS.
Valid Uses for Stacked Sequence Structures
Here are the uses cases where I think SSSs are totally acceptable:
- Timing Metrics. The railroad-tie approach to getting a timestamp before and after an operation requires too much screen space and adds no value to understanding the code that’s really of interest. It requires you to elongate your diagram for the sake of adding code that’s likely temporary. In my opinion, I’d rather see the SSS implementation, particularly if it is being added to an existing diagram.
I can very easily infer what’s happening in frame 0 and 2, and dataflow is preserved. As long as frame 1 is saved as the visible frame, the reader can focus on the code of interest.
- Debug Code. Debug code, occurring before or after your code of interest, further detracts from the readability of your code. Debug code may start out temporary and over time become quasi-permanent if a sporadic issue is never fully resolved. But in either case, I don’t want the reader to be distracted from the main intent of the diagram. Good candidates for debug code in a SSS are non-impactful, such as writing print statements to a log file or DETT trace, or adding information to an error cluster. However, operations with more noticeable impact in terms of execution speed or operator interaction should not be placed in a SSS. Things like sending emails or opening dialogs need to obvious to the reader so they can be periodically re-evaluated, and so the reader knows this code has major limitations on its ability to be reused directly.
- Setup and Teardown Code. SSSs are also convenient for simple Setup/Teardown code that must be run before or after the code of interest. I find this particularly useful when inheriting code that already makes use of local variables, global variables, or Action Engines (FGVs with logic). Rarely do I advocate for the cost or risk associated with refactoring legacy code to eliminate the use of these constructs. Refactoring might make sense if you are planning to make major updates and you know there are many more years of life remaining on this software or system. However, in many cases, simple updates or fixes can be made with only minor modifications to the existing code, which avoids the cost of refactoring and more importantly avoids introducing significant new risk into your system. A SSS can easily wrap around the code of interest, and then frames can be added before or after to perform the necessary setup or teardown such as initializing variables or calling specific options on an Action Engine. This may be the least invasive way to update legacy code.
So there you have it, three use cases for Stacked Sequence Structures that I think are totally legit, when used in moderation.
What is a Structure?
On a more philosophical level, there’s another thing about FSSs that bother me, a little… For all other Structures, NONE of the tunnels output data until ALL of the sub-diagrams have completed. This is not true with FSSs, and I think this is a distinction between Flat and Stacked structures that many people have not considered. Output tunnels on Flat structures output data on a per-frame basis. In fact, it’s possible to have data leave the structure in one frame, skip several frames, and reenter the structure in a later frame. This blurs the definition in my mind of what a structure is. A structure should start executing at one point in time (reading all inputs), and stop executing at a later point in time (writing all outputs). Not true with the FSS.
I agree with the implementation NI has taken, it is much more flexible and fits the dataflow paradigm better than the restrictive definition of Structure that I have provided above. I suspect that I do not have the correct technical definition of a Structure, but it has served me well thus far. The exception I have to make to my mental model of a Structure is that each frame of a FSS is really like its own single-frame sequence structure, each frame acting as its own structure, strung together and made sequential by the compiler.
For the reasons I have stated here, I think removing the SSS altogether would be a mistake that would fall into the category of “we know what’s best for you”. I don’t like when NI makes decisions for my “protection” when it means being more restrictive or taking away features. Fortunately SSSs haven’t been removed completely, and I’m quite satisfied with making FSSs the default as they’ve done in 2014. Converting this to a SSS only takes one extra click, and considering that in prior versions you start out with a single frame, Stacked or Flat, it’s really a wash. I think NI has made a good decision to remove the SSS from the Structures palette in LabVIEW 2014, I just hope they don’t completely remove it from future versions of LabVIEW.
(No code was harmed by SSSs in the making of this blog.)