D - One More Vote for 'foreach'
- Russ Lewis (22/22) Oct 02 2002 Now that I'm actually doing D programming, I must say that I think
- Mark Evans (58/58) Oct 02 2002 I vote in favor of all iteration features. STL offers foreach as an alg...
- Sean L. Palmer (90/112) Oct 03 2002 Definitely some kind of foreach is crucial.
- Evan McClanahan (15/34) Oct 03 2002 I'll second or third or n-th this suggestion. Sean's ideas about syntax...
- Walter (18/35) Oct 03 2002 I think you're right. I've been thinking about adding it in. I was think...
- Mark Evans (3/6) Oct 03 2002 Walter - sometimes the index itself is an encoded piece of information, ...
- Walter (25/30) Oct 04 2002 array/collection/whatever
- Chris (7/11) Oct 03 2002 Not a terribly experience programmer, but:
- Mike Wynn (42/53) Oct 04 2002 array/collection/whatever
- Walter (10/37) Oct 04 2002 array
- Mike Wynn (21/27) Oct 04 2002 then
- Walter (5/17) Oct 04 2002 I am wondering if it might be better to define .reverse as doing a copy
- Burton Radons (19/42) Oct 04 2002 Is the array completely, totally immutable inside? If not (and it
- Mark Evans (4/7) Oct 04 2002 Why not offer both to the programmer, .reverse.inplace and .reverse.copy...
- Walter (9/15) Oct 05 2002 or
- Mark Evans (4/10) Oct 05 2002 I agree. The reverse indexing suggested earlier, but discounted by oppo...
- Patrick Down (41/51) Oct 05 2002 I think allowing object and structs to support
- anderson (11/47) Oct 04 2002 Looks like a good way of doing this, I never though of using it with
Now that I'm actually doing D programming, I must say that I think "foreach" to be a nearly essential programming construct. D's arrays really change the way I go about things...now almost everything that isn't structured data ends up in an array or associative array. That means I iterate through my arrays A LOT. That's where foreach would be great. Sometimes, you want to also want to actually manipulate the array you're "foreach"ing through, though. It would be very nice to be able to extract the array index of your current "foreach" variable from it. My thought is to add a special property, returning uint, that only applies to variables defined by "foreach" constructs: 'foreach_index'. MyClass[] array; foreach(cur in array) { if(cur.stuff()) printf("Index %d matched 'stuff'.\n", cur.foreach_index); } -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Oct 02 2002
I vote in favor of all iteration features. STL offers foreach as an algorithm. Walter mentioned that he is brewing ideas for STL-like iterators. The proposed foreach corresponds to Mathematica's MapIndexed. One of the major reasons I use Mathematica in daily work is this sort of facility with data arrays. Mathematica's Map functions are one of its major benefits. (Some people like MATLAB / O-Matrix / Octave for similar reasons.) I don't say that D should incorporate these features as they exist in other languages, but only that array manipulation / iteration / indexing is a very critical capability. The more of it the better. It is not limited to numerical work. It applies everywhere. Arrays are universal data structures. Mathematica is expression-based so the Map functions all return a modified array expression. The language offers Scan to perform in-place array modifications. I won't even delve into Table, Range, Array, Part, Nest, Fold, Select, Cases, and other marvelous contraptions. Flatten and Partition are worthy of note. They effectively re-dimension arrays. All this power makes me feel homesick when I'm stuck with STL. Mathematica is interpreted and I know not whether a compiled language can approach such expressive power. I do know that these features let me walk on water in comparison to STL. I would fall in love with D if it had them. Mark =============================================== ?Map "Map[f, expr] ... applies f to each element on the first level in expr. Map[f, expr, levelspec] applies f to parts of expr specified by levelspec." ?MapAll "MapAll[f, expr] ... applies f to every subexpression in expr." ?MapAt "MapAt[f, expr, n] applies f to the element at position n in expr. If n is negative, the position is counted from the end. MapAt[f, expr, {i, j, ... }] applies f to the part of expr at position {i, j, ... }. MapAt[f, expr, {{i1, j1, ... }, {i2, j2, ... }, ... }] applies f to parts of expr at several positions." ?MapIndexed "MapIndexed[f, expr] applies f to the elements of expr, giving the part specification of each element as a second argument to f. MapIndexed[f, expr, levspec] applies f to all parts of expr on levels specified by levspec." ?MapThread "MapThread[f, {{a1, a2, ... }, {b1, b2, ... }, ... }] gives {f[a1, b1, ... ], f[a2, b2, ... ], ... }. MapThread[f, {expr1, expr2, ... }, n] applies f to the parts of the expri at level n." Level specifications The level in an expression corresponding to a non-negative integer n is defined to consist of parts specified by n indices. A negative level number -n represents all parts of an expression that have depth n. The depth of an expression, Depth[expr], is the maximum number of indices needed to specify any part, plus one. Levels do not include heads of expressions, except with the option setting Heads -> True. Level 0 is the whole expression. Level -1 contains all symbols and other objects that have no subparts. Functions with level specifications visit different subexpressions in an order that corresponds to depth-first traversal of the expression tree, with leaves visited before roots. The subexpressions visited have part specifications which occur in an order which is lexicographic, except that longer sequences appear before shorter ones. n = levels 1 through n Infinity = levels 1 through Infinity {n} = level n only {n1,n2} = levels n1 through n2
Oct 02 2002
Definitely some kind of foreach is crucial. Maybe a more pointer-like syntax. Or a more for-like syntax. What we want is the equivalent of for (uint i=0; i<a.size; ++i) expr(a[i]); where expr is any functional expression which can make any use of the supplied a[i] that it wants. a and b are arrays, i and j are index pointers. Clean that up and make the index automatic. Note that inside expr, i refers to a[i] for (i in a) i = sqrt(i-a); Clean. But take that up a notch to: for (i in a,b) a[i] = sqrt(b[i]); Tangled, back into explicit indexing. Something explicitly parallel can have no knowledge of any other unit of work done to any other part of the array. If it does you have filters or data moves. But those are usually highly sensitive to the order you traverse. However lots of stuff doesn't care what order you do it in. So there are several kinds of foreach, either unordered, forward, or backward We also want to be able to represent multidimensional foreach like so: for (i in a,c[*][]) for (j in b,c[][*]) So that's a pretty complicated problem, how to turn for into something that'll handle anything either forward or backward, any range or subslice, in and across any number of dimensions. That's going to be interesting to see. What would it look like? for (a[i], b[j], out c[i][j]) c[i][j] = a[i] * b[j]; I don't know why I threw the out in there. Maybe that makes sense. Maybe it doesn't. Anyway I think I'm getting off track. for (i,j) c[i][j] = a[i] * b[j]; That's what we want, I think. For loop variables with no type or range use the capacity of the array[s] they're used to index within the controlled expression. For these type of for loops, the control index variables must be used as array indices within the controlled expression. What about direction? An upward memory move: for (i++) a[i] = a[i-1]; // oops.. range access violation!!! Ok maybe a safer one: for (i : a.size-1 to 1) a[i] = a[i-1]; Syntax design is hard. I should probably start with the semantics. ;) But you get the idea. Something as powerful as for, just easier to use. For the cases where you wouldn't need to fill in all the blanks in a normal for statement, or would use a standard pattern such as for (uint i=0; i<a.size; ++i) expr(a[i]); or for (int i = a.size; --i >= 0; ) expr(a[i]); or STL's way: for (a[].type* p = a[0], e = a[a.size]; p < e; ++p) expr(*p); We want D's pattern for this to be MUCH more elegant. And a way to concisely write a multidimensional matrix operation would be nice. Vector and matrix operations. template(int x) { float inner(float[x] a, float[x] b) { float f = 0; for (i : 0 .. x-1) f += a[i] * b[i]; return f; } void outer(out float[x][x] c, float[x] a, float[x] b) { for (i,j) c[i][j] = a[i] * b[j]; } } Why do we have to use indexes at all in the expression why can't we just name the iterating dimensions? for (a[i],b[j],c[i][j]) c = a * b; I guess dimensions used more than once have to match in size. Being able to quickly construct an array that's got compatible dimensions with some other array might be a nice feature. Most out-of-bounds array accesses could be caught at compile time with a nice enough for construct, one that knew the sizes of everything used and could choose the ones with the smallest constraints on the resulting range. int a[2], b[3]; for (i) a[i] = b[i]; // should this be an error, or should it use a's smaller range? Maybe one of those syntactic experiments will gel with somebody. ;) Sean "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3D9BC26F.C26DBE8E deming-os.org...Now that I'm actually doing D programming, I must say that I think "foreach" to be a nearly essential programming construct. D's arrays really change the way I go about things...now almost everything that isn't structured data ends up in an array or associative array. That means I iterate through my arrays A LOT. That's where foreach would be great. Sometimes, you want to also want to actually manipulate the array you're "foreach"ing through, though. It would be very nice to be able to extract the array index of your current "foreach" variable from it. My thought is to add a special property, returning uint, that only applies to variables defined by "foreach" constructs: 'foreach_index'. MyClass[] array; foreach(cur in array) { if(cur.stuff()) printf("Index %d matched 'stuff'.\n", cur.foreach_index); } -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Oct 03 2002
I'll second or third or n-th this suggestion. Sean's ideas about syntax are interesting, but I'm not sure that I would vote for any particular one. There needs to be something, and for what I would be using it for, a simple foreach that addressed directionality of access in some way would be sufficient. Hashes would be harder, especially when it comes to performance. I'm most comfortable with the perl idiom of pulling out a list of keys (with the option of sorting it in some arbitrary manner) and then iterating through that to get at the values of the hash, but I know that it's dog slow, so if that knid of thing even makes it into the language, I wouldn't want it to be the default, by any means. For the records, I'm a game developer, so I fall in the middle of the road in terms of the coding speed vs. performance debate, perhaps tipped a little towards performance. Evan Russ Lewis wrote:Now that I'm actually doing D programming, I must say that I think "foreach" to be a nearly essential programming construct. D's arrays really change the way I go about things...now almost everything that isn't structured data ends up in an array or associative array. That means I iterate through my arrays A LOT. That's where foreach would be great. Sometimes, you want to also want to actually manipulate the array you're "foreach"ing through, though. It would be very nice to be able to extract the array index of your current "foreach" variable from it. My thought is to add a special property, returning uint, that only applies to variables defined by "foreach" constructs: 'foreach_index'. MyClass[] array; foreach(cur in array) { if(cur.stuff()) printf("Index %d matched 'stuff'.\n", cur.foreach_index); }
Oct 03 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3D9BC26F.C26DBE8E deming-os.org...Now that I'm actually doing D programming, I must say that I think "foreach" to be a nearly essential programming construct. D's arrays really change the way I go about things...now almost everything that isn't structured data ends up in an array or associative array. That means I iterate through my arrays A LOT. That's where foreach would be great.I think you're right. I've been thinking about adding it in. I was thinking along the lines of: foo a[]; // foo is some type foo v; for (v in a) { .. do something with v .. } Initially, 'a' could be arrays only. Later, 'a' could be a class that supports an Iterator interface. If 'a' has an order, the values are returned in that order, otherwise the order is unspecified (regular arrays have an order, associative arrays do not). It would be illegal to add or remove objects from 'a' within the loop.Sometimes, you want to also want to actually manipulate the array you're "foreach"ing through, though. It would be very nice to be able to extract the array index of your current "foreach" variable from it. My thought is to add a special property, returning uint, that only applies to variables defined by "foreach" constructs: 'foreach_index'. MyClass[] array; foreach(cur in array) { if(cur.stuff()) printf("Index %d matched 'stuff'.\n", cur.foreach_index); }I think that if you're using foreach, you shouldn't be dependent on the order or on the particular lookup mechanism of the array/collection/whatever being looped on.
Oct 03 2002
I think that if you're using foreach, you shouldn't be dependent on the order or on the particular lookup mechanism of the array/collection/whatever being looped on.Walter - sometimes the index itself is an encoded piece of information, and has utility as such. I use such a trick in Mathematica and in C all the time. Mark
Oct 03 2002
"Mark Evans" <Mark_member pathlink.com> wrote in message news:aniroq$26ea$1 digitaldaemon.com...array/collection/whateverI think that if you're using foreach, you shouldn't be dependent on the order or on the particular lookup mechanism of theand hasbeing looped on.Walter - sometimes the index itself is an encoded piece of information,utility as such. I use such a trick in Mathematica and in C all the time.Yes, I agree, but I suggest that using a regular for loop would be more appropriate for that purpose. I have a good reason for saying that. Many people transform loops like: for (int i = 0; i < a.length; i++) v = a[i]; ... into: foo *pmax = &a[a.length]; for (foo *p = &a[0]; p < pmax; p++) v = *p; ... for runtime efficiency purposes. There is no index used (yes you can derive one from (p - &a[0])). Using the foreach instead: for (v in a) ... means that the compiler can select the optimal loop traversal algorithm based on the target machine. Requiring it to produce an index means that people will go back to the ugly pointer optimization loop. Note that the pointer optimization version loses all array bounds checking help. Note also that the foreach version *does not need to do* array bounds checking in the loop body!
Oct 04 2002
Walter wrote:I think that if you're using foreach, you shouldn't be dependent on the order or on the particular lookup mechanism of the array/collection/whatever being looped on.Not a terribly experience programmer, but: A lot of people seem to place significance on the ordering of the index of an associative array. My example is the common Perl code foreach $foo (sort keys %aHash ) { ... } But maybe Perl features aren't what people are looking for in D. Chris
Oct 03 2002
"Chris" <cl nopressedmeat.tinfoilhat.ca> wrote in message news:3D9D39D6.2040400 nopressedmeat.tinfoilhat.ca...Walter wrote:array/collection/whateverI think that if you're using foreach, you shouldn't be dependent on the order or on the particular lookup mechanism of theI think this example show exactly what is require/expected, foreach should iterate an array forward there is not need for an assoc array foreach my reason is simple, this covers both cases; those who don't care and those who do I would like to see 'foreach' used and not 'for' reused. foreach ( <var> in <array_expr> ) <block> to iterate backwards you an use foreach( item in array.reverse ) { ... } which I assume should be quite easy for the optimiser to detect and shortcut. for hashtables/assoc arrays by key foreach( item in hash.keys ) { ... } if your not bothered by order foreach( item in hash.keys.sort ) { ... } if you are bothered by order or by value foreach( item in hash.values) { ... } if your not bothered by order foreach( item in hash.values.sort ) { ... } if you are bothered by order again the optimiser should be able to detect some (if not all) of these conditions and rearrange them foreach( item in hash.keys ) { ... }can be reordered such in to the order most efficient order for the hashtable (this does not contradict my later statement about determanism because hash table key order IS ALWAYS non determanistic (unlike array item order)). if you want values in key order then you'll have the below code with `hash[item]` to get the required item. foreach( item in hash.keys.sort ) { hash[item] ... } if you are bothered by order I am not a fan of language features where the compiler has a chose on how to order things, that does not mean I disagree with instruction reordering within basic blocks, but that the result of code should be fully determanistic. as an example here is some C/C++/Java code a = 2; if ( (c<9) || ((a = b) > 8) ) { b = 3; } with old C compilers the value of a, if c was less than 9 was undefined, the || could be fully evaluated with C++ (i belive) and Java || much only evaluate the rhs IFF the lhs is false. Mike.being looped on.Not a terribly experience programmer, but: A lot of people seem to place significance on the ordering of the index of an associative array. My example is the common Perl code foreach $foo (sort keys %aHash ) { ... } But maybe Perl features aren't what people are looking for in D.
Oct 04 2002
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message news:anjvh8$aes$1 digitaldaemon.com...I think this example show exactly what is require/expected, foreach should iterate an array forward there is not need for an assocarrayforeach my reason is simple, this covers both cases; those who don't care andthosewho doI think you're right.I would like to see 'foreach' used and not 'for' reused. foreach ( <var> in <array_expr> ) <block>D already has too many keywords <g>.to iterate backwards you an use foreach( item in array.reverse ) { ... } which I assume should be quite easy for the optimiser to detect and shortcut.That's a great idea! The only flaw is that array.reverse reverses the array in place, which might not be what's intended.for hashtables/assoc arrays by key foreach( item in hash.keys ) { ... } if your not bothered by order foreach( item in hash.keys.sort ) { ... } if you are bothered by order or by value foreach( item in hash.values) { ... } if your not bothered by order foreach( item in hash.values.sort ) { ... } if you are bothered by order again the optimiser should be able to detect some (if not all) of these conditions and rearrange them foreach( item in hash.keys ) { ... }can be reordered such in to the order most efficient order for the hashtable (this does not contradict my later statement about determanism because hash table key order IS ALWAYS non determanistic (unlike array item order)).Great ideas!if you want values in key order then you'll have the below code with `hash[item]` to get the required item. foreach( item in hash.keys.sort ) { hash[item] ... } if you are botheredbyorder
Oct 04 2002
arrayto iterate backwards you an use foreach( item in array.reverse ) { ... } which I assume should be quite easy for the optimiser to detect and shortcut.That's a great idea! The only flaw is that array.reverse reverses thein place, which might not be what's intended.then for( item in array.dup.reverse ) { ... } // compiler will have to detect that the copy is not truely required or change the array semantics to be (Perl again) pass by value so array.reverse returns a new array and adding a new operator .= syntax object .= method( params ); equiv to object = object.method( params ); so Foo [] bar = getMyArray(); bar .= reverse; // instead of bar.reverse; other = bar.reverse; // instead of other = bar.dup.reverse; or other[] = bar[]; other.reverse; this could go as far as makeing arrays by default be passed by value 'in int[]' means pass-by-value 'inout int[]' means pass-by-ref 'out int[]' returns a new array I accept that predomantly only script languages have array default pass by value, and most compiled languages pass arrays by reference. and does effect perfromance if used too much.
Oct 04 2002
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message news:ankglo$sl5$1 digitaldaemon.com...I am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.arrayto iterate backwards you an use foreach( item in array.reverse ) { ... } which I assume should be quite easy for the optimiser to detect and shortcut.That's a great idea! The only flaw is that array.reverse reverses thein place, which might not be what's intended.then for( item in array.dup.reverse ) { ... } // compiler will have to detect that the copy is not truely required
Oct 04 2002
Walter wrote:"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message news:ankglo$sl5$1 digitaldaemon.com...Is the array completely, totally immutable inside? If not (and it shouldn't be), then the optimiser can't do anything no matter what. I don't think there's much advantages to playing games here - there should be iterator properties instead (and iterators should be structs, not classes, so that they can usually be inlined). Also, I think the iterated item should be an inout parameter, so that I can modify it, and that would also be faster. So it should be declared in the for: for (Type item in array.ireverse) item = sin (item); IMO this should keep the three-section form of for, which was a wise decision; otherwise things tend to break down rather horribly when the assumption that you don't need anything more complex is wrong (Python in particular is simply _awful_): each (int index; Type item in array; index ++) ... And of course, I think putting new semantics in for is a bad idea. Time for a new keyword.I am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.arrayto iterate backwards you an use foreach( item in array.reverse ) { ... } which I assume should be quite easy for the optimiser to detect and shortcut.That's a great idea! The only flaw is that array.reverse reverses thein place, which might not be what's intended.then for( item in array.dup.reverse ) { ... } // compiler will have to detect that the copy is not truely required
Oct 04 2002
Walter wrote:I am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.Why not offer both to the programmer, .reverse.inplace and .reverse.copy or something. Mark
Oct 04 2002
"Mark Evans" <Mark_member pathlink.com> wrote in message news:anlsvl$2997$1 digitaldaemon.com...Walter wrote:orI am wondering if it might be better to define .reverse as doing a copy rather than in-place. You're right in that a better D compiler could optimize the .reverse away entirely in a foreach.Why not offer both to the programmer, .reverse.inplace and .reverse.copysomething.Each permutation makes the language more complicated. The goal is instead of providing m*n features, only provide m+n features which, when combined, offer m*n capabilities. In other words, provide a small base set of orthogonal building blocks, each easy to understand, that can be combined to form complex tasks that have obvious meanings from the base set. This is why I'm a bit slow to adopt new features <g>.
Oct 05 2002
In article <ann6h0$1c57$1 digitaldaemon.com>, Walter says...I agree. The reverse indexing suggested earlier, but discounted by opponents as featuritis, would eliminate the need to reverse arrays inplace. MarkWhy not offer both to the programmer, .reverse.inplace and .reverse.copyEach permutation makes the language more complicated. The goal is instead of providing m*n features, only provide m+n features which, when combined, offer m*n capabilities.> This is why I'm a bit slow to adopt new features <g>.
Oct 05 2002
"Walter" <walter digitalmars.com> wrote in news:ann6h0$1c57$1 digitaldaemon.com:Each permutation makes the language more complicated. The goal is instead of providing m*n features, only provide m+n features which, when combined, offer m*n capabilities. In other words, provide a small base set of orthogonal building blocks, each easy to understand, that can be combined to form complex tasks that have obvious meanings from the base set. This is why I'm a bit slow to adopt new features <g>.I think allowing object and structs to support and iterator function like getNext would provide a versatile solution to a lot of these cases. // define iterator template template Iterators(T) { struct ReverseArr { T[] tArr; int curPos; bit getNext(out T t) { --curPos; if(curPos < 0) return false; t = tArr[curPos]; return true; } } ReverseArr reverse(T[] t) { ReverseArr r; r.curPos = t.length; r.tArr = t; return r; } } // use iterator template int[] a; Iterators(int) intIter; // calls getNext until it returns false for(item in intIter.reverse(a)) { }
Oct 05 2002
Looks like a good way of doing this, I never though of using it with associative arrays. Parhaps it could be multi-leveled... foo a[][]; foo z[]; foo v; for(v in z in a) ... "Walter" <walter digitalmars.com> wrote in message news:aniqq3$25km$1 digitaldaemon.com..."Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3D9BC26F.C26DBE8E deming-os.org...thinkingNow that I'm actually doing D programming, I must say that I think "foreach" to be a nearly essential programming construct. D's arrays really change the way I go about things...now almost everything that isn't structured data ends up in an array or associative array. That means I iterate through my arrays A LOT. That's where foreach would be great.I think you're right. I've been thinking about adding it in. I wasalong the lines of: foo a[]; // foo is some type foo v; for (v in a) { .. do something with v .. } Initially, 'a' could be arrays only. Later, 'a' could be a class that supports an Iterator interface. If 'a' has an order, the values arereturnedin that order, otherwise the order is unspecified (regular arrays have an order, associative arrays do not). It would be illegal to add or remove objects from 'a' within the loop.array/collection/whateverSometimes, you want to also want to actually manipulate the array you're "foreach"ing through, though. It would be very nice to be able to extract the array index of your current "foreach" variable from it. My thought is to add a special property, returning uint, that only applies to variables defined by "foreach" constructs: 'foreach_index'. MyClass[] array; foreach(cur in array) { if(cur.stuff()) printf("Index %d matched 'stuff'.\n", cur.foreach_index); }I think that if you're using foreach, you shouldn't be dependent on the order or on the particular lookup mechanism of thebeing looped on.
Oct 04 2002
Looks like a good way of doing this, I never though of using it with associative arrays. Parhaps it could be multi-leveled... foo a[][]; foo z[]; foo v; for(v in z in a) ...You can write it in this way: for(z in a) for(v in z) ... Or maybe: for(v in z) ... should be valid since the compiler knows the types of the variables. _________________________________________ Sometimes this type of loop is used too: char[] a, b; assert(a.length == b.length); for(int i; i < a.length; i++) {a[i] = b[i];} Maybe it would be nice to have a sintax like this: char[] a, b; char i, j; for(i in a; j in b) {i = j;} But then three iterations will cause confusion with the for(;;) sintax! The solution would be a new keyword ('foreach' or simply 'each'). _____________________________________ Only another observation. Think about the in keyword used to check if a value is in an array (as suggested by Russell Lewis). It makes the for(a in b) sintax ambiguous in the following example: for(a in b ? c : d in e) {} Do you understand what is intended? =) for(((a in b) ? c : d) in e) {} To avoid these ambiguity problems will can have a more intelligent use of parenthesis. See below. char a, b[], c, d; for(a) in(b) {} /* as you can see, the in keyword is NOT between parenthesis */ for(c in b ? a : d) in(b) {} Another solution is to use ':' instead if 'in'. foreach(a : b) {} However I agree that the "for each" construct is simply too useful to be not implemented.
Oct 07 2002
"Dario" <supdar yahoo.com> wrote in message news:ans0fk$o2a$1 digitaldaemon.com...Only another observation. Think about the in keyword used to check if a value is in an array (as suggested by Russell Lewis). It makes the for(ainb) sintax ambiguous in the following example: for(a in b ? c : d in e) {} Do you understand what is intended? =) for(((a in b) ? c : d) in e) {} To avoid these ambiguity problems will can have a more intelligent use of parenthesis. See below. char a, b[], c, d; for(a) in(b) {} /* as you can see, the in keyword is NOT between parenthesis */ for(c in b ? a : d) in(b) {} Another solution is to use ':' instead if 'in'. foreach(a : b) {}Yeah, I know the in syntax is ambiguous, I need to come up with something that will work. Your ideas are good.
Oct 07 2002