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