From 11:00 PM CST Friday, Feb 14th - 6:30 PM CST Saturday, Feb 15th, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
0 Kudos
Bo-olean

First check, then run while /for loop

Status: New

I know this idea has been coined already in A new head-controlled while loop, though it was closed becasue it didn't receive more then 4 kudos. That was 3 years ago and I didn't get any vote because I wasn't aware this post was out there. I'd like to re-open the discussion. Or for how long do we close suggested topics because at the time, there was not enough interest? It is not al that difficult and yet we are 2019 and NI still didn't solve this (as well as taking the square of a united input doesn't square the unit).

 

I have been programming a lot in LabVIEW and generally love it, but I also find it quite frustrating that you can not do the classic "check condition first, then run". I alos find the classic arguments not valid.

 

Some argue that it is easily solved using a case structure and while loop, which is not equivalent. One solution is to put the while loop inside the conditional loop, which forces you duplicate the conditional code and good programmers don't like duplicate code. (You could create subVI though, but that is also creating a lot of overhead for both the programmer as the program at run-time). Another solution, as some suggested here, is to put the case structure in the while loop, but then if you are indexing the output, you output a array with one element, whereas you probably wanted to output an empty array. In this case you can work with conditional terminals but that is also a lot of overhead and there is even a bug in LabVIEW when you output multidimensional arrays in this way that are empty and later on try to iterate over it, a for loop will execute the inside of the for loop, although the array is "empty".

 

I also find the argument that it is a rare case not compelling, I myself experienced this often while programming and the whole sense of a while (or conditional for) loop is that you don't know beforehand how many times you will have to iterate it. So it might be as well that you don't even have to iterate it a single time. That sounds reasonable, no? Otherwise you would use for loop. It is actually the other way round: the classic "do while" is a rare case (that's why textbooks first learn the while loop).

 

I also don't agree with the fact that the way LabVIEW works, it is not possible. I understand that you need a value for non-indexing terminals, but that would simply be not supported in this type of loop. A "check first then run" kind of loop would only work with iterating terminals (which can be empty) and shift registers (which can take up the value it was initialized to).

A seperate part of the loop's body must be reserved for the conditional code (for instance a rectangle that is fixed at the left underside of the while loop rectangle), just like in most languages where you have to write your conditional statement in brackets as part of the loop statement...

 

This type of loop would also solve the problem that you often have to delete the last element of your indexed array because the condition for which you probably wanted it, was no longer true (but the loop has excuted first after deciding that).

 

Lastly, it would give new LabVIEW programmers that come from any other language more familiarity with what they know. As this is reasonably a rather big flaw in LabVIEW (see argumentation above) that is some common and basic in other languages and you are likely to stumble on quite soon when you start experimenting in LabVIEW, it might just make you turn around right away, as it was almost the case when I first started programming in LabVIEW and didn't know how the rest of the language and environment is very beautifull and well designed.

19 Comments
altenbach
Knight of NI

Well, you are trying to revive an ancient discussion that has already run it's course years earlier. All you are asking for can easily be programmed around, and implementing your suggestion would probably not make things much simpler than the current workarounds.

 

How exactly is this "loop" supposed to look like? We are graphical programmers, so please include a graphical sketch instead of long paragraphs.

 

The issue about empty 2D arrays where some dimensions are non-zero also has been discussed and the current behavior is correct. For an array to be empty, only one dimension needs to be zero size and we expect loops to honor nonzero dimensions of an empty array.

wiebe@CARYA
Knight of NI

@Bo-olean wrote:

I understand that you need a value for non-indexing terminals, but that would simply be not supported in this type of loop. A "check first then run" kind of loop would only work with iterating terminals (which can be empty) and shift registers (which can take up the value it was initialized to).


A for loop can iterate 0 times, and it allows non-indexing. This loop (while-do vs do-while) can do exactly the same. Simply output the type's default value.

 


@Bo-olean wrote:

This type of loop would also solve the problem that you often have to delete the last element of your indexed array because the condition for which you probably wanted it, was no longer true (but the loop has excuted first after deciding that).


Conditional indexing solved that for me. Add while the condition is true, don't add if it's done.  

AristosQueue (NI)
NI Employee (retired)

> I also find the argument that it is a rare case not compelling

 

You're probably just going to have to trust me on this argument. I really have kept my eyes open for this over the years... it was on my early list 20 years ago of deficits I saw in LabVIEW. I really don't see need for it commonly when I'm reviewing customer code (something I do somewhat regularly in bug escalations). I do not know why it is so rare.

 

Your other arguments in favor of this structure are generally valid (although the introduction of conditional autoindexing does weaken the argument against case-inside-while workaround). I'm just not sure they're worth the investment of time needed to develop a) the design and b) the feature.

 

And the design costs aren't small. I haven't seen any proposals for this that don't look like a flat sequence structure and a while loop and a case structure all blended together in one structure -- a far cry from elegant and accessible.

 

Bo-olean
Member

@Altenbach and AristosQueue,

 

Thanks for the constructive response. It could look like the drawing below.

IMG_20191104_204802.jpg

 

It explains itself more or less: everything that is inside the conditional part gets excuted first, then the condition is checked and lastly (if condition is still valid) the body part is executed. All else (terminals, registers) is identical to the classic while loop. A register can be part of the conditional checking or the body, depending on its height in the loop.

 

In implementation, I doubt this would be hard to implement the feauture, as it is one of the most basic things in any given languag and is actually not very different from the do-while loop. Design wise, I don't know how easy/difficult that would be, it is in the end, two additional lines...

Bo-olean
Member

