1. foreach

I think euphoria 4.0 should have a foreach block.

Example:

foreach x in s do 
    puts(1, x) 
end foreach 
 
--vs 
for x = 1 to length(s) do 
    puts(1, s[x]) 
end for 

Ryan J.

new topic     » topic index » view message » categorize

2. Re: foreach

I think it would be a nice addition. I am not sure myself what it would take to add, but I wouldn't think it would be much code???

Jeremy

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

3. Re: foreach

Why don't you guys release 4.0 with out adding features then add all these features in 4.1. Let the public pound on what you have finished so far.

Shawn Pringle

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

4. Re: foreach

ryanj said...

I think euphoria 4.0 should have a foreach block.

So do I but there are a few syntax issues to work out with that first, so I'd rather wait until after 4.0.

I think that the idea with 4.0 is that this is were we would introduce stuff that has the potential to break existing code, so that we don't repeat that particular pain in subsequent releases. A foreach would not break existing code so it can wait a bit so we can get it right the first time.

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

5. Re: foreach

DerekParnell said...
ryanj said...

I think euphoria 4.0 should have a foreach block.

So do I but there are a few syntax issues to work out with that first, so I'd rather wait until after 4.0.

I think that the idea with 4.0 is that this is were we would introduce stuff that has the potential to break existing code, so that we don't repeat that particular pain in subsequent releases. A foreach would not break existing code so it can wait a bit so we can get it right the first time.

While we are talking about foreach, maybe we should just hash it out? I am not sure of syntax issues, the foreach given by ryan is pretty standard?

Jeremy

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

6. Re: foreach

SDPringle said...

Why don't you guys release 4.0 with out adding features then add all these features in 4.1. Let the public pound on what you have finished so far.

Shawn Pringle

I do want to make mention that 4.0 has been in development now for 3 months. 3 months is a very small amount of time for a major release. The dev team has been speeding to get as much as we have gotten done in so little time. With any other language after the 3 month mark you would begin to hear rumors of what is or might be available. You would still have another 6 months before any type of alpha release.

I think the dev team has been feeling undue pressure to release for an unknown reason to me.

Jeremy

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

7. Re: foreach

jeremy said...
SDPringle said...

Why don't you guys release 4.0 with out adding features then add all these features in 4.1. Let the public pound on what you have finished so far.

Shawn Pringle

I do want to make mention that 4.0 has been in development now for 3 months. 3 months is a very small amount of time for a major release. The dev team has been speeding to get as much as we have gotten done in so little time. With any other language after the 3 month mark you would begin to hear rumors of what is or might be available. You would still have another 6 months before any type of alpha release.

I think the dev team has been feeling undue pressure to release for an unknown reason to me.

Jeremy

Jeremy is correct in this. I know that Ruby started development back around this time last year on 1.9.0, and didn't make an official release till December of 2007. And it still isn't at an official release. Python hit 3.0 alpha around August 2007, and they are just finally reaching the Beta phase.

While you may be anxious, what these guys have done, has been an utter miracle to bring the Interpreter as far as they have. And there's still a lot of work to be done, if you want to believe it or not. Work on the Interpreter to get everything correct, is strongly needed, especially to bring Euphoria up to compete with other languages, as far as Keyword features that are available in the language.

