1. trace(1) bug

Using Eu 3.1 official:
with trace
trace(1)
for i=1 to 3 do
?i
end for
for i=1 to 2 do
?i
end for
integer i i=5
?0


Step into program until in second loop. The current value of i is displayed
correctly.
Then enter "?i": the correct value is erased, and "i=3" is incorrectly
displayed, at a different screen location.
Keep stepping forward to the second last statement, and enter "?i" again. You'll
get "i=3" displayed, instead of the expected "not defined at this point" message.
This will happen whether you performed the first "?i" or not.
Press enter to last stateùment and do "?i" again. You'll get "i=3" instead of
"i=5".

Reason: the logic of RTLookup() in be_symtab.c wrongly assumes that it should
return the first maching top level loop index, while several with the same name
are likely to be defined. And it has no idea whether an SC_GLOOP_VAR var is in
scope at the current trace location, or that a local var may override loop
indexes.

Tentative fix: 
1/ keep track of the last matching variable in file instead of returning on
first found. When <var>stop</var> is reached, if any was found, then return it.
2/ to fix the middle problem ("i=3" instead of "not defined"), the ENDFOR_*
opcodes should set the loop var to NOVALUE, which never happens during its
observable life span. The "not defined" message could be displayed then for loop
indexes, and "<no value>" for other vars that just didn't get a value yet.
3/ apply same strategy for private symbols, but you can return when a SC_PRIVATE
is found. Otherwise return last defined index instead of first.

I don't have a C compiler at work; I'll try to submit a tested fix ASAP.

CChris

new topic     » topic index » view message » categorize

2. Re: trace(1) bug

