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
AristosQueue (NI)
NI Employee (retired)

> 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). 

 

The difference between a new structure and a mode on a structure is largely one of perception. But I think the division as a different structure is going to be necessary for scripting -- there are Liskov issues with trying to treat this as a mode switch... I suspect it's going to run into the same problems that the Flat Sequence Structure hit -- which is why FSS isn't even a *node* in scripting.

 

Personally, I'd suggest naming it "Pre-Test Loop" and leave "While Loop" unchanged.

altenbach
Knight of NI

What if it would look like a regular while loop but with two new termination conditions (for a total of four): stop if true, stop if false, pre-stop if false, pre-stop if true (naming to be adjusted, of course ;)). For the last two, it would be up to the compiler to only execute code that contributes to calculating the termination condition and if it evaluates to "terminate", stop the loop and output all tunnel values from the previous iteration. (It could even preemptively calculate some of the other code in parallel for better multi-core use and either use or discard it accordingly. It would not be allowed to update indicators, locals, do DAQ, file IO, etc. etc. unless the loop is allowed to continue).

 

There are probably side effects that I have not considered, so this is just an quick idea. I don't like more complicated structures.

wiebe@CARYA
Knight of NI

@altenbach:

That sounds like a solid idea. It might be a bit tricky, as what the compiler makes of it might not be clear to the user. But if this is doable in the compiler part, it seems to have very low impact on graphics and scripting.

AristosQueue (NI)
NI Employee (retired)

> For the last two, it would be up to the compiler to only execute code that contributes

> to calculating the termination condition and if it evaluates to "terminate", stop the

> loop and output all tunnel values from the previous iteration.

 

So, what do you do with the Wait Milliseconds that is running in parallel to the code? Does it just magically not start waiting until after the stop is computed?

I guess it could work that we just implicitly compile everything as if there were a two-stage flat sequence structure on the diagram.

 

You'd get some weird effects when trying to debug the stop condition -- i.e. you try to bring values used in the stop condition out of the loop to log them, but they'd never come out of the loop because the tunnels would take the value they had the iteration before stop became true. That would be baffling, I'm pretty sure.

In normal While Loop mode, the indicator shows "5".

In pre-test While Loop mode, the indicator shows "4".

Untitled.png

Shift registers would be similarly strange, using the value from the previous iteration.

AristosQueue (NI)
NI Employee (retired)

Wiring a refnum through a pre-test While would not be safe... you'd need to use shift registers, like we do on For Loops in case the loop runs zero times.

wiebe@CARYA
Knight of NI

>You'd get some weird effects when trying to debug the stop condition -- i.e. you try to bring values used in the stop condition out of the loop to log them, but they'd never come out of the loop because the tunnels would take the value they had the iteration before stop became true. That would be baffling, I'm pretty sure.

 

Would it be baffling at first, or baffling forever? I'm leaning towards the latter.

 

Pretty sure this will sooner traumatize beginners than help them. For advanced users, it does at least seem interesting.

wiebe@CARYA
Knight of NI

I did a quick survey in my current project.

 

I have ~300 while loops.

About 5% of them would benefit from this (some action in a case or conditional indexing)

But to be fair, ~60% of the loops either run once (preserving state) or infinite.

 

The 60% category could also (just as well?) be implemented with a new 'while do' loop. That makes the ratio 5/35, not 5/100.

Bo-olean
Member
Wiring a refnum through a pre-test While would not be safe... you'd need to use shift registers, like we do on For Loops in case the loop runs zero times.

 

This is indeed the same with for loops that run zero times or have conditional tunnels. Actually, in many programming classes you will learn that it is not considered safe not to initialize variables in fromt of your loops, in LabVIEW it is the same as saying: don't use normal non-indexing tunnels, instead always use (initialized) shift registers. I would consider that a "best practice", even in while loops.

 

I have ~300 while loops.

About 5% of them would benefit from this (some action in a case or conditional indexing)

So, based on that: on average of 15 benefits per project, that is quite a lot no? I think there are many feautures implemented in LabVIEW that are much more complicated and are rarely used in a project...

 

>You'd get some weird effects when trying to debug the stop condition -- i.e. you try to bring values used in the stop condition out of the loop to log them, but they'd never come out of the loop because the tunnels would take the value they had the iteration before stop became true. That would be baffling, I'm pretty sure.

 

Would it be baffling at first, or baffling forever? I'm leaning towards the latter.

 

Pretty sure this will sooner traumatize beginners than help them. For advanced users, it does at least seem interesting.

That is one of the reasons, I'd rather opt for a seperate conditional section of the code, in that way it is visually clear that there is part of the code inside the loop that is treated "differently" as the others.

 

AristosQueue (NI)
NI Employee (retired)

I'm not going to ask NI to close this idea, but I have to say, at this point, it would not get my support in R&D. That's not a deal breaker -- plenty of ideas have moved forward championed by other developers -- but I don't see myself advocating for this one.