So sit back, relax, and enjoy the ride. If your so anxious, see about checking out the eubins (http://jeremy.cowgar.com/eubins/) and use SVN to check out the code. That is what I've been doing, and I'm perfectly happy with it, cause it gives me a chance to test for bugs, and let the others know what I find, so that they can work on it, and get it out there faster.

L8ers,

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

8. Re: foreach

jeremy said...

While we are talking about foreach, maybe we should just hash it out? I am not sure of syntax issues, the foreach given by ryan is pretty standard?

A development forum would nice at this point smile

One issue is whether the loop variable can be assigned to. In the current for loop, one cannot assign to the loop variable, but that restriction might not be appropriate in a foreach.

foreach x in s do 
    if x > n then 
       x /= 2 
    end if 
end for 

ought to be equivalent to

for x = 1 to length(s) do 
    if s[x] > n then 
       s[x] /= 2 
    end if 
end for 

Another issue is whether we can also get the current index value inside the loop.

foreach x[i] in s do 
    if i > 1 then 
      if x > s[i-1] then 
       x /= 2 
      end if 
    end if 
end for 

Yet another issue is whether we can do parallel processing on a set of sequences.

foreach x in s, y in t do 
  if x > y then 
     x = y 
  end if 
end for 

Yet another issue is whether we can process the sequence in reverse order.

foreach x in reversed s do 
  if find(x, " \t\r\n") = 0 then 
    exit 
  end if 
  x = ' ' 
end for 

Yet another issue is what happens when the length of the sequence changes within the loop?

foreach x in s do 
  if x > 1 then 
     s = func(s) 
  end if 
end for 

And I'm sure there are still a few other corner cases worthy of consideration.

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

9. Re: foreach

DerekParnell said...
jeremy said...

While we are talking about foreach, maybe we should just hash it out? I am not sure of syntax issues, the foreach given by ryan is pretty standard?

A development forum would nice at this point smile

I wouldn't call most of the below "issues", but obviously expected stuff. This is why I was confused by the mention of syntax issues.

[/quote]

DerekParnell said...

One issue is whether the loop variable can be assigned to. In the current for loop, one cannot assign to the loop variable, but that restriction might not be appropriate in a foreach.

foreach x in s do 
    if x > n then 
       x /= 2 
    end if 
end for 

ought to be equivalent to

for x = 1 to length(s) do 
    if s[x] > n then 
       s[x] /= 2 
    end if 
end for 

Since x is not an index variable, it doesn't need to be read only. Why mixing things up?

DerekParnell said...

Another issue is whether we can also get the current index value inside the loop.

foreach x[i] in s do 
    if i > 1 then 
      if x > s[i-1] then 
       x /= 2 
      end if 
    end if 
end for 

I think I'd find

foreach x in s index i do 

clearer, but wouldn't mind. The index clause woould be optional, and the foreach loop index would be read only.

DerekParnell said...

Yet another issue is whether we can do parallel processing on a set of sequences.

foreach x in s, y in t do 
  if x > y then 
     x = y 
  end if 
end for 

I would say yes, but what happens when s and t have different lengths? I would quit whenever any parallelly processed sequence is exhausted. Also, the extra comma is not usual in Eu, can be removed.

DerekParnell said...

Yet another issue is whether we can process the sequence in reverse order.

foreach x in reversed s do 
  if find(x, " \t\r\n") = 0 then 
    exit 
  end if 
  x = ' ' 
end for 

Why not?

DerekParnell said...

Yet another issue is what happens when the length of the sequence changes within the loop?

foreach x in s do 
  if x > 1 then 
     s = func(s) 
  end if 
end for 

This is the only item I'd consider an issue.

My understanding would be this: foreach dumbly traverses the sequence, one element after the previous/next, and quits when no more is found. This behaviour is, I think, the only one we can implement efficiently, and it may be the desired thing in some cases. It won't be always so, but then why not use a while loop? I assume these will be uncommon enough cases.

Dynamic s-es will be handled much more efficiently than having to test always for valid indexes - the interpreter does it anyway, so that's duplicated code.

DerekParnell said...

And I'm sure there are still a few other corner cases worthy of consideration.

Even though I'd definitel use foreach it it was there, it can wait past 4.0 alpha, as it does not modify current code. Except for variables/routines currently named "foreach", of course.

Actually, there is another issue which could be raised, and which is common to for loops: should the scope for the index variable be extended? And should the object variable in the foreach construct be scoped inside the foreach loop proper? But this is a connected issue for another thread.

CChris

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

10. Re: foreach

I like the ability to modify the variable:

s = {1,2,3} 
 
foreach x in s do 
    x *= 2 
end foreach 
 
-- s is now {2, 4, 6} 

I think a simple foreach added to 4.0 would be a good thing. We can add in parameters in 4.1 such as reversed and multiple item iteration. The same with the above variable modification. As for the changing list size, I would make it act like a for, i.e. from x to y, thus foreach is equivilent to:

s = {1, 2, 3} 
foreach x in s do 
    ? x 
end foreach 
 
-- Same as: 
 
for i = 1 to length(s) do 
    x = s[i] 
    ? x 
end for 

To add that would be pretty simple, effective for 90% of all uses and does not mean we cannot add on the other fancies in 4.1, yet would be easy to implement, would reseve the keyword in 4.0, add greater functionality to Euphoria brining it closer to syntax capabilities of our competitors and at what cost? I do not see any except a bit of time to implement.

Jeremy

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

11. Re: foreach

What about the ability to edit the list itself?

What happens when you do something like: s = repeat(0,10) for i = 1 to length(s) do s = s[1..$-1] ? i end for

or

for i = 1 to length(s) do s = s[1..$-1] ? i end for

or

foreach value in s do ? value s = s[1..$-1] end foreach

I have had problems doing this kind of thing in the past. I cannot tell you what because it has been so long ago and I convert them to while loops when ever I want to increment the index manually or modify the list in anyway.

P.S.: Quote Reply seems broken now.

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

12. Re: foreach

CChris said...

I wouldn't call most of the below "issues"

OK, maybe issue was too strong a word, but all I meant was that there are some things that need to be considered, and decided upon, before we implement a foreach statement. If we prematurely implement it we may have to break code using the first implementation or curtail some important changes once we had more time to consider it.

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

13. Re: foreach

jeremy said...

I like the ability to modify the variable:

s = {1,2,3} 
 
foreach x in s do 
    x *= 2 
end foreach 
 
-- s is now {2, 4, 6} 

I think a simple foreach added to 4.0 would be a good thing. We can add in parameters in 4.1 such as reversed and multiple item iteration. The same with the above variable modification. As for the changing list size, I would make it act like a for, i.e. from x to y, thus foreach is equivilent to:

s = {1, 2, 3} 
foreach x in s do 
    ? x 
end foreach 
 
-- Same as: 
 
for i = 1 to length(s) do 
    x = s[i] 
    ? x 
end for 

To add that would be pretty simple, effective for 90% of all uses and does not mean we cannot add on the other fancies in 4.1, yet would be easy to implement, would reseve the keyword in 4.0, add greater functionality to Euphoria brining it closer to syntax capabilities of our competitors and at what cost? I do not see any except a bit of time to implement.

Jeremy

This view fits very well within my expectations of an intial version. I agree that additional features should only be added after the 4.0 release. Allowing everyone plenty of time to hash out their opinions on the positives and negatives of each nuance.

Another optional format is:

--parentheses are optional.  Just part of my coding style. 
-- I don't like this format 
foreach (list as item) do 
  ? item 
end foreach 
 
--I prefer this 
foreach (item in list) do 
  ? item 
end foreach 

Lucius L. Hilley III - Unkmar

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

14. Re: foreach

DerekParnell said...

OK, maybe issue was too strong a word, but all I meant was that there are some things that need to be considered, and decided upon, before we implement a foreach statement. If we prematurely implement it we may have to break code using the first implementation or curtail some important changes once we had more time to consider it.

Is their an issue with the most basic form of foreach and then adding features in 4.1? i.e.

s = {1,2,3} 
foreach x in s do 
    ? x 
end foreach 
 
-- being identical to: 
 
s = {1,2,3} 
for i = 1 to length(s) do 
    object x = s[i] 
    ? x 
end for 

In 4.1 we can safely add features such as updating x and have it reflected in the original list, adding a reversed parameter, etc... As said previously, the above would cover 90% of all uses of foreach.

Jeremy

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

15. Re: foreach

jeremy said...
DerekParnell said...

OK, maybe issue was too strong a word, but all I meant was that there are some things that need to be considered, and decided upon, before we implement a foreach statement. If we prematurely implement it we may have to break code using the first implementation or curtail some important changes once we had more time to consider it.

Is their an issue with the most basic form of foreach and then adding features in 4.1? i.e.

s = {1,2,3} 
foreach x in s do 
    ? x 
end foreach 
 
-- being identical to: 
 
s = {1,2,3} 
for i = 1 to length(s) do 
    object x = s[i] 
    ? x 
end for 

In 4.1 we can safely add features such as updating x and have it reflected in the original list, adding a reversed parameter, etc... As said previously, the above would cover 90% of all uses of foreach.

Jeremy

Or 4.0 beta.

It all depends of the time frame. More time, moreextra possible twists and tweaks.

CChris

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

16. Re: foreach

CChris said...

Or 4.0 beta.

It all depends of the time frame. More time, moreextra possible twists and tweaks.

Once we hit beta features need to be frozen and all development efforts should be focused to bugs. Alpha is find. Alpha means we are not yet frozen. Beta means we are frozen and bug fixing for preparation of 4.0 final.

Jeremy

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

17. Re: foreach

jeremy said...

In 4.1 we can safely add features such as updating x and have it reflected in the original list, adding a reversed parameter, etc... As said previously, the above would cover 90% of all uses of foreach.

It can only be safely done if, in 4.0, x is treated like a for loop variable currently is (i.e., no assignment possible).

And to lump something else in there, what about [optionally] specifying a type for the 'each'?

foreach integer c in my_string do 
    -- ... 
end foreach 

Matt

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

18. Re: foreach

mattlewis said...
jeremy said...

In 4.1 we can safely add features such as updating x and have it reflected in the original list, adding a reversed parameter, etc... As said previously, the above would cover 90% of all uses of foreach.

It can only be safely done if, in 4.0, x is treated like a for loop variable currently is (i.e., no assignment possible).

That sounds fine to me. Later, in 4.1 we can enhance these things and the 4.1 feature list can say "foreach variable now assignable!"

mattlewis said...

And to lump something else in there, what about [optionally] specifying a type for the 'each'?

foreach integer c in my_string do 
    -- ... 
end foreach 

This is for speed I guess? I'm all for giving the interpreter/translator the necessary information for optimizing.

Jeremy

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

19. Re: foreach

mattlewis said...

And to lump something else in there, what about [optionally] specifying a type for the 'each'?

foreach integer c in my_string do 
    -- ... 
end foreach 

What is the semantics behind that?

Does it mean that it only selects the integers contained in my_string and ignores non-integers? Or does it crash if a non-integer is found?

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

20. Re: foreach

DerekParnell said...
mattlewis said...

And to lump something else in there, what about [optionally] specifying a type for the 'each'?

foreach integer c in my_string do 
    -- ... 
end foreach 

What is the semantics behind that?

Does it mean that it only selects the integers contained in my_string and ignores non-integers? Or does it crash if a non-integer is found?

I'd mean for it to crash with a type check error on non-integers. So it would be (at least in the 'simple' version) equivalent to:

for i = 1 to length(my_string) do 
    integer c = my_string[i] 
    -- ... 
end for 

Using a known integer variable can dramatically speed up both interpreted and translated code. In the case of the translator, it would also be an additional hint about the type (even if it were atom or sequence) that could be used for other optimizations. I'd treat anything not specified as an object, of course.

Matt

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

21. Re: foreach

mattlewis said...
foreach integer c in my_string do 
    -- ... 
end foreach 

I'd mean for it to crash with a type check error on non-integers. So it would be (at least in the 'simple' version) equivalent to:

for i = 1 to length(my_string) do 
    integer c = my_string[i] 
    -- ... 
end for 

Ok. However keep in mind that I'll be proposing a 4.x modification to the for family of statements that would allow declaring the loop variable outside the actual for statement so it can have a wider scope.

Something like ...

integer c 
for defined c = 1 to 10 do 
    if func(c) then exit end if 
end for 
printf(1, "The value of 'c' is %d\n", c) 
new topic     » goto parent     » topic index » view message » categorize

22. Re: foreach

DerekParnell said...

Ok. However keep in mind that I'll be proposing a 4.x modification to the for family of statements that would allow declaring the loop variable outside the actual for statement so it can have a wider scope.

Something like ...

integer c 
for defined c = 1 to 10 do 
    if func(c) then exit end if 
end for 
printf(1, "The value of 'c' is %d\n", c) 

That makes sense to me. In fact, I'd say that rather than use the define keyword, simply require the type declaration if you want a new variable. Any 'naked' foreach variable would then have to be already declared. So really, it's probably no more difficult to follow this path for 4.0 than not.

The main issue to consider (which I think you had brought up, and then so did Jeremy):

jeremy said...

In 4.1 we can safely add features such as updating x and have it reflected in the original list, adding a reversed parameter, etc... As said previously, the above would cover 90% of all uses of foreach.

While I certainly see the utility in this, the more I think about it, it's not a very euphorian concept. Everywhere else in the language, we have assignment by value, and then here we have something operating by reference. So not something to be done lightly, I think...

Matt

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

23. Re: foreach

mattlewis said...
DerekParnell said...

Ok. However keep in mind that I'll be proposing a 4.x modification to the for family of statements that would allow declaring the loop variable outside the actual for statement so it can have a wider scope.

Something like ...

integer c 
for defined c = 1 to 10 do 
    if func(c) then exit end if 
end for 
printf(1, "The value of 'c' is %d\n", c) 

That makes sense to me. In fact, I'd say that rather than use the define keyword, simply require the type declaration if you want a new variable. Any 'naked' foreach variable would then have to be already declared. So really, it's probably no more difficult to follow this path for 4.0 than not.

The main issue to consider (which I think you had brought up, and then so did Jeremy):

jeremy said...

In 4.1 we can safely add features such as updating x and have it reflected in the original list, adding a reversed parameter, etc... As said previously, the above would cover 90% of all uses of foreach.

While I certainly see the utility in this, the more I think about it, it's not a very euphorian concept. Everywhere else in the language, we have assignment by value, and then here we have something operating by reference. So not something to be done lightly, I think...

Matt

I'm good with that as long as the following still crashes with an error.

integer varCT, varEbull 
for varCT = 1 to 10 do 
  for varEbull = 1 to 10 do 
    for varCT = 1 to 10 do -- Attempt to reuse active for loop variable 'varCT' 
    end for 
  end for 
end for 
--Just thought I would use something stranger than foo and bar. grin 
--Sound them out. 

Lucius L. Hilley - Unkmar

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

24. Re: foreach

[/quote] Matt said:

While I certainly see the utility in this, the more I think about it, it's not a very euphorian concept. Everywhere else in the language, we have assignment by value, and then here we have something operating by reference. So not something to be done lightly, I think...

Matt [/quote]

But doesn't that highlight the fact that what is natural for VB is not so natural for Euphoria. In VB, when using foreach to iterate through a collection of objects, you can access the object by index or name via object methods. Transposing this to Euphoria, you get a reference alias 'x' that gives you no access to its index and unnatural access to the real variable - even more unnatural if the real variable doesn't exist at all because it is the reverse of a real variable (or alternatively, a slice of one, like s[1..4] ).

Surely in Euphoria, you want to reference the elements by index, not by reference, something like this:-

foreach index in s do 
 
   if index < 3 then 
      s[index] += 1 
   else 
      s[index] += 2 
   end if 
 
end for 

This allows you to access both the sequence element directly and its index, whichever is you want. To me, the reference variable seems completely superfluous.

Cheers Peter

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

25. Re: foreach

Matt said:

While I certainly see the utility in this, the more I think about it, it's not a very euphorian concept. Everywhere else in the language, we have assignment by value, and then here we have something operating by reference. So not something to be done lightly, I think...

Matt [/quote]

But doesn't that highlight the fact that what is natural for VB is not so natural for Euphoria. In VB, when using foreach to iterate through a collection of objects, you can access the object by index or name via object methods. Transposing this to Euphoria, you get a reference alias 'x' that gives you no access to its index and unnatural access to the real variable - even more unnatural if the real variable doesn't exist at all because it is the reverse of a real variable (or alternatively, a slice of one, like s[1..4] ).

Surely in Euphoria, you want to reference the elements by index, not by reference, something like this:-

foreach index in s do 
 
   if index < 3 then 
      s[index] += 1 
   else 
      s[index] += 2 
   end if 
 
end for 

This allows you to access both the sequence element directly and its index, whichever is you want. To me, the reference variable seems completely superfluous.

Cheers Peter

[/quote]

Euphoria may some day become an adult language, and among other things will have some pass by ref mechanism. The sooner it gets into the language the better.

But in the meantime, I find your syntax very confusing, because a sequence is made of elements, not of indexes. I think I'd prefer then:

foreach s[index] do 
-- whatever 
end foreach --<-- when do we get rid of that redundancy? 

Whether index is read only is an issue - I think it shouldn't, but don't really care -. And s[index] would be available for either read or write.

CChris

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

26. Re: foreach

CChris said...
foreach s[index] do 
-- whatever 
end foreach --<-- when do we get rid of that redundancy? 

The redundancy is only in the eyes of the interpreter. It doesn't need it. But the end XXX serves another purpose. Source code is actually meant for people to read, not programs to read, and people are not as efficient at symbol processing, so we need a certain amount of redundancy to help us understand what we are reading.

Our spoken (and written) language has many examples of redundancy, but they are useful.

Euphoria source code is for us to read, so whatever it can do to help us in that is a good thing.

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

27. Re: foreach

DerekParnell said...
CChris said...
foreach s[index] do 
-- whatever 
end foreach --<-- when do we get rid of that redundancy? 

The redundancy is only in the eyes of the interpreter. It doesn't need it. But the end XXX serves another purpose. Source code is actually meant for people to read, not programs to read, and people are not as efficient at symbol processing, so we need a certain amount of redundancy to help us understand what we are reading.

It doesn't need it, but it uses it to make sure that it understands what we're trying to tell it. Much easier than C or Java, where you have to track back to figure out where you missed or added a curly bracket.

Matt

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

28. Re: foreach

Personally I'm in favor of keeping the end <block> style (end if, end foreach, end procedure etc). It makes the code more readable IMO, and since most end-statements (at least in my code) are end if:s and end for:s it's usually just two or three extra characters to type. Perhaps one could argue that end for would suffice as a terminator for foreach. Either would be fine with me.

Great job by you contributors BTW. I'm looking forward to the official 4.0 release.

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

29. Re: foreach

Pass by reference isn't a difficult problem for me to use in other languages but you know its rather EUPHORIA's character to show you pass by value semantics even though it would have been easier for the EUPHORIA's implementor to give you pass by reference semantics. I don't think because a language does away with a concept such as manual pass by ref that it should be called not yet adult language.

Exclusive pass by value gives you the debugging advantage to know that the only things that get modified in some scope are on the left side of an equals sign (and not some where in the scope of a called routine). Yet, it actually sends only the pointer instead of a memcpy as so many C programmers imagine when I tell them about it. So, it must decide to do the copy if you write to a passed value. You can call this copy-on-write-pass-by-value (COWPBV).

Does foreach break this concept though?

Assigning to a foreach variable is similiar to assigning to a sequence member indexed with a for loop.

I propose for the reversed syntax you could have reverse(s). Instead of actually doing a reverse function call the loop would transverse s in a reversed fashion. To the programmer it behaves the same as though you were reversing first and going through in a foward manner, yet it is faster. It is analogous to COWPBV it simplifies semantics for you, yet gives you a fast implementation.

Shawn Pringle

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

Search



Quick Links

User menu

Not signed in.

Misc Menu