CChris wrote:
> Using Eu 3.1 official:
> }}}
<eucode>
> with trace
> trace(1)
> for i=1 to 3 do
> ?i
> end for
> for i=1 to 2 do
> ?i
> end for
> integer i i=5
> ?0
> </eucode>
{{{

> 
> Step into program until in second loop. The current value of i is displayed
> correctly.
> Then enter "?i": the correct value is erased, and "i=3" is incorrectly
> displayed,
> at a different screen location.
> Keep stepping forward to the second last statement, and enter "?i" again.
> You'll
> get "i=3" displayed, instead of the expected "not defined at this point"
> message.
> This will happen whether you performed the first "?i" or not.
> Press enter to last stateùment and do "?i" again. You'll get "i=3" instead of
> "i=5".
> 
> Reason: the logic of RTLookup() in be_symtab.c wrongly assumes that it should
> return the first maching top level loop index, while several with the same
> name
> are likely to be defined. And it has no idea whether an SC_GLOOP_VAR var is
> in scope at the current trace location, or that a local var may override loop
> indexes.
> 
> Tentative fix: 
> 1/ keep track of the last matching variable in file instead of returning on
> first
> found. When <var>stop</var> is reached, if any was found, then return
> it.
> 2/ to fix the middle problem ("i=3" instead of "not defined"), the ENDFOR_*
> opcodes
> should set the loop var to NOVALUE, which never happens during its observable
> life span. The "not defined" message could be displayed then for loop indexes,
> and "<no value>" for other vars that just didn't get a value yet.
> 3/ apply same strategy for private symbols, but you can return when a
> SC_PRIVATE
> is found. Otherwise return last defined index instead of first.
> 
> I don't have a C compiler at work; I'll try to submit a tested fix ASAP.

I'd be delighted if you can fix this.
Someone recently sent me a big complicated example
that seems to show the very same problem. It looked 
rather difficult to diagnose and fix, so I was tempted 
to lazily post it to the SourceForge bug tracker and forget
about it for a while. smile

Now that Euphoria is an open source project,
people should post all bug reports to EUforum and/or 
the SourceForge bug tracker.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

3. Re: trace(1) bug

Robert Craig wrote:
> 
> CChris wrote:
> > Using Eu 3.1 official:
> > }}}
<eucode>
> > with trace
> > trace(1)
> > for i=1 to 3 do
> > ?i
> > end for
> > for i=1 to 2 do
> > ?i
> > end for
> > integer i i=5
> > ?0
> > </eucode>
{{{

> > 
> > Step into program until in second loop. The current value of i is displayed
> > correctly.
> > Then enter "?i": the correct value is erased, and "i=3" is incorrectly
> > displayed,
> > at a different screen location.
> > Keep stepping forward to the second last statement, and enter "?i" again.
> > You'll
> > get "i=3" displayed, instead of the expected "not defined at this point"
> > message.
> > This will happen whether you performed the first "?i" or not.
> > Press enter to last stateùment and do "?i" again. You'll get "i=3" instead
> > of
> > "i=5".
> > 
> > Reason: the logic of RTLookup() in be_symtab.c wrongly assumes that it
> > should
> > return the first maching top level loop index, while several with the same
> > name
> > are likely to be defined. And it has no idea whether an SC_GLOOP_VAR var is
> > in scope at the current trace location, or that a local var may override
> > loop
> > indexes.
> > 
> > Tentative fix: 
> > 1/ keep track of the last matching variable in file instead of returning on
> > first
> > found. When <var>stop</var> is reached, if any was found, then return
> > it.
> > 2/ to fix the middle problem ("i=3" instead of "not defined"), the ENDFOR_*
> > opcodes
> > should set the loop var to NOVALUE, which never happens during its
> > observable
> > life span. The "not defined" message could be displayed then for loop
> > indexes,
> > and "<no value>" for other vars that just didn't get a value yet.
> > 3/ apply same strategy for private symbols, but you can return when a
> > SC_PRIVATE
> > is found. Otherwise return last defined index instead of first.
> > 
> > I don't have a C compiler at work; I'll try to submit a tested fix ASAP.
> 
> I'd be delighted if you can fix this.
> Someone recently sent me a big complicated example
> that seems to show the very same problem. It looked 
> rather difficult to diagnose and fix, so I was tempted 
> to lazily post it to the SourceForge bug tracker and forget
> about it for a while. smile
> 
> Now that Euphoria is an open source project,
> people should post all bug reports to EUforum and/or 
> the SourceForge bug tracker.
> 
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    <a href="http://www.RapidEuphoria.com">http://www.RapidEuphoria.com</a>

The problem is: if ENDFOR_* sets loop indexes to NOVALUE, the final value of an
index will be clobbered and won't be displayed in ex.err as it currently does,
but will show "<not defined>" or something. Perhaps not displaying it at all is
an option. I have always been a little surprised at repeated "i = xxx" lines in
ex.err; I expect some are downright confused. The extra lines would just go away.

If we need to keep the final values of out of scope indexes: since the
SC_[G]LOOPVAR scope implies M_NORMAL mode, the mode field in SymTab could be used
to flag whether a loop index is in scope or not. Could prove tricky - I have to
check how the backend uses this member.

In Advanced Euphoria, there are a couple extra fields in the reduced SymTab,
including an S_LASTLINE that gives the last gline_number for a symbol to be valid
when it has special scoping rules: loop indexes are only one of the symbol types
where it is used. I stumbled on the bug while trying to figure how the current
backend could report the right loop index - it just doesn'r. Perhaps this is the
way to go. Patching SymTab entries from current shrouded code could be a problem,
but shrouded code isn't supposed to be traced anyway, so setting the field to 0
(no special scoping) would be enough.

Which solution is preferrable?

CChris

new topic     » goto parent     » topic index » view message » categorize

4. Re: trace(1) bug

CChris wrote:
> I have always been a little surprised at repeated "i = xxx"
> lines in ex.err; I expect some are downright confused. The extra lines 
> would just go away.

> Which solution is preferrable?

IMNSHO: allow only *ONE* i per context.

allow eg:
procedure x()
integer i -- see point C:
    for i=1 to 10 do
        if i=5 then exit end if
    end for
    ?i
    for i=1 to 20 do end for
    ?i
end procedure
}}}
<eucode>
A: to work (currently you get "attempt to redefine i"),
B: to display either 5,20 or 5,21 (my preference is for latter),
C: ditto whether i predefined or not,
D: any ex.err lists one and only one i, per scope.
E: any trace(1) screen "" "" "", except for:
F: (erm?) trace screen allows inspection of callee i and other vars.
G: whatever you do, you must still prohibit nested "for i=" loops.
H: (doh) same deal for A:..G: with top-level code.
I: top-level: for i=1 to 2 do end for integer i now craps out => "tough"!

Obviously F: is a frill perhaps beyond the scope (no pun intended) of the
immediate discussion.

One caveat I can see is this:
}}}
<eucode>
   if x then
       for i=1 to 10 do end for
       ?i -- OK
   else
       ?i -- //iff i not predeclared, may warrant a warning?
   end if

Though personally, I'm OK with run-time "has not been assigned a value" and no
compile-time warning, there may be many others, YMMV, etc.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

5. Re: trace(1) bug

