bug in foreach continue

Hussien via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Mar 17 08:14:08 PDT 2017


On Friday, 17 March 2017 at 14:27:25 UTC, Adam D. Ruppe wrote:
> On Friday, 17 March 2017 at 13:53:58 UTC, Hussien wrote:
>> Yes, but you have a nested foreach loop. One runtime and one 
>> compile time. The break goes with the runtime loop... but 
>> NORMAL programming logic tells us that the break goes with the 
>> loop that it exists in.
>
> It did. It broke the loop counting the numbers, but continued 
> the loop of strings normally.
>
>
> People have requested a `static foreach` before, but that 
> request has not yet been granted.
>
>> They are going to expect them to continue or break out of the 
>> inner most loop that they are called from.
>
> That is exactly what they do, and exactly what happened in all 
> the examples posted.

You're failing to see what I am talking about. I understand the 
compiled code is correct and functions as it should.

What I am talking about is

how the statement

static if (x) continue;
pragma(msg, "called");

vs

static if (x) { } else
pragma(msg, "not called");


They are both semantically equivalent

e.g.,

if (x) continue; foo();

vs

if (x) {} else { foo(); }

Both do the same thing in loops when used in the context I 
originally gave. e.g., using a continue to skip over elements of 
an interation. Works great in normally programming!

BUT in static programming, the continue FUNCTIONS as a runtime 
component... just as you say. BUT that is not how one interprets 
it on the static level.

The logic for


if (x) continue; foo();

vs

if (x) {} else { foo(); }

and the logic for


static if (x) continue; foo();

vs

static if (x) {} else { foo(); }


should be identical. Just because we are programming on two 
different levels doesn't change the logic(or shouldn't).

The problem, of course, is the continue does exactly what you 
claim it does.

But when I am meta programming I am thinking in terms of meta 
programming. I program exactly the same way as I do in runtime 
programming except for the obvious shifts that are required. But 
foreach is a foreach. In runtime it works on runtime stuff and at 
compile time it works on compile time stuff.

Effectively I have

runtime_foreach and static_foreach in my head and I magically 
disambiguate when required.

But there is no such concept for continue. It is impossible to 
"continue" or even "break" a static for each loop. That is what I 
am addressing.

SO, because I had a mental glitch and I used continue "thinking" 
it would work for the static case, e.g., I assumed it was a 
static_continue... when no such thing exists, the code compiled 
and did something I did not expect!

YES, It was my fault! BUT the point is that D has that ambiguity. 
AND because the flow structures for runtime and compile time are 
virtually identical, the mistake is easy to make! Even if not, if 
the mistake does occur, it will be a difficult thing to track 
down in real world cases that are complex. That is the only point 
I am making! It has nothing to do with what D actually does, but 
how it does it.

A continue or break should create a warning when used in the 
context of a static foreach. OR change the freaken syntax of 
static semantics vs runtime. Making them identical is 
ridiculously and only leads to these kinds of problems. Sure, it 
works in 99% of the cases, but so will a new syntax.

My point is not what D does specifically in compiling source 
code, or that it does it right or wrong. I am talking about the 
interpretation by a human of the code. 
$@#$@($*%**%*#(@(@!)@$_@%%#$#$@#@($!* is some code to some yet to 
be created programming language... but it doesn't mean that 
humans will be able to interpret it properly. I am talking about 
how humans interpret things.

Do you really think that a non-D programmer that sees the code

foreach(x; [1,2,3])
foreach(y; aliasSeqOf![1,2,3])
static if (y == 1) continue;
pragma(msg, y)

is going to be able to interpret the code correctly?

Because if they use a rewrite rule, which is GENERALLY VALID in 
all programming languages:

foreach(x; [1,2,3])
foreach(y; aliasSeqOf![1,2,3])
static if (y == 1) {} else
{
pragma(msg, y)
}

(again, this should be the same as the first case, because we can 
do that at runtime and it is valid... people write code like that)

Yet one gets a different result.

Hence, if they are programming some NASA rocket, and make that 
mistake and the rocket goes left instead of dropping it's 
boosters, then what? Who's fault? Is it D's fault for creating 
ambiguity between static and runtime programming? Of course it 
is, because It sets the foundation for what is to come.

Again, my point is not about D compiling the above code, but 
about the syntax/grammar/language issue it creates conceptually. 
You may not have that problem because you are familiar enough 
with D's meta programming but to someone that isn't, they have to 
go on what they know, and there is a problem conceptually they 
will have to learn about. It shouldn't be that way. It is a 
problem of D treating apples as oranges. foreach != foreach... 
does that make sense? Sure, if you already learned, but if you 
are learning or have a brain fart, too bad for you...

This is D's approach: "Meta programming - The same as 
programming... well almost". The almost part is what gets people 
killed.
















More information about the Digitalmars-d-learn mailing list