"Conditional indexing solved that for me. Add while the condition is true, don't add if it's done."

Yes (but at cost of additional wiring),

- Except for registers, which can't be "conditionalled". You can also wire the the input of the register through to right side of the while loop, but that easily creates an horrible wiring mess if you have to do it for many signals.

It can all be done without there are plenty of workarounds, my argument is just that it would make writing code more efficient and maintainable, make "written" code more "readable" and it would embrace new programmers with something they know...
To sum up: some clear benefits, it is feasible and there is no argument so far not to do it, except for the cost. How high would this be?  I have no idea on how LabVIEW works in the background, but it seems fairly easy?

AristosQueue (NI)
NI Employee (retired)

> and there is no argument so far not to do it, except for the cost

 

The big arguments against depends upon the design of the feature. Without a fleshed out design, it is impossible for me to answer some very key questions that could be strong arguments against.

 

This would add a new type of loop. That's a foundational part of the language, and it would be something a relatively new user would a) have to make a decision about and b) likely see on block diagram.

 

Does this new structure improve readability of diagrams? (I.e., it is it really more comprehensible with some new syntax than the existing syntax that does the same thing.) Forget the benefit to the writer... how much does it burden readers?

 

Does it confuse users about which loop to use? We already have people who balk at difference between For Loop and While Loop. Adding the Timed Loop, even as limited exposure as it has, created some consternation. Timed Loop was buried in the palettes... this would be a peer to the other two.

 

If a user makes a mistake and drops the wrong one, how easy is it to refactor to the other?

 

> How high would this be? I have no idea on how LabVIEW works

> in the background, but it seems fairly easy?

 

TL;DR: I think it would probably a designer's primary task for a sprint (4 weeks) or two, trying paper designs out with test customers, then a developer's primary task for two iteration cycles (each cycle is three sprints). This assumes a mid-level dev whose done some node work before (almost no one has done new structure work... they don't come up often). Secondary impact on documentation and customer education is "Medium"... not much to document, but might be repeated in a lot of places. Similar estimates for both LabVIEW and LabVIEW NXG.

 

Details: Let's see... you've got a new structure node itself. I helped add the new Type Specialization Structure just a couple versions ago... took about 2 months, and it had a lot of overlap with existing Diagram Disable structure. I have some other data from a completely new node that is still in development... let's call it three months for a completely new structure.

 

But your picture has that corner region. One route would be to make that a nested structure that is pinned to the corner of the node. Another route would make those bent walls a node. I can see some pro/cons to both, but I'm guessing that UI design would need a month, and implementation probably another month after that. You've got some weird type prop scenarios to account for (someone brings a wire from the interior of the While Loop into the nested frame structure, for example). Like most features, it'll be fully handling the error cases that take the longest time.

 

Scripting API is hard to estimate. New refnum types definitely needed for that nested region with unique properties/methods.

 

Compiler should be straightforward... the intermediate language decomposition can decompose into existing syntax (i.e. the while loop around the case structure). Let's call that two weeks.

 

Another week if there's any refactoring tools (such as "Replace with While Loop", or vice versa).

 

A couple days to put together shipping examples.

 

Documentation and customer education burdens are pretty high for a foundation feature like this. I won't try to estimate their burden. They will trigger work for localization.

 

Add a year while people argue about what to name the new loop.

(That's a joke. I think. People get twitchy about names.)

wiebe@CARYA
Knight of NI

I won't like a corner, and I don't really see the point. I assume it will be harder to design and implement. There'd be lot's of questions and discussions, for instance: "why is the corner on the bottom, I want it at the top". (At some point someone will want the conditional part on the right sideSmiley Wink)

 

 

How about this: 

While Do.png

Indeed, a combination of a while loop, case structure and a little bit of flat sequence structure.

 

Graphical details could be improved of course.

 

It (arguably) looks intuitive. The auto indexing isn't communicated very well.

 

It could actually be a switch\option in a 'normal' while loop. I think it will be possible (theoretically) to decide what should go left and what should go right? Going form this back to a normal while loop will be easy.

 

The name? If it's an option of a while loop, we won't need a new structure name. Just the option. I'd say a switch between "do while loop" and "while do loop". I think Pascal has the two of them as well?

 

I'm still ambivalent about this. I can do without, but might actually like it. Hard to say without trying.

crossrulz
Knight of NI

In my nearly 15 year LabVIEW career, I can think of 1 time where I really wanted a While..Do.  Even then, I think I ended up replacing it with a FOR loop.  I think I am good with just a case structure around the loop or the code inside the loop.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
wiebe@CARYA
Knight of NI

A lot of languages have both (while loop \ do while loop), but I haven't seen do..while a lot in the wild. LabVIEW seems to be the odd one out.

 

What would be easier for all those schoolkids, that will start using the community edition? Or for people finally transitioning to LabVIEW? I don't know... They won't be giving kudos on the idea exchange, that's for sure.

 

Bo-olean
Member

The reason that I opted for a corner square is the following:

This way you are not forced to wire inputs and shift registers to pass through the conditional part, I'd like it better like that: there is a clear seperation between both.

I opted for the left bottom for the following reasons:

- I think it should certainly be left because it is excuted fisrst (having a left to right program flow, left is the only way that makes sense).

- Bottom because that is generally the place for index terminal, which, in my view should be placed in the conditional part, as you often use this in your conditional code.

I would also opt not to add a new structure but instead to "upgrade" the current while loop with this option (with right click menu). That keeps impact for developers lowest and will not confuse people to much with a new structure. Though, you might be able to insert it from the function palette pre-configured as a while-do, but you should be able to change the one into the other with simple drop down configuration.