Pete Lomax wrote:
> 
> CChris wrote:
> > I have always been a little surprised at repeated "i = xxx"
> > lines in ex.err; I expect some are downright confused. The extra lines 
> > would just go away.
> 
> > Which solution is preferrable?
> 
> IMNSHO: allow only *ONE* i per context.
> 
> allow eg:
> }}}
<eucode>
> procedure x()
> integer i -- see point C:
>     for i=1 to 10 do
>         if i=5 then exit end if
>     end for
>     ?i
>     for i=1 to 20 do end for
>     ?i
> end procedure
> }}}
<eucode>
> A: to work (currently you get "attempt to redefine i"),
> B: to display either 5,20 or 5,21 (my preference is for latter),
> C: ditto whether i predefined or not,
> D: any ex.err lists one and only one i, per scope.
> E: any trace(1) screen "" "" "", except for:
> F: (erm?) trace screen allows inspection of callee i and other vars.
> G: whatever you do, you must still prohibit nested "for i=" loops.
> H: (doh) same deal for A:..G: with top-level code.
> I: top-level: for i=1 to 2 do end for integer i now craps out => "tough"!
> 
> Obviously F: is a frill perhaps beyond the scope (no pun intended) of the
> immediate
> discussion.
> 
> One caveat I can see is this:
> }}}
<eucode>
>    if x then
>        for i=1 to 10 do end for
>        ?i -- OK
>    else
>        ?i -- //iff i not predeclared, may warrant a warning?
>    end if
> </eucode>
{{{

> Though personally, I'm OK with run-time "has not been assigned a value" and
> no compile-time warning, there may be many others, YMMV, etc.
> 
> Regards,
> Pete

The current issue is the discrepancy between what parser understands and what
interactive execution understands.

If the for loop is considered to be a scope, which has always been the case,
then both }}}
<eucode> integer i</eucode>
{{{
 before and }}}
