1. problems with the scoping in eu4

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]

new topic     » topic index » view message » categorize

2. Re: problems with the scoping in eu4

Hi

bill said...

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?

bill said...

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.

bill said...

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.

bill said...

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?

bill said...
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?

bill said...

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.

bill said...

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.

bill said...

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.

bill said...

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

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

3. Re: problems with the scoping in eu4

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

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

4. Re: problems with the scoping in eu4

coconut said...
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

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

5. Re: problems with the scoping in eu4

coconut said...
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 
bill said...
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?

bill said...
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. blink

bill said...

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.

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

6. Re: problems with the scoping in eu4

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

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

7. Re: problems with the scoping in eu4

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?

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

8. Re: problems with the scoping in eu4

Vinoba said...
if condition then exit

Why not allow |if condition then i = i+7 |

Umm, you can do that. Unless I'm missing your meaning.

Vinoba said...

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.

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

9. Re: problems with the scoping in eu4

coconut said...

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

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

10. Re: problems with the scoping in eu4

coconut said...
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.

coconut said...

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.

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

11. Re: problems with the scoping in eu4

jeremy said...
coconut said...

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.

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

12. Re: problems with the scoping in eu4

jaygade said...

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.

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

13. Re: problems with the scoping in eu4

jaygade said...

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

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

14. Re: problems with the scoping in eu4

jaygade said...

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

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

15. Re: problems with the scoping in eu4

coconut said...
jaygade said...

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

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

16. Re: problems with the scoping in eu4

coconut said...
jaygade said...

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.

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

17. Re: problems with the scoping in eu4

mattlewis said...

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.

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

18. Re: problems with the scoping in eu4

coconut said...
mattlewis said...

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.

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

19. Re: problems with the scoping in eu4

Edit: never mind. The subject changed.

Just what Euphoria needs, yet another storage class.

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

20. Re: problems with the scoping in eu4

jaygade said...

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

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

21. Re: problems with the scoping in eu4

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.

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

22. Re: problems with the scoping in eu4

bill said...

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

bill said...


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.

bill said...


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 
bill said...


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

bill said...


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?

bill said...

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.

bill said...

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.

bill said...

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.

bill said...

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.

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

23. Re: problems with the scoping in eu4

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.

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

24. Re: problems with the scoping in eu4

bill said...

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.

bill said...

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"

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

25. Re: problems with the scoping in eu4

jaygade said...
bill said...

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.

bill said...

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.

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

26. Re: problems with the scoping in eu4

bill said...
jaygade said...
bill said...

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.

bill said...

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.

bill said...

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.

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

27. Re: problems with the scoping in eu4

bill said...

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.

bill said...

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.

bill said...

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.

bill said...

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 
           ^ 

bill said...

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.

bill said...

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

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

28. Re: problems with the scoping in eu4

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.

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

29. Re: problems with the scoping in eu4

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.

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

30. Re: problems with the scoping in eu4

bill said...

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

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

31. Re: problems with the scoping in eu4

jeremy said...
bill said...

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

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

32. Re: problems with the scoping in eu4

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

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

33. Re: problems with the scoping in eu4

Bill said...

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.

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

34. Re: problems with the scoping in eu4

bill said...

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.

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

35. Re: problems with the scoping in eu4

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.

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

36. Re: problems with the scoping in eu4

bill said...
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

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

37. Re: problems with the scoping in eu4

jaygade said...
bill said...

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

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

38. Re: problems with the scoping in eu4

bill said...

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

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

39. Re: problems with the scoping in eu4

bill said...
jeremy said...

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

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

40. Re: problems with the scoping in eu4

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)

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

41. Re: problems with the scoping in eu4

bill said...

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

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

42. Re: problems with the scoping in eu4

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.

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

43. Re: problems with the scoping in eu4

jeremy said...

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

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

44. Re: problems with the scoping in eu4

petelomax said...
jeremy said...

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

petelomax said...

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

petelomax said...

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.

petelomax said...

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.

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

45. Re: problems with the scoping in eu4

jimcbrown said...
jeremy said...

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

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

46. Re: problems with the scoping in eu4

petelomax said...
jimcbrown said...
jeremy said...

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

Matt

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

47. Re: problems with the scoping in eu4

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.

mattlewis said...
petelomax said...
jimcbrown said...
jeremy said...

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

Matt

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

48. Re: problems with the scoping in eu4

jimcbrown said...

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

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

49. Re: problems with the scoping in eu4

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

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

Search



Quick Links

User menu

Not signed in.

Misc Menu