1. Argument for "foreach"
- Posted by D. Newhall <derek_newhall at yahoo.com> Feb 09, 2006
- 454 views
I know I have mentioned this before but I trully believe that a foreach statement would benefit Euphoria greatly and I have proof this time! Many, many times we Euphorians have to type:
object element for i=1 to length(list) do element = list[i] -- Code goes here end for
to loop through every element of a list or string to perform checking on it. In doing this we need to declare an extra variable (element) for the data we wish to check, in the loop create the looping variable, and assign the new indexed value to the other variable (yes, we can do list[i] but it's inefficient and looks horrid in nested loops ex. element[i][j][k]). Instead of this a foreach statement would greatly simplify things. We could instead write: foreach element in list do -- Code goes here end for That's 33 keystrokes (+2 for shifts on '(' and ')') less than before and the scope is more explicit (element is only available for use in the loop). This may not seem like a lot but if you write this code frequently it could make a big difference. For this element should be read-only just like variables used with for and element should be an object. Ideally, the interpreter would optimize this to simply iterate through every element of the sequence but it could be added quickly as a syntactic substitute for what we do already. One issue would be how to treat atoms when used as list; should it error or set element to that one value? I went through some of my programs and checked to see exactly how many of my for loops would be replaced with foreach if it was added. Here's the results from the programs I last worked on (taken from my ConTEXT history): lispkit.ex - Simple LISP interpreter FOREACH 3 FOR 1 rmcomments.ex - Removes comments from file FOREACH 2 FOR 1 diceroller.ex - A dice program for my friend's RPG group FOREACH 0 FOR 1 EuDoc.ex - The "driver" for EuDoc FOREACH 3 FOR 0 EuDoc.e - The main data-mangling routines for EuDoc FOREACH 9 FOR 1 (Note: EuDoc.e might be off. I think I accidently counted 1 or 2 loops that modify "element" which foreach would not allow) (Note: Two of the "for"s are technically inaccurate since they looped backwards and foreach element in reverse(list) would have taken care of it in hindsight) As you can see for big files like EuDoc.e that's 297 characters less that I wouldn't have to type. I should also note that In the grand scheme of things it might not seem like that much but one could make the same argument with list[$] versus list[length(list)] (which was an excellent idea BTW). Of course there are good reasons not to implement foreach such as it makes the language more complex, people will forget that element is read-only, it's not worth the extra statement, it's not really that much work now, etc. The previous discussion on "foreach" is here: http://www.listfilter.com/cgi-bin/esearch.exu?thread=1&fromMonth=6&fromYear=A&toMonth=8&toYear=A&keywords=%222.6+feature+request:+foreach%22 The Euphoria Standard Library project : http://esl.sourceforge.net/ The Euphoria Standard Library mailing list : https://lists.sourceforge.net/lists/listinfo/esl-discussion
2. Re: Argument for "foreach"
- Posted by Jason Gade <jaygade at yahoo.com> Feb 09, 2006
- 462 views
I was going to say that for a language that has a flexible sequence as its main data type that foreach would make a lot of sense, but I already said it in the thread that you posted. You could always write a foreach routine that takes a routine ID:
procedure foreach(object list, integer rid) -- define your called procedure so that it takes an object and an index for i = 1 to length(list) do call_proc(rid, {list[i], i}) end for end procedure -- foreach
You could also define a function called map that does the same thing but calls a function and returns a modified sequence instead:
function map(object list, integer rid) sequence out out = list -- allocate enough memory to start -- define your called function so that it takes an object and an index for i = 1 to length(list) do out[i] = call_func(rid, {list[i], i}) end for return out end function -- map
There are other sequence operations that I would like to see built in, like sum(), but what can you do? -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel j.
3. Re: Argument for "foreach"
- Posted by Kenneth Rhodes <ken_rhodes30436 at yahoo.com> Feb 09, 2006
- 458 views
Jason Gade wrote: > > I was going to say that for a language that has a flexible sequence as its > main > data type that foreach would make a lot of sense, but I already said it in the > thread that you posted. > > You could always write a foreach routine that takes a routine ID: > }}} <eucode> > procedure foreach(object list, integer rid) > -- define your called procedure so that it takes an object and an index > for i = 1 to length(list) do > call_proc(rid, {list[i], i}) > end for > end procedure -- foreach > </eucode> {{{ > You could also define a function called map that does the same thing but calls > a function and returns a modified sequence instead: > }}} <eucode> > function map(object list, integer rid) > sequence out > > out = list -- allocate enough memory to start > > -- define your called function so that it takes an object and an index > for i = 1 to length(list) do > out[i] = call_func(rid, {list[i], i}) > end for > > return out > end function -- map > </eucode> {{{ > There are other sequence operations that I would like to see built in, like > sum(), but what can you do? > I've been trying to understand benefit of translating/compiling routines into *.dll or *.so files. Wouldn't these types of routines benefit most from being tanslated/compiled and wrapped? And once wrapped, could they be called as easily as the euphoria source code above? I have been studying the examples in Euphoria documentation and demo files - all seems very obscure to me, hence I am eager to see Jeremy's wrapper hit the contribution page. Ken Rhodes 100% MicroSoft Free SuSE Linux 10.0 No AddWare, SpyWare, or Viruses! Life is Good
4. Re: Argument for "foreach"
- Posted by Jason Gade <jaygade at yahoo.com> Feb 09, 2006
- 449 views
Kenneth Rhodes wrote: > > Jason Gade wrote: > > > > I was going to say that for a language that has a flexible sequence as its > > main > > data type that foreach would make a lot of sense, but I already said it in > > the > > thread that you posted. > > > > You could always write a foreach routine that takes a routine ID: > > }}} <eucode> > > procedure foreach(object list, integer rid) > > -- define your called procedure so that it takes an object and an index > > for i = 1 to length(list) do > > call_proc(rid, {list[i], i}) > > end for > > end procedure -- foreach > > </eucode> {{{ > > You could also define a function called map that does the same thing but > > calls > > a function and returns a modified sequence instead: > > }}} <eucode> > > function map(object list, integer rid) > > sequence out > > > > out = list -- allocate enough memory to start > > > > -- define your called function so that it takes an object and an index > > for i = 1 to length(list) do > > out[i] = call_func(rid, {list[i], i}) > > end for > > > > return out > > end function -- map > > </eucode> {{{ > > There are other sequence operations that I would like to see built in, like > > sum(), but what can you do? > > > > I've been trying to understand benefit of translating/compiling routines > into *.dll or *.so files. Wouldn't these types of routines benefit most > from being tanslated/compiled and wrapped? And once wrapped, could they > be called as easily as the euphoria source code above? > I have been > studying the examples in Euphoria documentation and demo files - all > seems very obscure to me, hence I am eager to see Jeremy's wrapper hit > the contribution page. I don't know as I've never done it. I don't think that it would gain you much for such short routines as above. I imagine that routines with > 10-15 lines and which are heavily used by your program would benefit the most. Plus, like Rob replied to my optimization post, you would lose some troubleshooting information from ex.err. Remember to debug and profile before you try to optimize! -- "Any programming problem can be solved by adding a level of indirection." --anonymous "Any performance problem can be solved by removing a level of indirection." --M. Haertel j.