<eucode>integer i</eucode>
{{{
 after
are valid. However, the docs say that a loop index must not be declared, which is
why the code you wrote doesn't work. I agre that it would be more logical to
amend docs to say "doesn't reuire to be declared" and let A live.

Displaying 21 (last value assigned to i) in B is a problem, because i is not
defined at the point you say }}}
<eucode>?i</eucode>
{{{
. Some C compilers allow the
index of a for loop to be valid and available after end of loop.  have no problem
with this, but this is a change in the language, requiring perhaps some
discussion.

C results from A and B, no comment.

A and D contradict each other. If each for loo^p is a scope, then both the whole
 scope variable (the integer i) and the active loop index i (if any) should be
displayed, but only these two.
So there is a problem with B:
* if there is no integer i, and program crashes after the for loop, ex.err xould
show the loop index i
* if there is an integer i predefined, then that i would show in ex.err. Not so
sure I like B, after all.

E is what I was concerned in the first place, so we agree there.

If there are both an integer i and a loop index i, the later shadows the former
and you cannot access it from inside the for loop, either in normal or traced
execution. I wouldn't mind doing something else, but that would be a big change
in the language. Probably a code breaker, and I don't see a lot of benefits.

G kid of results from A, agreed.

H must hold for consistency.

As I said, if we consider a for loop to be a full fledged scope, which it is,
then I is not consistent. I would be consistent with B, but see, there are subtle
issues in allowing potentially twovars with the same name to coexist past the end
of the for loop.

Thoughts, anuone?

CChris

new topic     » goto parent     » topic index » view message » categorize

6. Re: trace(1) bug

CChris wrote:
> 
> Pete Lomax wrote:
> >}}}
<eucode>
> >procedure x()
> >integer i
> >    for i=1 to 10 do
> >    end for
> >    for i=1 to 20 do
> >    end for
> ></eucode>
{{{


> If there are both an integer i and a loop index i, the later shadows the
> former

In the case given, I meant they should be one and the *same*.

Correct, this would constitute a change to the language spec.

I trust you agree that allowing the above construct cannot break any legacy
code. Can you think of any reason, or example, why all 3 [local] i above refer to
same var would cause a problem?

Regards,
Pete

PS there may be cases where a predeclared "integer i" must instead be "atom i"
to marry with subsequent f.p. loops, I hope such can be handled ok.

new topic     » goto parent     » topic index » view message » categorize

7. Re: trace(1) bug

Version 2.4 has the same (or similar) problem.

new topic     » goto parent     » topic index » view message » categorize

8. Re: trace(1) bug

Pete Lomax wrote:
> 
> CChris wrote:
> > 
> > Pete Lomax wrote:
> > >}}}
<eucode>
> > >procedure x()
> > >integer i
> > >    for i=1 to 10 do
> > >    end for
> > >    for i=1 to 20 do
> > >    end for
> > ></eucode>
{{{

> 
> > If there are both an integer i and a loop index i, the later shadows the
> > former
> 
> In the case given, I meant they should be one and the *same*.
> 
> Correct, this would constitute a change to the language spec.
> 
> I trust you agree that allowing the above construct cannot break any legacy
> code. Can you think of any reason, or example, why all 3 [local] i above refer
> to same var would cause a problem?
> 
> Regards,
> Pete
> 
> PS there may be cases where a predeclared "integer i" must instead be "atom
> i" to marry with subsequent f.p. loops, I hope such can be handled ok.

Technically, it is not a problem. If you remember OpenEu (lowercase), you may
remember a wfor loop proposal too. Yours resurrects it. It is useful to have, at
least convenient.

But imho under another name than "for",  be it "wfor" or something else. I'd
probably prefer something else actually - "iterate" perhaps?

The difference between a for loop and a wfor loop would only be that a wfor loop
doesn't define a scope, so that its index has to exist prior and remains in
existence beyond its end statement. It is a specialised while loop actually,
which motivates its historical name. In contrast, the current for loop would
remain a scope by itself, with no reason for its index to be valid outside it, as
it is now. Both are useful, so let's have the two constructs.

Currently, a for loop index should not exist prior ("attempt to redefine i"); I
don't see any problem in changing this so that the loop index shadows anything
with the same name as long as it is alive, except another for loop index. It
won't break any code. I don't see why defining a top level integer i after having
top level loop indexes named i should error out - it shouldn't, since the loop
indexes are out of scope by then, so i is not being redefined.

And since for loop indexes don't exist after the loop is exited, I'd suggest
simply removing their display from ex.err (or set them to NOVALUE on exit),
solving the second problem shown by my original code (loop index displayed past
its bounding end statement). The first one (wrong loop index displayed by ?) is
easy to fix without changing anything in the language.

Opinions?

CChris

new topic     » goto parent     » topic index » view message » categorize

9. Re: trace(1) bug

CChris wrote:

> Currently, a for loop index should not exist prior ("attempt to redefine i");
> I don't see any problem in changing this so that the loop index shadows
> anything
> with the same name as long as it is alive, except another for loop index.

The current behavior prevents me from accidentally assigning a loop value
to a currently existing variable. I'd like to keep that behavior. For the
other consideration, iterate() would be a good name.

integer i

iterate(i,1,2,<10) do -- (variable,start,step,continue condition)
  ?i -- 1, 3, 5, 7, 9
end iterate
?i  -- 11

That's the general idea.

new topic     » goto parent     » topic index » view message » categorize

10. Re: trace(1) bug

c.k.lester wrote:
> 
> CChris wrote:
> 
> > Currently, a for loop index should not exist prior ("attempt to redefine
> > i");
> > I don't see any problem in changing this so that the loop index shadows
> > anything
> > with the same name as long as it is alive, except another for loop index.
> 
> The current behavior prevents me from accidentally assigning a loop value
> to a currently existing variable. I'd like to keep that behavior.

Well I have no fixed opinion on this actually. Pete seems to wish he could
predeclare an integer i. The iterate loop would serve him right I think. But
again, I'll apply this specific small change only if there's consensus about it.
It wouldn't fix anything.

> For the
> other consideration, iterate() would be a good name.
> 
> integer i
> 
> iterate(i,1,2,<10) do -- (variable,start,step,continue condition)
>   ?i -- 1, 3, 5, 7, 9
> end iterate
> ?i  -- 11
> 
> That's the general idea.

I was thinking more along the line of }}}
<eucode>iterate i=1 to n by p do</eucode>
{{{
,
just like a for loop, but with the semantic differences underlined earlier.

CChris

new topic     » goto parent     » topic index » view message » categorize

11. Re: trace(1) bug

CChris wrote:

> I was thinking more along the line of }}}
<eucode>iterate i=1 to n by p
> do</eucode>
{{{
,
> just like a </font><font color="#0000FF">for </font><font
> color="#330033">loop, but </font><font color="#0000FF">with </font><font
> color="#330033">the semantic differences underlined earlier.</font>

Yeah, that's what I meant. :P

new topic     » goto parent     » topic index » view message » categorize

12. Re: trace(1) bug

My personal preference - if worth anything - is that if a variable
has been declared when used in a for loop, then that variable is used.
Then it is in scope after the loop exits.  If no such variable has
been declared then it is a local to the loop and out of scope as soon
as the loop exits.  This seems entirely consistent with the normal 
practise of variable scoping when functions are defined....

Andy

new topic     » goto parent     » topic index » view message » categorize

13. Re: trace(1) bug

Andy Drummond wrote:

> My personal preference - if worth anything - is that if a variable
> has been declared when used in a for loop, then that variable is used.
> Then it is in scope after the loop exits.  If no such variable has
> been declared then it is a local to the loop and out of scope as soon
> as the loop exits.  This seems entirely consistent with the normal 
> practise of variable scoping when functions are defined....

Please, no. I want this to be a goof:

integer i
  i = find(x,y) -- i is now 32
  for j = 1 to 10 do
    for k = 1 to 10 do
      for i = 1 to 10 do -- DO NOT ALLOW
         ...
      end for
    end for
  end for

  ?i -- better be 32

new topic     » goto parent     » topic index » view message » categorize

14. Re: trace(1) bug

c.k.lester wrote:
> 
> Andy Drummond wrote:
> 
> > My personal preference - if worth anything - is that if a variable
> > has been declared when used in a for loop, then that variable is used.
> > Then it is in scope after the loop exits.  If no such variable has
> > been declared then it is a local to the loop and out of scope as soon
> > as the loop exits.  This seems entirely consistent with the normal 
> > practise of variable scoping when functions are defined....
> 
> Please, no. I want this to be a goof:
> 
> integer i
>   i = find(x,y) -- i is now 32
>   for j = 1 to 10 do
>     for k = 1 to 10 do
>       for i = 1 to 10 do -- DO NOT ALLOW
>          ...
>       end for
>     end for
>   end for
> 
>   ?i -- better be 32

Heck, I'm not doing this at all well.

Why do you want this to goof? If I have a function with local variables, they
are only local. If I refer to a variable I didn't declare locally and it was
declared globally I'd use that. And no matter how deep the nesting, the locals
could all be the same name - all i if you like. If you used a routine-global
variable in more than one nested loop you would expect horrible results - but
you might want that. At present it is not legit so no code would be broken.

So why you expect the i to remain 32 after changing it in a for-loop? If you
had wanted the for-loop iterator to be different then call it something
different.  It seems unreasonable to have a variable in scope, changed, and
yet to preserve an earlier value.  In current terms the DO NOT ALLOW would
have prevented any code to be written which would foul the value of i, but new
coding could use a variable in a loop iterator and yet access it after the loop.
Sounds great to me but ....

Matt - I am missing something fundamental if you disagree - what is it?

AndyD

new topic     » goto parent     » topic index » view message » categorize

15. Re: trace(1) bug

Andy Drummond wrote:
> c.k.lester wrote:
> > Andy Drummond wrote:
> > > My personal preference - if worth anything - is that if a variable
> > > has been declared when used in a for loop, then that variable is used.
> > > Then it is in scope after the loop exits.  If no such variable has
> > > been declared then it is a local to the loop and out of scope as soon
> > > as the loop exits.  This seems entirely consistent with the normal 
> > > practise of variable scoping when functions are defined....
> > Please, no. I want this to be a goof:
> > integer i
> >   i = find(x,y) -- i is now 32
> >   for j = 1 to 10 do
> >     for k = 1 to 10 do
> >       for i = 1 to 10 do -- DO NOT ALLOW
> >          ...
> >       end for
> >     end for
> >   end for
> >   ?i -- better be 32
> Why do you want this to goof?

Because it's a mistake. In this case, I did not intend to overwrite the
'i' variable; I did it on accident.

> So why you expect the i to remain 32 after changing it in a for-loop? If you
> had wanted the for-loop iterator to be different then call it something
> different.

Right now the interpreter protects programmers from making this mistake. If
you want to be able to use an already-declared variable in a for loop, make
a new way to iterate. Don't mess with for...end for!

new topic     » goto parent     » topic index » view message » categorize

16. Re: trace(1) bug

c.k.lester wrote:
> 
> Andy Drummond wrote:
> > c.k.lester wrote:
> > > Andy Drummond wrote:
> > > > My personal preference - if worth anything - is that if a variable
> > > > has been declared when used in a for loop, then that variable is used.
> > > > Then it is in scope after the loop exits.  If no such variable has
> > > > been declared then it is a local to the loop and out of scope as soon
> > > > as the loop exits.  This seems entirely consistent with the normal 
> > > > practise of variable scoping when functions are defined....
> > > Please, no. I want this to be a goof:
> > > integer i
> > >   i = find(x,y) -- i is now 32
> > >   for j = 1 to 10 do
> > >     for k = 1 to 10 do
> > >       for i = 1 to 10 do -- DO NOT ALLOW
> > >          ...
> > >       end for
> > >     end for
> > >   end for
> > >   ?i -- better be 32
> > Why do you want this to goof?
> 
> Because it's a mistake. In this case, I did not intend to overwrite the
> 'i' variable; I did it on accident.
> 
> > So why you expect the i to remain 32 after changing it in a for-loop? If you
> > had wanted the for-loop iterator to be different then call it something
> > different.
> 
> Right now the interpreter protects programmers from making this mistake. If
> you want to be able to use an already-declared variable in a for loop, make
> a new way to iterate. Don't mess with for...end for!

What you say is true, of course. It just seems odd that a variable created
within and scoped only to a for-next loop precludes that variable being what
is effectively a non-local variable. It's as if using a local variable x
stopped you having a global variable x - of course it doesn't; you use the
global x or a local x. If you use the global x and change it then the global
x changes!

It is nice that Euphoria allows you to define for-loop iterators in the
loop definition itself.  But that means that if I use i for example in the
loop I am forbidden to have i within the rest of the routine with the loop in.
This means I have one - or more - variables I cannot use within the body of
the routine because they are used in for-loops *even though* I can't access
them within the body of the routine. That seems inconsistent. If I want to
know the iterator value after the exit I have to have another variable to
load it into for that purpose.

I will accept what you say - that if people code wrong they will get wrong
results. But why force procedures that complicate matters - and require more
variables - just so that people can use already defined variables a second
time without fouling up the earlier usage. Surely it isn't too much to expect
programmers to use different variables for different values?

Apart from all that, a change as I suggest - recommend - would not break
existing code because it wouldn't have passed the syntax checking thus far.
But OK, if you must have it this - IMNSHO - inconsistent fashion, so be it.
Euphoria is still a darned good language. If you want it to stay as it is, OK.
If you want improvments then something is gonna have to change...

AndyD

new topic     » goto parent     » topic index » view message » categorize

17. Re: trace(1) bug

Andy Drummond wrote:
> c.k.lester wrote:
> > Right now the interpreter protects programmers from making this mistake. If
> > you want to be able to use an already-declared variable in a for loop, make
> > a new way to iterate. Don't mess with for...end for!
> What you say is true, of course. It just seems odd that a variable created
> within and scoped only to a for-next loop precludes that variable being what
> is effectively a non-local variable. It's as if using a local variable x
> stopped you having a global variable x - of course it doesn't; you use the
> global x or a local x. If you use the global x and change it then the global
> x changes!

Do you mean if I reuse a variable in a for loop, it
should be considered local to that for loop?

i = 324
for i=1 to 10 do
  ?i -- 1,2,3,4,5,6,7,8,9,10
end for
?i -- 324

What if I want to use the i that equals 324 in the loop?

Anyway, my point is I would never want to use a pre-defined variable
in a for loop, and neither would anybody else. :D

> I will accept what you say - that if people code wrong they will get wrong
> results. But why force procedures that complicate matters - and require more
> variables - just so that people can use already defined variables a second
> time without fouling up the earlier usage. Surely it isn't too much to expect
> programmers to use different variables for different values?

What are the benefits of allowing the use of a pre-declared var in a loop?

Of course I want Euphoria to improve. :)

new topic     » goto parent     » topic index » view message » categorize

18. Re: trace(1) bug

<snipped/>
> Apart from all that, a change as I suggest - recommend - would not break
> existing code because it wouldn't have passed the syntax checking thus far.
> But OK, if you must have it this - IMNSHO - inconsistent fashion, so be it.
> Euphoria is still a darned good language. If you want it to stay as it is, OK.
> If you want improvments then something is gonna have to change...
> 
> AndyD

True. However, we have THREE concurrent and mutually inconsistent changes
available:
1/ allow predeclared variables to be used as indexes, which entails that they
are available beyond the loop itself, since they are not scoped;
2/ allow predeclared variables to have the same name as loop indexes, which
makes them invisible outside their procedure, sorry loop;
3/ allow for loop indexes to be visible beyond the end of their loop, till they
are recycled, so that they are still scoped.

Why can't you have all of them at the same time?
Because, if there is a predeclared variable distinct from a loop index of the
same name, it has to be available when it is not shadowed by the more local loop
index. As a result, the loop indexes would be hidden outside of their respective
loop.
And additionally, you have to choose whether you want a loop index to be scoped
or not; can't be both at the same time.

How can you have it both ways?
By having THREE separate constructs, one for when you want the loop indexes
visible beyond end of loop but still scoped, and one where you allow a
predeclared variable to take over. I agree with Derek on this. I just think that
using another loop keyword makes for clearer reading than "for with i=...".
I didn't forget the case where loop indexes are not scoped, because it is
already available as the while loop. Which leaves us with two options actually.

In order to minimise the risk of breaking code, I'd suggest to retain for "for"
a meaning almost identical to what it is now, ie with invisible loop indexes.
Since there is hardly a risk of confusion in allowing a predeclared variable with
the same name, ok for this extension.

The other construct, called "for with", "for_existing" or whatever, would, in
contrast, preclude predeclared variables _so as_ to enable accessing the loop
indexes as long as they are not recycled. Any predeclared variable would be
visible till the first for loop that shadows it; I'm not sure it would help, and
would not recommmend it.

Trying to combine both is bound to cause some confusion, offsetting the
benefits.

I think I have pushed a lot for improvements in the language, which clearly
needs some. But doing so in an inconsistent way would just ruin the whole thing.
Let's call a cat a cat and a dog, a dog, instead of trying to give them the ame
name and see what happens - which is imho what your solution amounts to.

Btw, I'm not too much concerned with bd coding - it will die on its own by not
being copied. I'm more concerned about decreasing the number of pitfalls when
some code is modified. This is where constructs whose behaviour depends on the
context - what you suggest - can bite you in very subtle ways. Having several
distinct constructs with constant behaviour certainly reduces the number of bugs
introduced when upgrading code - one-shot stuff will always work. More keywords,
but more certainty in assessing the coder's intent.

CChris

new topic     » goto parent     » topic index » view message » categorize

19. Re: trace(1) bug

c.k.lester wrote:
> 
> 
> Anyway, my point is I would never want to use a pre-defined variable
> in a for loop, and neither would anybody else. :D

<snip>
 
> What are the benefits of allowing the use of a pre-declared var in a loop?

I think a lot of the impetus behind this initiative is the C-style for loop,
combined with the C++ ability of declaring variables anywhere in a routine.
A C-style for loop has several parts:

 1:  initialize the starting value (and in C++, possibly declare a new 
     variable with the scope of the loop block.
 2:  an expression to evaluate to determine when to exit the loop (end
     the loop when it evaluates to 0)
 3:  an expression to execute to iterate through the loop

Any of these may be empty statements, BTW.  A typical loop might look
something like this:

for( int i = 0; i < max; i++ ){
    // do stuff
}
...which is equivalent to:
for i = 0 to max-1 do
    -- do stuff
end for

But you can also do something like (to mix euphoria and C):
for(object i = gets(fn); sequence(i); i = gets(fn))

end for

It's really more of a structured while loop, where the iterators and 
conditions are all neatly contained at the top of the loop, though the
loop variable (if it exists) can be modified anywhere in the loop, since
it's a regular variable.

I've often considered trying this out in ooeu, since it's such a useful
construct.

Matt

new topic     » goto parent     » topic index » view message » categorize

20. Re: trace(1) bug

c.k.lester wrote:
> 
> Please, no. I want this to be a goof:
> 
> integer i
>   i = find(x,y) -- i is now 32
>   for j = 1 to 10 do
>     for k = 1 to 10 do
>       for i = 1 to 10 do -- DO NOT ALLOW
>          ...
>       end for
>     end for
>   end for
> 
>   ?i -- better be 32

By the same token should the compiler complain about:
integer i
   i = find(x,y) -- i is now 32
   for j = 1 to 10 do
     for k = 1 to 10 do
       i=11
     end for
   end for
 
   ?i -- better be 32


If not, why one and not the other?

In my book both mistakes are equally easily made, found and fixed.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

21. Re: trace(1) bug

Pete Lomax wrote:
> c.k.lester wrote:
> > Please, no. I want this to be a goof:
> > integer i
> >   i = find(x,y) -- i is now 32
> >   for j = 1 to 10 do
> >     for k = 1 to 10 do
> >       for i = 1 to 10 do -- DO NOT ALLOW
> >          ...
> >       end for
> >     end for
> >   end for
> >   ?i -- better be 32
> 
> By the same token should the compiler complain about:
> }}}
<eucode>
> integer i
>    i = find(x,y) -- i is now 32
>    for j = 1 to 10 do
>      for k = 1 to 10 do
>        i=11
>      end for
>    end for
>    ?i -- better be 32
> </eucode>
{{{

> 
> If not, why one and not the other?

Why should it complain in the case you present? i has been declared and
initialized and can now be set at will in the context of the space in
which it was defined. There is no mistake in assigning it a value, and
this would be easy to debug.

> In my book both mistakes are equally easily made, found and fixed.

It might not be easily found in the case I presented, especially if the
declaration and assignment were two screens separate from the errant for
loop.

I admit I'm wanting to protect the coder here from making a mistake that
might be hard to debug. I don't disagree with the construct being suggested
where a variable can be reused in a for loop... I just don't want the
current for...end for behavior changed.

new topic     » goto parent     » topic index » view message » categorize

22. Re: trace(1) bug

c.k.lester wrote:
> 
> Pete Lomax wrote:
> > c.k.lester wrote:
> > >       for i = 1 to 10 do -- DO NOT ALLOW
> > By the same token should the compiler complain about:
> >        i=11
> > If not, why one and not the other?
> 
> Why should it complain in the case you present?
The point I am making is that it should not.

> this would be easy to debug.
Easier than a for loop slip-up?

> > In my book both mistakes are equally easily made, found and fixed.
> 
> It might not be easily found in the case I presented, especially if the
> declaration and assignment were two screens separate from the errant for
> loop.
Why would the assignment error I presented be any easier to find?

> I admit I'm wanting to protect the coder here from making a mistake that
> might be hard to debug.
This I understand, the question I am posing is whether the existing error
message actually gains us any additional protection in practice. The more I think
along the lines of "that error message must be there for a reason, it must be
doing some good", the less I can quantify what that good really is.

Regards,
Pete

new topic     » goto parent     » topic index » view message » categorize

23. Re: trace(1) bug

> I admit I'm wanting to protect the coder here from making a mistake that
> might be hard to debug.

IMHO, why? If the coder wants to use the same variable twice its bad
practice. There are many bad practices. I doubt that you will ever put
enough checks etc in to prevent bad practices without making Eu a dog. 

How about a programming "best practices" doc, where common mistakes and
the consequences and the alternatives can be shown. In the Eu context
mostly. Rob already has a start of this with his common mistakes doc.

If you are not going to be *required* to debug someone else's code,
IE its not a paid for project, leave others alone to code the way they 
want. Coding is a creative process so don't stifle it, IMHO.

Regards
Alan

new topic     » goto parent     » topic index » view message » categorize

24. Re: trace(1) bug

c.k.lester wrote:
> 
> 
> Do you mean if I reuse a variable in a for loop, it
> should be considered local to that for loop?
> 
> i = 324
> for i=1 to 10 do
>   ?i -- 1,2,3,4,5,6,7,8,9,10
> end for
> ?i -- 324
> 
> What if I want to use the i that equals 324 in the loop?
> 
> Anyway, my point is I would never want to use a pre-defined variable
> in a for loop, and neither would anybody else. :D
> 
> > I will accept what you say - that if people code wrong they will get wrong
> > results. But why force procedures that complicate matters - and require more
> > variables - just so that people can use already defined variables a second
> > time without fouling up the earlier usage. Surely it isn't too much to
> > expect
> > programmers to use different variables for different values?
> 
> What are the benefits of allowing the use of a pre-declared var in a loop?
> 
> Of course I want Euphoria to improve. :)

It's good to bat these ideas about to get an improvment in the language...

It is clearly not a good idea to have a single variable name taking two
different values simultaneously in any part of the code.  So when Euphoria
insists that if I declare i as a loop iterator then it MAY NOT be already
in scope or you get this conflict. But that is true ONLY if the interpreter
is not allowed to use the pre-existing variable.

Actually I can see some merit in what is done now; if a loop iterator can 
use existing variables then it must be able to use program-global variables
too, which might cause errors.  So OK, we keep what we have but if the loop 
iterator is to use a pre-existing variable then have something with a buzz-word
like:
   for using i=1 to 10 do
which would be clear to users that the i is to be a variable already in scope.

I still think that if a variable i is used as a for-loop iterator, and goes out
of scope outside the loop, that to disallow any other i to become in scope is
a bit of a limitation - although it does probably reduce programming errors.

I think I have stirred the muddy waters enough on this one; I will now do
what most of you hope and shut up.  ;D

AndyD

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu