1. problems with the scoping in eu4
- Posted by bill Jan 07, 2011
- 2220 views
1 Shadowing:
One cannot redefine variable names eg
integer f = 0 ... sequence f = {}
is an error
likewise :
for i = 1 to 10 do puts(1,sprintf("%d, ",2*i) end for ... for i = 1 to 20 do .. <= error
however this is different:
integer f = 2 function ff(sequence f = "ok") return f end function puts(1,sprintf("%s\n",ff())) => ok puts(1,sprintf("%d, ",f) => 2
2 while do problems:
Cannot initialise a counter inside a loop
integer r = 4 while r > 0 do integer i = 0 puts(1,sprintf("%d, ",i) i += 1 r -= 1 end while
prints: 0, 0, 0, 0
while r > 0 with entry do integer i = 0 puts(1,sprintf("%d, ",i) r -= 1 entry i += 1 <= at runtime i has no value end while
3 while with entry seems quite unnecessay given exit (using ada loop, end loop & exit when).
sequence ret = {} loop from = find_from (x, source, from) exit when from = 0 ret &= from from += 1 end loop
Exit can take a label.
Now the code executes in order, there is no jump into scope.
4 another reason not to use while with entry (readability).
It places the entry code below any inner loop
5 Switch has problems as well.
switch a case x then integer i = 0 puts(1, sprintf("%d",i)) i += 1 case x+1 then puts(1, sprintf("%d",i)) i += 1## ...
This should compile but cannot work with a = (x+1)
Any declaration before case else allow a jump into scope.
6. Commentary:
ada has anonymous blocks syntax
eg an in-line swap of integers x, y
declare t integer := x begin x := y y := t end
A possible while syntax could be
while condition declare type id [= value] do .. end
I am not saying this is how things should be done but these aspects of Euphoria make the new features difficult to impossible to use.
[matt: added eucode tags]
2. Re: problems with the scoping in eu4
- Posted by ChrisB (moderator) Jan 07, 2011
- 2167 views
Hi
1 Shadowing:
One cannot redefine variable names eg
integer f = 0 ... sequence f = {}
is an error
As it should be - why would you want to redifine a variable within the the same block / scope level?
likewise :
for i = 1 to 10 do puts(1,sprintf("%d, ",2*i) end for ... for i = 1 to 20 do .. <= error
No it doesn't, I use for i loops all over the place, sometimes one after the other.
however this is different:
integer f = 2 function ff(sequence f = "ok") return f end function puts(1,sprintf("%s\n",ff())) => ok puts(1,sprintf("%d, ",f) => 2
This is expected behaviour - these are two separate scope levels, the newly defined variable takes precedence over the one defined in the scope level above. Just use more meaningful variable names if you want clarity.
2 while do problems:
Cannot initialise a counter inside a loop
integer r = 4 while r > 0 do integer i = 0 puts(1,sprintf("%d, ",i) i += 1 r -= 1 end while
prints: 0, 0, 0, 0
Again, I would expect this to happen - i is repeatedly being redefined, and consequently reset. What behaviour would you expect?
while r > 0 with entry do integer i = 0 puts(1,sprintf("%d, ",i) r -= 1 entry i += 1 <= at runtime i has no value end while
Don't you need a label for the entry? Doesn't the entry just define a start point for the first loop run?
3 while with entry seems quite unnecessay given exit (using ada loop, end loop & exit when).
sequence ret = {} loop from = find_from (x, source, from) exit when from = 0 ret &= from from += 1 end loop
Exit can take a label.
Now the code executes in order, there is no jump into scope.
This is how Ada does stuff, not Euphoria.
4 another reason not to use while with entry (readability).
It places the entry code below any inner loop
5 Switch has problems as well.
switch a case x then integer i = 0 puts(1, sprintf("%d",i)) i += 1 case x+1 then puts(1, sprintf("%d",i)) i += 1## ...
This should compile but cannot work with a = (x+1)
Any declaration before case else allow a jump into scope.
Not quite sure I follow that. Aren't the case options defined at the time the switch is executed, so why would you want to make a = x+1, this would equate to saying always do case (x+1), and never do the others.
6. Commentary:
ada has anonymous blocks syntax
eg an in-line swap of integers x, y
declare t integer := x begin x := y y := t end
A possible while syntax could be
while condition declare type id [= value] do .. end
Thats how Ada does stuff, not Euphoria.
I am not saying this is how things should be done but these aspects of Euphoria make the new features difficult to impossible to use.
[matt: added eucode tags]
And I'm not saying that Ada should change to follow the cleaner(and more logical to me) rules of Euphoria either, but I use Euphoria, and I don't use Ada. I hope Euphoria never does become Ada, because then all we'll have is Ada.
Kindest regards
Chris
3. Re: problems with the scoping in eu4
- Posted by coconut Jan 07, 2011
- 2129 views
integer r=5 while r do integer i=0 printf(1,"%d, ",i) i+=1 r-=1 end while
Bill raise a strong point here.
What's the point of beeing able to declare a variable inside a loop construct if its value is reset at each loop cycle?
It would be better to forbid variable declaration inside loop as it was in version 3.x
It is what I suggest concerning variables declarations: a rollback to the situation of version 3.x
And I very like the
exit when condition
this could be added to euphoria 4.x
Jacques
4. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 07, 2011
- 2115 views
integer r=5 while r do integer i=0 printf(1,"%d, ",i) i+=1 r-=1 end while
Bill raise a strong point here.
What's the point of beeing able to declare a variable inside a loop construct if its value is reset at each loop cycle?
It would be better to forbid variable declaration inside loop as it was in version 3.x
It is what I suggest concerning variables declarations: a rollback to the situation of version 3.x
The point is to declare a variable that doesn't persist from loop to loop. I agree that his example doesn't make sense. This is a more sensible use case:
while r do sequence x = s[r] ... use x ... r -= 1 end while
Matt
5. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 2108 views
integer r=5 while r do integer i=0 printf(1,"%d, ",i) i+=1 r-=1 end while
Bill raise a strong point here.
What's the point of beeing able to declare a variable inside a loop construct if its value is reset at each loop cycle?
It would be better to forbid variable declaration inside loop as it was in version 3.x
It is what I suggest concerning variables declarations: a rollback to the situation of version 3.x
And I very like the
exit when condition
this could be added to euphoria 4.x
Jacques
Do this:
if condition then exit end if
for i = 1 to 10 do puts(1,sprintf("%d, ",2*i) end for ... for i = 1 to 20 do .. <= error
I agree that this shouldn't be an error. It never was in the past, has it become an error now?
integer r = 4 while r > 0 do integer i = 0 puts(1,sprintf("%d, ",i) i += 1 r -= 1 end while
prints: 0, 0, 0, 0
while r > 0 with entry do integer i = 0 puts(1,sprintf("%d, ",i) r -= 1 entry i += 1 <= at runtime i has no value end while
I see your point with regards to the first one. This should probably be coded as follows: (untested)
while r > 0 with entry do integer i puts(1, sprintf("%d, ",i) r -= 1 entry if object(i) = 0 then i = 0 -- test and initialize end if i += 1 end while
Although the test does kind of break the utility of "with entry". Maybe there's an even better way of coding that?
Heh - could you do this?
i += object(i)
Probably not.
3 while with entry seems quite unnecessay given exit (using ada loop, end loop & exit when).
sequence ret = {} loop from = find_from (x, source, from) exit when from = 0 ret &= from from += 1 end loop
Enough people wanted "with entry" so the devs added it. Enough people found it clearer than using a do loop. And entry works with do loops as well. To each their own.
6. Re: problems with the scoping in eu4
- Posted by coconut Jan 07, 2011
- 2094 views
if condition then exit end if
I knows I can do that Jason, it's not the point I simply like the cleaner syntax <exit when condition>
Concerning variables declaration I repeat my suggestion to comeback to version 3.x situation.
The actual situation create inconsistancies and confusion without bringing any benefit.
Jacques
7. Re: problems with the scoping in eu4
- Posted by Vinoba Jan 07, 2011
- 2103 views
if condition then exit |
Why not allow |if condition then i = i+7 |
Or the simple question is: Why do developers want to put more restrictions and formalitites instead of allowing programmers idiosyncracies?
8. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 2070 views
if condition then exit |
Why not allow |if condition then i = i+7 |
Umm, you can do that. Unless I'm missing your meaning.
Or the simple question is: Why do developers want to put more restrictions and formalitites instead of allowing programmers idiosyncracies?
I would say because it clutters up the language and makes it harder to understand. If you want more than one way to do it then use Perl. That's the selling point of that language.
But otherwise, has anyone made a feature request of "when condition action"? It's just another wording for if/then in my book. It means the same thing.
9. Re: problems with the scoping in eu4
- Posted by jeremy (admin) Jan 07, 2011
- 2108 views
Concerning variables declaration I repeat my suggestion to comeback to version 3.x situation.
The actual situation create inconsistancies and confusion without bringing any benefit.
I'm lost in this thread, what exactly are you speaking of that was added that does not provide any benefit? Are you speaking of:
sequence names = { "John Doe", "Jim Doe", "Jack Doe", "Joe Doe" } for i = 1 to length(names) do sequence name = names[i] sequence firstName = get_first_name(name) sequence lastName = get_last_name(name) if equal(lastName, "Doe") then printf(1, "CAUTION: Last name is really not known\n") end if printf(1, "Dear Mr. %s,\n\nThank you for your suggestion %s!", { lastName, firstName }) end for
i.e. declaring variables inside of a loop and those variables not persisting? If so (I think that is what we are talking about), that feature brings huge benefit into clean function design. I really hated not being able to do it 3.1. Being able to is a big step ahead for Euphoria. It would be a terrible thing if this functionality were to be reverted.
If you want a variable to persist, then you declare it in the scope it should persist in. For example:
sequence names = { "John Doe", "Jim Doe", "Jack Doe", "Joe Doe" } sequence lastNameProcessed = "None" for i = 1 to length(names) do sequence name = names[i] sequence firstName = get_first_name(name) sequence lastName = get_last_name(name) if equal(lastName, "Doe") then printf(1, "CAUTION: Last name is really not known\n") end if printf(1, "Dear Mr. %s,\n\nThank you for your suggestion %s!", { lastName, firstName }) lastNameProcessed = named end for printf(1, "Sent %d messages, last name processed was %s\n", { length(names), lastNameProcessed })
This is clean design and I'd suggest that everyone begin programming by keeping the variable to the minimum scope necessary.
Jeremy
10. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 07, 2011
- 2063 views
if condition then exit end if
I knows I can do that Jason, it's not the point I simply like the cleaner syntax <exit when condition>
I think dot4 has this.
Concerning variables declaration I repeat my suggestion to comeback to version 3.x situation.
The actual situation create inconsistancies and confusion without bringing any benefit.
Jacques
I don't agree. I've personally benefitted from the new 4.0.0 ability to declare variables anywhere inside a loop.
11. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 2071 views
Concerning variables declaration I repeat my suggestion to comeback to version 3.x situation.
The actual situation create inconsistancies and confusion without bringing any benefit.
I'm lost in this thread, what exactly are you speaking of that was added that does not provide any benefit? Are you speaking of:
sequence names = { "John Doe", "Jim Doe", "Jack Doe", "Joe Doe" } for i = 1 to length(names) do sequence name = names[i] sequence firstName = get_first_name(name) sequence lastName = get_last_name(name) if equal(lastName, "Doe") then printf(1, "CAUTION: Last name is really not known\n") end if printf(1, "Dear Mr. %s,\n\nThank you for your suggestion %s!", { lastName, firstName }) end for
i.e. declaring variables inside of a loop and those variables not persisting? If so (I think that is what we are talking about), that feature brings huge benefit into clean function design. I really hated not being able to do it 3.1. Being able to is a big step ahead for Euphoria. It would be a terrible thing if this functionality were to be reverted.
If you want a variable to persist, then you declare it in the scope it should persist in. For example:
sequence names = { "John Doe", "Jim Doe", "Jack Doe", "Joe Doe" } sequence lastNameProcessed = "None" for i = 1 to length(names) do sequence name = names[i] sequence firstName = get_first_name(name) sequence lastName = get_last_name(name) if equal(lastName, "Doe") then printf(1, "CAUTION: Last name is really not known\n") end if printf(1, "Dear Mr. %s,\n\nThank you for your suggestion %s!", { lastName, firstName }) lastNameProcessed = named end for printf(1, "Sent %d messages, last name processed was %s\n", { length(names), lastNameProcessed })
This is clean design and I'd suggest that everyone begin programming by keeping the variable to the minimum scope necessary.
Jeremy
I don't think that the complaint is persistence outside of the loop. After all, that doesn't even make sense.
I think that the complaint is persistence from iteration to iteration. The variable is either unassigned, or it is reassigned some default value on every new iteration of the loop.
The simple example initially given was a good one, trying to use two counters in one loop.
12. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 07, 2011
- 2068 views
I think that the complaint is persistence from iteration to iteration. The variable is either unassigned, or it is reassigned some default value on every new iteration of the loop.
The simple example initially given was a good one, trying to use two counters in one loop.
If persistence from iteration to iteration is allowed, you'd need to do this:
while 1 do integer i if not object(i) then i = 0 end if i += 1 end while
Which may not be a bad thing.
13. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 07, 2011
- 2037 views
I don't think that the complaint is persistence outside of the loop. After all, that doesn't even make sense.
I think that the complaint is persistence from iteration to iteration. The variable is either unassigned, or it is reassigned some default value on every new iteration of the loop.
The simple example initially given was a good one, trying to use two counters in one loop.
In that case, it's simply misunderstanding how lexical scopes generally work. For example:
#include <stdio.h> int main(){ int i = 5; while( i ){ int j = 0; printf("--i: %d ++j: %d\n", --i, ++j ); } return 0; }
Here's what happens:
$ gcc -oloop loop.c && ./loop --i: 4 ++j: 1 --i: 3 ++j: 1 --i: 2 ++j: 1 --i: 1 ++j: 1 --i: 0 ++j: 1
A variable goes out of scope when the end of its scope is reached. In this case, the scope is the body of the loop. The original request seemed to me to be for the equivalent of C's static (function-level) variables inside a particular scope.
Matt
14. Re: problems with the scoping in eu4
- Posted by coconut Jan 07, 2011
- 2051 views
But otherwise, has anyone made a feature request of "when condition action"? It's just another wording for if/then in my book. It means the same thing.
And the keyword "break" as the same meaning as "exit" but it was added ...
Jacques
15. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 07, 2011
- 2025 views
But otherwise, has anyone made a feature request of "when condition action"? It's just another wording for if/then in my book. It means the same thing.
And the keyword "break" as the same meaning as "exit" but it was added ...
It's similar, but different. exit jumps out of loops (for, while, until), but break jumps out of conditional blocks (if, switch).
It's somewhat subtle, but useful.
Matt
16. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 07, 2011
- 2039 views
But otherwise, has anyone made a feature request of "when condition action"? It's just another wording for if/then in my book. It means the same thing.
And the keyword "break" as the same meaning as "exit" but it was added ...
Jacques
The idea of making 'exit' do the job of break was tossed around, but too much code would have broke.
while 1 do c = gets(h) if atom(c) then exit end if end while
Having the exit statement exit out of the if statement only would have broken old code. A LOT of old code.
17. Re: problems with the scoping in eu4
- Posted by coconut Jan 07, 2011
- 2041 views
The original request seemed to me to be for the equivalent of C's static (function-level) variables inside a particular scope.
Matt
Yes! static variables inside function would be good, as Jeremy hammer it: a variable must have shortest scope as possible. And prensently in euphoria when one need a static variable in a function it must declare it outside the function. (but after rethinking it I wouldn't add this feature to loop structure).
I will add it as a feature request
Jacques
P.S. feature request #588 created.
18. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 07, 2011
- 2060 views
The original request seemed to me to be for the equivalent of C's static (function-level) variables inside a particular scope.
Matt
Yes! static variables inside function would be good, as Jeremy hammer it: a variable must have shortest scope as possible. And prensently in euphoria when one need a static variable in a function it must declare it outside the function. (but after rethinking it I wouldn't add this feature to loop structure).
I will add it as a feature request
Jacques
I'm in favor.
19. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 2060 views
Edit: never mind. The subject changed.
Just what Euphoria needs, yet another storage class.
20. Re: problems with the scoping in eu4
- Posted by coconut Jan 07, 2011
- 2014 views
Edit: never mind. The subject changed.
Just what Euphoria needs, yet another storage class.
Not really a storage class, just a front end directive to tell him to store it as top level variable but lock its visibility inside the function. When transformed in IL code this variable will be like any top level variable.
see static variable thread
21. Re: problems with the scoping in eu4
- Posted by bill Jan 07, 2011
- 2009 views
To summarise, clarify and re-emphasise points:
I am not particularly concerned about syntax. I am concerned about meaning.
1 Inability to reuse for-loop variables:
The issue here is that using i,j,k for loop indices is common practice. It's universal mathematical use just as a,b,c are constants and x,y,z are variables./
The problem in Euphoria is that when the variable has gone out of scope the name and it's type hasn't. That says to me broken scope.
This is emphasised when we see that function parameters do shadowing correctly. The parameter can be of any type and it eclipses the outer declaration only while it is in scope.
2 While loops:
This isn't about static variables. It is about continued re-declaration.
The issue of reusing variables should imply that it is illegal to create variables in a loop as the name will not be released after use.
To say that the variable doesn't persist from loop to loop (Matt) is wrong - the variable should not go out of scope until the loop is exited. Therefore either the variable creates a re-declaration error as in 1 or the the declaration line has to be skipped on subsequent loops.
Initialisation to a constant should be possible if variables can be created in a loop.
One *could* enclose the declaration in an if-test but that is very defensive and is an avoidance of the issue
What should happen is that the the declaration is treated as part of the initialisation of the loop.
3. While with entry:
Starting at the bottom of a loop to avoid initialisation problems is bad design. Performing a sequence of statements out of order is *unstructured*. In the context of variable declaration it is a *jump into scope*.
It will break things.
And it is picked up by the compiler.
Starting at the bottom could mean starting 200+ lines away from the head of the loop (really bad stuff - but possible).
Nesting such loops makes for a kind of spaghetti. Stick a large switch in it and you have a complete mess.
Many may have voted for while with entry as a cute idea based on a single loop which could have been coded as a loop .. exit on condition ... end loop structure. I don't think they were voting for its use with variable declaration, nesting etc.
4. Switch:
No one seems to have commented on this.
Switches tend to be long as they enumerate the values the switch variable can take.
Declaring variables in a switch means they will be in scope over a large piece of terrain and multiple case labels. Jumping into scope will certainly happen. Fall through will allow other ways of coming into scope.
If variable declaration is outlawed in switch it would be no loss. However it raises an issue which is what to do if you want a local variable in a switch.
5 Blocks:
In order to limit the scope of variables it is necessary to be able to declare block scope. Currently that means: use a do once loop, or an if true then .. end if block or a procedure.
A block is conceptually very simple.
Example: in-line swap:
assuming two integers x, y
begin
integer t = x
x = y
y = t
end
If you like it is C's { .. } only {} means sequence.
If there were some expensive procedure to be done a block allows the space to be reclaimed immediately the block is complete.
Clearly blocks like this make more sense than declaring in loops or switches unless loop wide, switch wide scope was needed.
Having its own notation is cleaner than perverting loops or conditionals to this use.
Conclusion:
But first scope needs to be fixed.
22. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 07, 2011
- 1985 views
To summarise, clarify and re-emphasise points:
I am not particularly concerned about syntax. I am concerned about meaning.
1 Inability to reuse for-loop variables:
The issue here is that using i,j,k for loop indices is common practice. It's universal mathematical use just as a,b,c are constants and x,y,z are variables./
The problem in Euphoria is that when the variable has gone out of scope the name and it's type hasn't. That says to me broken scope.
And you see with for loops, this works correctly. The loop counter variable remains visible throughout the entire loop, and its value is persisted throughout until the loop ends. o
This is emphasised when we see that function parameters do shadowing correctly. The parameter can be of any type and it eclipses the outer declaration only while it is in scope.
Agreed. But while for loops (as the loop index variable) and procedures and functions (as function parameters) have the ability to declare variables concurrently with their own declaration, no other loop or conditional structure does. So this is not applicable to them, the normal rules apply there.
Also, the function parameters is a bit of a red herring. Their values are not persisted throughout multiple calls.
2 While loops:
This isn't about static variables. It is about continued re-declaration.
The issue of reusing variables should imply that it is illegal to create variables in a loop as the name will not be released after use.
This is incorrect.
while 1 do -- i not in scope yet -- i = 1 -- crashes puts(1, "ok") integer i -- i now declared i = 1 end while
To say that the variable doesn't persist from loop to loop (Matt) is wrong - the variable should not go out of scope until the loop is exited. Therefore either the variable creates a re-declaration error as in 1 or the the declaration line has to be skipped on subsequent loops.
What should happen is that the the declaration is treated as part of the initialisation of the loop.
The variable doesn't persist from loop to loop. That's what the implementation of Euphoria does. Matt is right. He should know, he designed it. Unless you mean that this is how it *should not* work, i.e. bad design.
This is the way it works. It was a deliberate design decision due to the lack of an explicit block..end block structure (akin to C's braces).
Initialisation to a constant should be possible if variables can be created in a loop.
This works. Why do you imply that it does not?
One *could* enclose the declaration in an if-test but that is very defensive and is an avoidance of the issue
Actually, you can't. If you do that, the declaration goes out of scope as soon as the if-test ends.
3. While with entry:
Many may have voted for while with entry as a cute idea based on a single loop which could have been coded as a loop .. exit on condition ... end loop structure. I don't think they were voting for its use with variable declaration, nesting etc.
A valid point here. entry was introduced long before the variable declaration change was made.
5 Blocks:
In order to limit the scope of variables it is necessary to be able to declare block scope. Currently that means: use a do once loop, or an if true then .. end if block or a procedure.
A block is conceptually very simple.
Example: in-line swap:
assuming two integers x, y
begin
integer t = x
x = y
y = t
end
If you like it is C's { .. } only {} means sequence.
If there were some expensive procedure to be done a block allows the space to be reclaimed immediately the block is complete.
Clearly blocks like this make more sense than declaring in loops or switches unless loop wide, switch wide scope was needed.
Having its own notation is cleaner than perverting loops or conditionals to this use.
I actually think that this is a good idea.
If we do implement blocks, then I'd also consider it a "best practices" to either declare your variables at the top, or in a block.
Conclusion:
But first scope needs to be fixed.
I'm not convinced that it's broken. Keep in mind, that this design came about and a consequence of a lack of an explicit block construct, requiring us to think about what is a logical place to start a new scope and what isn't.
23. Re: problems with the scoping in eu4
- Posted by bill Jan 07, 2011
- 1975 views
All I would really say is the scoping together with, the issue of name, type retention after the scope is exited make a situation where odd things happen.
I would not say that scope is broken because the issues are not that severe.
Not being able to declare a variable in a nested scope of the same name as a variable in outer scope is odd. Being able to declare a parameter of the same name as the outer variable (and for that to operate exactly as one would expect - temporarily shadowing the outer variable) makes things rather more odd.
None of the problems I have mentioned are show stoppers. I think they add complexity and particularity. Other than that well it is certainly programmable and rather elegant.
I guess the problem is elegant designs are often hard to improve.
I dislike while with entry and I think that variable declaration should be prohibited in while and switch, and that Eu should have a clean block scope notation.
24. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 1990 views
Not being able to declare a variable in a nested scope of the same name as a variable in outer scope is odd. Being able to declare a parameter of the same name as the outer variable (and for that to operate exactly as one would expect - temporarily shadowing the outer variable) makes things rather more odd.
I agree with this, and there is another thread discussing it.
None of the problems I have mentioned are show stoppers. I think they add complexity and particularity. Other than that well it is certainly programmable and rather elegant.
I guess the problem is elegant designs are often hard to improve.
I dislike while with entry and I think that variable declaration should be prohibited in while and switch, and that Eu should have a clean block scope notation.
I didn't used to like "with entry", but seeing it used it's utility is pretty clear to me. I don't think that it adds complications.
While I do believe that some clutter has been added to Euphoria, overall the dev team has done a pretty good job. Heck, when Rob initially designed the language he supposedly didn't include a "for" construct because the "while" loop could handle all cases. Without labels or "with entry"
25. Re: problems with the scoping in eu4
- Posted by bill Jan 07, 2011
- 1949 views
Not being able to declare a variable in a nested scope of the same name as a variable in outer scope is odd. Being able to declare a parameter of the same name as the outer variable (and for that to operate exactly as one would expect - temporarily shadowing the outer variable) makes things rather more odd.
I agree with this, and there is another thread discussing it.
None of the problems I have mentioned are show stoppers. I think they add complexity and particularity. Other than that well it is certainly programmable and rather elegant.
I guess the problem is elegant designs are often hard to improve.
I dislike while with entry and I think that variable declaration should be prohibited in while and switch, and that Eu should have a clean block scope notation.
I didn't used to like "with entry", but seeing it used it's utility is pretty clear to me. I don't think that it adds complications.
While I do believe that some clutter has been added to Euphoria, overall the dev team has done a pretty good job. Heck, when Rob initially designed the language he supposedly didn't include a "for" construct because the "while" loop could handle all cases. Without labels or "with entry"
The problem I have is this: I write a lot of parsing code the structure of the code goes something like:
loop
get c
sym = symbol[c]
case c of
...
reading various type of data into variables etc
...
end case
...
end loop
Therefore I am not thinking of small loops with quirky behavior. Usually I don't use for loops because running off the end of a string is likely behaviour given bad data to parse. Using a while loop implies there is is a condition to test for - usually testing what the next character is.
Using an infinite loop is a good solution because the test(s) can be put where they are needed. Thus the motivation behind with entry do is always in the code.
Starting at the bottom of the loop is enticing if you only have while loops and no exit mechanism. Given these with entry do is pointless and potentially obscure.
26. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 1986 views
Not being able to declare a variable in a nested scope of the same name as a variable in outer scope is odd. Being able to declare a parameter of the same name as the outer variable (and for that to operate exactly as one would expect - temporarily shadowing the outer variable) makes things rather more odd.
I agree with this, and there is another thread discussing it.
None of the problems I have mentioned are show stoppers. I think they add complexity and particularity. Other than that well it is certainly programmable and rather elegant.
I guess the problem is elegant designs are often hard to improve.
I dislike while with entry and I think that variable declaration should be prohibited in while and switch, and that Eu should have a clean block scope notation.
I didn't used to like "with entry", but seeing it used it's utility is pretty clear to me. I don't think that it adds complications.
While I do believe that some clutter has been added to Euphoria, overall the dev team has done a pretty good job. Heck, when Rob initially designed the language he supposedly didn't include a "for" construct because the "while" loop could handle all cases. Without labels or "with entry"
The problem I have is this: I write a lot of parsing code the structure of the code goes something like:
loop
get c
sym = symbol[c]
case c of
...
reading various type of data into variables etc
...
end case
...
end loop
Therefore I am not thinking of small loops with quirky behavior. Usually I don't use for loops because running off the end of a string is likely behaviour given bad data to parse. Using a while loop implies there is is a condition to test for - usually testing what the next character is.
How do you run off the end of a string if you know the length?
This isn't C.
Using an infinite loop is a good solution because the test(s) can be put where they are needed. Thus the motivation behind with entry do is always in the code.
Starting at the bottom of the loop is enticing if you only have while loops and no exit mechanism. Given these with entry do is pointless and potentially obscure.
I don't understand your statement here.
You can use an infinite loop. You can either add essential initialization language before the loop begins or you can add it after "entry". It is best used when the initial condition is something which is repeated on every iteration of the loop but which is less important than the test.
It helps eliminate violations of the rule "don't repeat yourself".
Your second statement makes no sense. Why start at the bottom of the loop? Why "only while loops and no exit mechanism"? "with entry" is a new addition, not something which has been with the language from the beginning.
27. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 07, 2011
- 1975 views
To summarise, clarify and re-emphasise points:
I am not particularly concerned about syntax. I am concerned about meaning.
1 Inability to reuse for-loop variables:
The issue here is that using i,j,k for loop indices is common practice. It's universal mathematical use just as a,b,c are constants and x,y,z are variables./
The problem in Euphoria is that when the variable has gone out of scope the name and it's type hasn't. That says to me broken scope.
I don't know where you got this idea. You can reuse for loop variables as much as you want.
2 While loops:
This isn't about static variables. It is about continued re-declaration.
The issue of reusing variables should imply that it is illegal to create variables in a loop as the name will not be released after use.
To say that the variable doesn't persist from loop to loop (Matt) is wrong - the variable should not go out of scope until the loop is exited. Therefore either the variable creates a re-declaration error as in 1 or the the declaration line has to be skipped on subsequent loops.
Well, you may think that's how it should work, but I disagree.
[quote bill]
3. While with entry:
Starting at the bottom of a loop to avoid initialisation problems is bad design. Performing a sequence of statements out of order is *unstructured*. In the context of variable declaration it is a *jump into scope*.
It will break things.
And it is picked up by the compiler.
Starting at the bottom could mean starting 200+ lines away from the head of the loop (really bad stuff - but possible).
It's a choice of evils I suppose. Allow coders to avoid repeating themselves, or adhere to super strict structured programming paradigms. A 200+ line loop is bad stuff no matter what structured or unstructured programming is involved.
Many may have voted for while with entry as a cute idea based on a single loop which could have been coded as a loop .. exit on condition ... end loop structure. I don't think they were voting for its use with variable declaration, nesting etc.
They may have, but I didn't. You either change the flow of the code, or move the condition to the bottom, which for me at least, makes the loop more difficult to read. Sorry, I really can't figure out what this has to do with the additional, smaller scopes.
4. Switch:
No one seems to have commented on this.
Switches tend to be long as they enumerate the values the switch variable can take.
Declaring variables in a switch means they will be in scope over a large piece of terrain and multiple case labels. Jumping into scope will certainly happen. Fall through will allow other ways of coming into scope.
If variable declaration is outlawed in switch it would be no loss. However it raises an issue which is what to do if you want a local variable in a switch.
It is possible that no one has commented because they could not figure out what you were talking about. Again, it's certainly not euphoria 4.0. For example:
-- bug.ex integer c = getc(0) switch c do case 'a' then integer x = 1 ? x case 'b' then ? x end switch
$ eui bug bug.ex:8 <0074>:: Errors resolving the following references: bug.ex (8): x ? x ^
5 Blocks:
In order to limit the scope of variables it is necessary to be able to declare block scope. Currently that means: use a do once loop, or an if true then .. end if block or a procedure.
I recall talking about doing this, though we settled on using the blocks defined by existing euphoria flow control. The then/do...end blocks define our scoped blocks. I might be worth revisiting adding an explicit block. I don't recall why we decided against it.
Conclusion:
But first scope needs to be fixed.
While I admit that there are additional ways in which euphoria scopes could be enhanced or refined, I really don't see any existing bugs that need fixing. In fact, in several cases, euphoria already does what you said it should, and trying to do what you think it does will result in an error.
Matt
28. Re: problems with the scoping in eu4
- Posted by jaygade Jan 07, 2011
- 1962 views
I think his point about reusing for-loop variables is that you cannot have a normal variable with the same name as the for-loop variable. It's related to the masking issue we've been discussing.
integer idx = 0 for idx = 1 to 10 do -- error! ? idx end for
Maybe kind of silly, but I think it and the block scope variable masking has a lot to do with all the namespace issues the dev team has been trying to fix/make sane since the beginning.
29. Re: problems with the scoping in eu4
- Posted by bill Jan 08, 2011
- 1976 views
About the switch:
I may have mis-read but I believe it is what the manual said.
I am interested in Euphoria because it is simple and fast enough for what I want.
I don't want to get into a big dispute about features and mis-features.
About delarations in loops I am clearly of the opinion it is a mis-feature. Perhaps I am in a minority of one thinking this. Also I think while with entry is a mis-feature again it is my opinion.
If I use Euphoria I will not use these features.
30. Re: problems with the scoping in eu4
- Posted by jeremy (admin) Jan 08, 2011
- 1923 views
About delarations in loops I am clearly of the opinion it is a mis-feature. Perhaps I am in a minority of one thinking this. Also I think while with entry is a mis-feature again it is my opinion.
If I use Euphoria I will not use these features.
Quite a few other languages must be in err as well, C/C++, Java, D for a few. Not that we are trying to copy those, but when you declare a variable inside of a loop, it just makes sense that the declaration occur each iteration of the loop.
For example:
integer cnt = 1 for i = 1 to 10 do cnt += 1 ? cnt end for
You would expect that cnt += 1 would execute 10 times, no? Not 1 time, 5 or 8 times, correct? Why, then, would:
for i = 1 to 10 do integer ten_i = i * 10 ? ten_i end for
be any different? Each iteration, just as cnt += 1 is executed, integer ten_i = i * 10 is executed. To do anything different would be very confusing, bug producing, extremely complicated to explain and use, IMHO. For example, I don't even know what the above program should do if it didn't initialize ten_i each iteration as the code says.
Now, the with entry, I feel it's a great option. About jumping around, a loop is nothing but a conditional goto, the with entry is also nothing but a goto. Both make sense to me and both make my existing programs simpler. The less code I write as a developer means the more productive I will be (within reason of course). Thus, nice shortcuts like this make me as a developer more productive thus as an employee more profitable. In todays programming market, I enjoy being more profitable to my clients. Yes, something as simple as with entry makes a difference in clarity or code and profitability.
Jeremy
31. Re: problems with the scoping in eu4
- Posted by bill Jan 08, 2011
- 1856 views
About delarations in loops I am clearly of the opinion it is a mis-feature. Perhaps I am in a minority of one thinking this. Also I think while with entry is a mis-feature again it is my opinion.
If I use Euphoria I will not use these features.
Quite a few other languages must be in err as well, C/C++, Java, D for a few. Not that we are trying to copy those, but when you declare a variable inside of a loop, it just makes sense that the declaration occur each iteration of the loop.
For example:
integer cnt = 1 for i = 1 to 10 do cnt += 1 ? cnt end for
You would expect that cnt += 1 would execute 10 times, no? Not 1 time, 5 or 8 times, correct? Why, then, would:
for i = 1 to 10 do integer ten_i = i * 10 ? ten_i end for
be any different? Each iteration, just as cnt += 1 is executed, integer ten_i = i * 10 is executed. To do anything different would be very confusing, bug producing, extremely complicated to explain and use, IMHO. For example, I don't even know what the above program should do if it didn't initialize ten_i each iteration as the code says.
You are missing the point.
What has been created is a block scope which finishes at the end of the loop. What has not been created is a block scope which is the whole of the loop.
If the scope was the whole of the loop then clearly the line integer ten_i could only be run once (at initialisation of the while). Thus it could be given a value.
I am not saying that doing this is good, I'm saying declaring variables inside loops as it is done in Euphoria with Euphoria semantics is very odd particularly so with the use of with entry
The problem is highlighted by this code:
1 while f > 0 with entry do 2 integer sum = 0 3 ... 4 entry 5 f = ... 6 sum += 7 end while
It compiles because the reference to sum is in scope. It dies because line 2 has not been executed.
You may say this is an abuse of with entry. But who is to say what needs to be done before the test is made? And you cannot limit scope to the lines before entry without making while with entry a special case.
You don't have block scope.
You don't have loop scope.
You have buggy here to end of loop scope.
Any variable declared inside a loop is in scope for any while, switch, if, function, procedure which comes after the declaration because scope is to the end. And is out of scope for lines after with entry on the first iteration. This is why Euphorias while scope is bad. Because it is unstructured.
The problem can be partly resolved retaining locality by writing this
if TRUE then -- begin block integer sum = 0 while f > 0 with entry do ... entry f = ... sum += f end while end if -- end block
Which is better written as:
if TRUE then integer sum = 0 while TRUE do f = ... sum += f exit when ... (or if f=0 then exit end if) ... end while end if
If I want a block inside the while I can do the same there
if TRUE then -- begin block integer sum = 0 while f > 0 with entry do ... if TRUE then integer x -- declaration in the if-block not the while ... -- will this pollute the while's namespace? end if ... entry f = ... sum += f end while end if -- end block
These declarations are much more useful than declarations in while .. end while scope.
However it is a pain to use clumsy notation like this.
Really what was needed (and only this):
declare [declarations] begin [run this code] end
Better code could be this:
declare integer sum = 0 begin loop f = ... exit when f = 0 sum += f declare integer x begin ... end ... end loop end
Now, the with entry, I feel it's a great option. About jumping around, a loop is nothing but a conditional goto, the with entry is also nothing but a goto. Both make sense to me and both make my existing programs simpler. The less code I write as a developer means the more productive I will be (within reason of course). Thus, nice shortcuts like this make me as a developer more productive thus as an employee more profitable. In todays programming market, I enjoy being more profitable to my clients. Yes, something as simple as with entry makes a difference in clarity or code and profitability.
Jeremy
You are wrong. If a loop is nothing but a goto then there is nothing sepecial about a loop. It is true a loop could be:
:loop if f = 0 goto end ... goto loop ... :end
And you can merrily jump around through your code. You had better have global scope and a good debugger as you need both.
It is like that in sed and other obscure languages - (obscure as in difficult to understand).
However Euphoria loops have scope. There your argument falls down.
Declaring variables in while loops is not helpful.
With entry is an unneeded kludge presumably brought into existence by the lack of an exit statement.
With/without fallthru is undesirable - switch should have.
Surely
loop [run this code] [check for exit] [run more code] end loop
is less cumbersome, difficult to undestand and problematic than
goto x loop [check for exit] [run more code] -- declare and use loop declared variables here :x [run this code] -- no loop variables here end loop
Bill
32. Re: problems with the scoping in eu4
- Posted by bill Jan 08, 2011
- 1807 views
Quoting Jayglade
think his point about reusing for-loop variables is that you cannot have a normal variable with the same name as the for-loop variable. It's related to the masking issue we've been discussing.
integer idx = 0 for idx = 1 to 10 do -- error! ? idx end for
Maybe kind of silly, but I think it and the block scope variable masking has a lot to do with all the namespace issues the dev team has been trying to fix/make sane since the beginning.
No: my point was that the for loop variable pollutes the outer namespace.
for i ... end for
for i ... end for <= is a re-declaration error
Masking is a somewhat separate issue as it is about being able to declare variables in nested scope
The for loop variable should not be accessible outside of the scope of the for. That should mean that separate non-nested fors should be able to use the same index name
Bill
33. Re: problems with the scoping in eu4
- Posted by jaygade Jan 08, 2011
- 1834 views
Declaring variables in while loops is not helpful. With entry is an unneeded kludge presumably brought into existence by the lack of an exit statement. With/without fallthru is undesirable - switch should have.
Umm, how is it unhelpful to be able to declare variables in while loops? I mean, it's not a feature that I would necessarily use and I think that it would be enhanced by being a true masking scope, but even without that I can see the utility of it.
With regards to "with entry" and the lack of an exit statement, umm, an exit statement exists. It is very flexible. You can even follow it with a certain number representing the loop depth or a specific label representing a specific loop. I'm not sure if any other language is so flexible.
With regards to switch statements and with or without fallthru, well, your statement was cut off. Can you explain better? People in the community could not decide whether a C-style switch (with fallthru) or a BASIC-style switch (without fallthru) so both were added, with the BASIC-style being the default.
34. Re: problems with the scoping in eu4
- Posted by jaygade Jan 08, 2011
- 1765 views
No: my point was that the for loop variable pollutes the outer namespace.
for i ... end for
for i ... end for <= is a re-declaration error
Masking is a somewhat separate issue as it is about being able to declare variables in nested scope
The for loop variable should not be accessible outside of the scope of the for. That should mean that separate non-nested fors should be able to use the same index name
Bill
Then you are incorrect. This works without error, and has at least back to the 1.4 version days.
35. Re: problems with the scoping in eu4
- Posted by jaygade Jan 08, 2011
- 1793 views
Just saying, not trying to discourage you by being overly confrontational. If you are truly interested in giving helpful advice and learning about the language then that is cool.
36. Re: problems with the scoping in eu4
- Posted by jeremy (admin) Jan 09, 2011
- 1799 views
declare integer sum = 0 begin loop f = ... exit when f = 0 sum += f declare integer x begin ... end ... end loop end
In programming you should keep your scopes and methods as small as possible by nature. If a function begins to take on more that a loop or two, then that's a pretty good sign it needs to be split. Rarely have I seen a case in Euphoria that the above is really necessary. For example:
function compute_sum(sequence nums) integer sum = 0 for i = 1 to length(nums) do sum += nums[i] end for return sum end function
i.e. the containing block has always been suitable. We have discussed a block ... end block in the past. That may come in the future, but I personally do not see it as a big priority. Now, I think you're missing the point a bit with declaring values inside of a loop, here is a sample I posted before where this is valuable, and this scenario I run into all the time unlike having problems of the containing scope being too large for my likings as described above in your quote and my example above.
sequence names = { "John Doe", "Jane Doe", "Jim Doe" } for i = 1 to length(names) do sequence name = names[i] sequence first_name = get_first_name(name) sequence last_name = get_last_name(name) -- do a bunch of stuff w/first and last name end for
That is a valid and very common pattern in coding that I have been involved with.
Jeremy
37. Re: problems with the scoping in eu4
- Posted by jeremy (admin) Jan 09, 2011
- 1785 views
No: my point was that the for loop variable pollutes the outer namespace.
for i ... end for
for i ... end for <= is a re-declaration error
Masking is a somewhat separate issue as it is about being able to declare variables in nested scope
The for loop variable should not be accessible outside of the scope of the for. That should mean that separate non-nested fors should be able to use the same index name
Bill
Then you are incorrect. This works without error, and has at least back to the 1.4 version days.
Yes, this works. With a for loop, the variable name is an implicit declaration.
for i = 1 to 5 do ? i end for ? i -- Error... i is not defined.
Another example
for i = 1 to 3 do ? { 1, i } end for for i = 4 to 6 do ? { 2, i } end for
Output is:
{ 1, 1 } { 1, 2 } { 1, 3 } { 2, 4 } { 2, 5 } { 2, 6 }
Jeremy
38. Re: problems with the scoping in eu4
- Posted by jeremy (admin) Jan 09, 2011
- 1785 views
the use of with entry
The problem is highlighted by this code:
1 while f > 0 with entry do 2 integer sum = 0 3 ... 4 entry 5 f = ... 6 sum += 7 end while
It compiles because the reference to sum is in scope. It dies because line 2 has not been executed.
This is a coding error, somewhat like this:
integer sum if xyz > 1 then sum = 0 elsif xyz < -20 then sum = 100 end if sum += 1
If you understand with entry and have a valid use for it, then you will not have coding errors like you illustrate above. Your example above is misusing with entry and also not understanding how scoping works in Euphoria. The sum, in that case, even if it incremented, would always be reset to zero. The way to write your loop above is:
integer sum = 0 while f > 0 with entry do ... entry f = ... sum += end while
with entry is not for every loop, but many loops it makes the code cleaner, no duplication and thus easier to understand, less potential for initial bugs and for bugs due to later maintenance. For example:
public function find_all(object needle, sequence haystack, integer start=1) integer kx = 0 while start with entry do kx += 1 haystack[kx] = start start += 1 entry start = find(needle, haystack, start) end while haystack = remove( haystack, kx+1, length( haystack ) ) return haystack end function
Jeremy
39. Re: problems with the scoping in eu4
- Posted by jeremy (admin) Jan 09, 2011
- 1785 views
Now, the with entry, I feel it's a great option. About jumping around, a loop is nothing but a conditional goto, the with entry is also nothing but a goto. Both make sense to me and both make my existing programs simpler. The less code I write as a developer means the more productive I will be (within reason of course). Thus, nice shortcuts like this make me as a developer more productive thus as an employee more profitable. In todays programming market, I enjoy being more profitable to my clients. Yes, something as simple as with entry makes a difference in clarity or code and profitability.
You are wrong. If a loop is nothing but a goto then there is nothing sepecial about a loop. It is true a loop could be:
:loop if f = 0 goto end ... goto loop ... :end
And you can merrily jump around through your code. You had better have global scope and a good debugger as you need both.
It is like that in sed and other obscure languages - (obscure as in difficult to understand).
However Euphoria loops have scope. There your argument falls down.
Yes. You are correct loops have scope. I was talking more in regards to how a loop jumps and relating that to how with entry also jumps, just like a loop but my statement was not well written, thus incorrect.
Also, as a side note. You do not need all the \\ at the end of your lines. The forum handles making proper paragraphs itself. Simply separate your paragraphs with an empty line.
Jeremy
40. Re: problems with the scoping in eu4
- Posted by bill Jan 09, 2011
- 1753 views
Re:
public function find_all(object needle, sequence haystack, integer start=1) integer kx = 0 while start with entry do kx += 1 haystack[kx] = start start += 1 entry start = find(needle, haystack, start) end while haystack = remove( haystack, kx+1, length( haystack ) ) return haystack end function
Two criticisms:
1 The function by default has start=1. Calling the function with start=0 is an error. Calling the function with a value out of range is possible. Calling with a negative index is also possible (think Python). This could easily be avoided by either:
a. Asserting start has to be in range 1..length(haystack) or at least > 0 # certainly a good idea.
b. silently ignore the error. If it is filter code you may not be allowed to bail out. But this is not such a good idea as negative numbers will throw errors.
The function looks pretty strange. I really do not see what it is trying to do. Perhaps the remove escaped the loop.
2 Dealing correctly with 1 means start has a value. But there is still a problem about using a while loop. start is pointing at an object, it may not be the object we want to remove..
OK: this is not Euphoria code - it's rather a mish-mash and it's a somewhat different task:
function delchar(char c, string s, int start) return string assert(start in 1..length(s),"start not in range fn: find") -- note: at this point start is in range but probably isn't -- pointing to a delchar loop start = index(s, c, start) -- find a delchar exit when start = 0 s = substr(s,1,start-1) || substr(s,start+1) end loop return s end function
That doesn't falsify anything.
Final note: while with entry do is apart from anything else defensive programming.
If you are going to go into a while loop then it is a very bad idea not to have a valid loop variable.
Dropping into the last line of the while in this particular instance hides the fact that the algorithm was incorrect.
On that point: types are a very good idea. as one can declare a type of (say :) ) index as:
type index(integer i) i > 0 end type
Re my bad creole - I started using it yesterday. I like to have things turn out the way I want not how some translator decides.
Re my original post: The issue about not being able to use:
for i = ... end for
for i = ... end for
seems to be some kind of problem with the interpreter and (perhaps) the OS. The problem wasn't there today when I ran equivalent code, but today I had a strange thing happen:
The code it apparently objected to was printf("a: %s\n",a) OK it was wrong and it told me so - but then I found my PATH variable was mutilated.
It wasn't dreadful. I didn't lose my session or anything - but when I started a new xterm the history didn't have anything from that session. Strange.
I use Slackware 13. I can't give you a full report as the session was pretty screwed up and I wasn't really thinking of you guys - but rather of - how badly is this screwed?
Bill (bye)
41. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 09, 2011
- 1767 views
Quoting Jayglade
think his point about reusing for-loop variables is that you cannot have a normal variable with the same name as the for-loop variable. It's related to the masking issue we've been discussing.
integer idx = 0 for idx = 1 to 10 do -- error! ? idx end for
Maybe kind of silly, but I think it and the block scope variable masking has a lot to do with all the namespace issues the dev team has been trying to fix/make sane since the beginning.
No: my point was that the for loop variable pollutes the outer namespace.
for i ... end for
for i ... end for <= is a re-declaration error
Masking is a somewhat separate issue as it is about being able to declare variables in nested scope
The for loop variable should not be accessible outside of the scope of the for. That should mean that separate non-nested fors should be able to use the same index name
Why do you keep saying this? Why do you believe this? I told you that it wasn't how euphoria works. Have you tried this? It's clear to me you have not. Are you simply trolling? Try this:
procedure main() for i = 1 to 2 do ? i end for for i = 3 to 4 do ? i end for end procedure main() main()
Matt
42. Re: problems with the scoping in eu4
- Posted by bill Jan 09, 2011
- 1771 views
- Last edited Jan 10, 2011
Matt:
You are right, if you had read my last post you would have read this:
Re my original post: The issue about not being able to use:
for i = ... end for for i = ... end for
[added eucode tags: SDP]
seems to be some kind of problem with the interpreter and (perhaps) the OS. The problem wasn't there today when I ran equivalent code, but today I had a strange thing happen:
The code it apparently objected to was
printf("a: %s\n",a)
. OK it was wrong and it told me so - but then I found my PATH variable was mutilated.
It wasn't dreadful. I didn't lose my session or anything - but when I started a new xterm the history didn't have anything from that session. Strange.
I don't know what the error was that gave me the cannot redefine message. It is possible I was mistaken (It was one among a number of tests I was running).
The problem today is also hard to explain. I note that someone on the site asked whether Euphoria might have done a setenv and this was denied. The problem I encountered could have been related as in slackware . is not in the system path - it is in the user path. Apart from anything else which might have been wrong after the error the session could not find /Desktop/euphoria/bin.
Please, do not take these as personal criticisms. It was easy to believe the for loop thing given the other issues. I am not sure that it wasn't a Euphoria error but it clearly wasn't simply a redefine error.
43. Re: problems with the scoping in eu4
- Posted by petelomax Jan 09, 2011
- 1742 views
with entry is not for every loop, but many loops it makes the code cleaner, no duplication and thus easier to understand, less potential for initial bugs and for bugs due to later maintenance. For example:
public function find_all(object needle, sequence haystack, integer start=1) integer kx = 0 while start with entry do kx += 1 haystack[kx] = start start += 1 entry start = find(needle, haystack, start) end while haystack = remove( haystack, kx+1, length( haystack ) ) return haystack end function
Jeremy
I have to say I'm in the "don't like with entry" crowd. For me the above looks like the while loop will not run for a find_all(,,0) call (I believe bill has the same impression).
I also feel that I might be tempted to code:
public function find_all(object needle, sequence haystack, integer start=1) integer kx = 0 if find(needle,ignore_set) then start = 0 end if while start with entry do kx += 1 haystack[kx] = start start += 1 entry start = find(needle, haystack, start) end while haystack = remove( haystack, kx+1, length( haystack ) ) return haystack end function
It just seems illogical to me that the test occurs first in the source code but is not executed until much later.
Also, can I ask why remove() when haystack=haystack[1..kx] would do the same job, or am I missing something?
The other point that strikes me is that you cannot code:
while start with entry do integer start ... entry start = find(needle, haystack, start) end while
Regards, Pete
44. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 09, 2011
- 1692 views
with entry is not for every loop, but many loops it makes the code cleaner, no duplication and thus easier to understand, less potential for initial bugs and for bugs due to later maintenance. For example:
public function find_all(object needle, sequence haystack, integer start=1) integer kx = 0 while start with entry do kx += 1 haystack[kx] = start start += 1 entry start = find(needle, haystack, start) end while haystack = remove( haystack, kx+1, length( haystack ) ) return haystack end function
Jeremy
I have to say I'm in the "don't like with entry" crowd. For me the above looks like the while loop will not run for a find_all(,,0) call (I believe bill has the same impression).
also did you mean haystack[kx] = haystack[start]?
No, find_all() returns a sequence of indexes so you know where each needle is located in the haystack.
This change would mean that haystack returns either an empty sequence or a sequence of needles, repeated over. length(ret) would tell you how many instances of needles were found, but beyond that it wouldn't be very useful....
Also, why remove() when haystack=haystack[1..kx] would do the same job, or am I missing something?]
remove() is a builtin that is especially optimized to do work in-place when assigning the result back to the original sequence. Same trick as append(), really.
The other point that strikes me is that you cannot code:
while start with entry do integer start ... entry start = find(needle, haystack, start) end while
Regards, Pete
Maybe that should be allowed to work. Hmm...
But, to make it work right now, one just have to put "integer start" outside of the loop. It may not be ideal, but at least there's no need to duplicate code for this case.
45. Re: problems with the scoping in eu4
- Posted by petelomax Jan 09, 2011
- 1672 views
with entry ... no duplication
... but at least there's no need to duplicate code for this case.
You are both inventing this. It is always perfectly ok to replace
while <condition> with entry do <block a> entry <block b> end while
with the much clearer
while true do <block b> if not <condition> then exit end if <block a> end while
You can like "with entry" and I can dislike it, but please stop saying it removes code duplication or makes things easier to read when it achieves neither.
Regards,
Pete
46. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 09, 2011
- 1667 views
with entry ... no duplication
... but at least there's no need to duplicate code for this case.
You are both inventing this. It is always perfectly ok to replace
while <condition> with entry do <block a> entry <block b> end while
with the much clearer
while true do <block b> if not <condition> then exit end if <block a> end while
You can like "with entry" and I can dislike it, but please stop saying it removes code duplication or makes things easier to read when it achieves neither.
It's a fair point, that absolute claims regarding style preferences are going to wrong. While the code is no less correct using an if-then-exit pattern, personally, I find it more difficult to read, and so I'd say it's neither always perfectly ok, nor much clearer. I'd usually rather duplicate some code to initialize the condition.
So, yes, I guess we'll agree to disagree.
Matt
47. Re: problems with the scoping in eu4
- Posted by jimcbrown (admin) Jan 09, 2011
- 1668 views
Hmm, actually he has a fair point.
This doesn't work
while start with entry do integer start ... entry start = ... end while
But this does work
while 1 do integer start ... if not start then exit end if start = ...
Hmm.
with entry ... no duplication
... but at least there's no need to duplicate code for this case.
You are both inventing this. It is always perfectly ok to replace
while <condition> with entry do <block a> entry <block b> end while
with the much clearer
while true do <block b> if not <condition> then exit end if <block a> end while
You can like "with entry" and I can dislike it, but please stop saying it removes code duplication or makes things easier to read when it achieves neither.
It's a fair point, that absolute claims regarding style preferences are going to wrong. While the code is no less correct using an if-then-exit pattern, personally, I find it more difficult to read, and so I'd say it's neither always perfectly ok, nor much clearer. I'd usually rather duplicate some code to initialize the condition.
So, yes, I guess we'll agree to disagree.
Matt
48. Re: problems with the scoping in eu4
- Posted by mattlewis (admin) Jan 09, 2011
- 1642 views
Hmm, actually he has a fair point.
This doesn't work
while start with entry do integer start ... entry start = ... end while
But this does work
while 1 do integer start ... if not start then exit end if start = ...
I'm not sure what that point would be. Are there languages where the first example would be expected to work? What would it do? What if you declared a variable named start previously? Which start would you expect to use?
The problem with the first example is that it's using a variable outside of its scope. I'm sure we'd all expect this to fail:
procedure my_loop() integer start while start do .... end while end procedure my_loop() if start then .... end if
I don't see the difference. I suppose euphoria's use of then/do..end instead of curly braces is confusing people about how scopes work. But if you saw (warning, C code ahead):
while( start ) { int start ... if( !start ) break; ... }
...it's pretty obvious that the start in the while condition is not the same start as one inside the block of code for the loop.
Matt
49. Re: problems with the scoping in eu4
- Posted by SDPringle Jan 10, 2011
- 1593 views
Hello Bill. I am a developer of EUPHORIA and I have tested this software hundreds of times. From experience, some interpreter bugs are difficult to produce. They can be unlikely to show their symptoms in similar contexts. A bug might appear to be fixed on one platform yet be broken on yours. At times the other developers can be skeptical of what you say. However, many of the code samples you supplied contained syntax bugs and it is impossible to track down a bug we cannot reproduce ourselves.
It would be helpful if you included a full source listing with the for and the contents of the ex.err file that gets created. Let us know which version of EUPHORIA you are using. There are several versions 4.0: released, release candidates, betas and alphas.
This source file executes without an error.
include std/console.e for i = 1 to 10 do puts(1,sprintf("%d, ",2*i) ) end for for i = 1 to 20 do puts(1,sprintf("%d, ",2*i) ) end for any_key()
Shawn Pringle