Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 05, 2004 foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Hi Walter, I finally had the time to read your (and Matt's) article in DDJ on D's foreach construct. I think it's well-written. I have three suggestions for even more improvement (in my opinion) of the construct: 1) The syntax Current syntax is "foreach( uint v; aa ) { ... }" (from the article), ie first element is a variable declaration and the second is a variable denoting some collection. My remark may be an itty bitty detail, but I don't like the ';' in this. Normally ';' is used as statement separator, and in C the for ( x ; y ; z ) syntax closely related to the notion that x,y,z are statements that are put in a particular order (it's syntactic sugar for " x ; while (y) { .... z }"). "uint v" may be a statement (variable declaration), but 'aa' isn't, at least not in itself. The semantics are that 'v' comes from the elements in 'aa', and I think this should be reflected in the syntax. Possible alternatives: foreach( uint v from aa ) { ... } foreach( uint v in aa ) { ... } foreach( uint v <- aa ) { ... } foreach( uint v : aa ) { ... } "from" and "in" would mean additional keywords, which I don't like too much. My personal preference is the last one using ':' 2) The type declaration The type declaration in the foreach syntax is redundant, since it should match the type of elements in the collection. I think the compiler should be able to determine this somehow (this would require new syntax for collection classes, similar to templates). Rather similar to the new type safe collections in Java, which I like too. 3) The 'opApply' convention Why not use 'foreach' as the method name? This reflects the context in which the method is invoked, and also allows syntax such as "aa.foreach( f )" which IMO is slightly more readable than "aa.opApply( f )" JvB |
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeroen van Bemmel | >1) The syntax >Current syntax is "foreach( uint v; aa ) { ... }" (from the article), ie >first element is a variable declaration and the second is a variable >denoting some collection. My remark may be an itty bitty detail, but I don't >like the ';' in this. Normally ';' is used as statement separator, and in C >the for ( x ; y ; z ) syntax closely related to the notion that x,y,z are >statements that are put in a particular order (it's syntactic sugar for " x >; while (y) { .... z }"). "uint v" may be a statement (variable >declaration), but 'aa' isn't, at least not in itself. The semantics are that >'v' comes from the elements in 'aa', and I think this should be reflected in >the syntax. > >Possible alternatives: >foreach( uint v from aa ) { ... } >foreach( uint v in aa ) { ... } >foreach( uint v <- aa ) { ... } >foreach( uint v : aa ) { ... } > >"from" and "in" would mean additional keywords, which I don't like too much. My personal preference is the last one using ':' in is a keyword. And in 'for ( x ; y ; z )' y is a statement? Nope. y is just like aa in your foreach example. >2) The type declaration >The type declaration in the foreach syntax is redundant, since it should >match the type of elements in the collection. You forgot to explain, why it has to match. IMHO it doesn't have to. |
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeroen van Bemmel | Jeroen van Bemmel wrote: >Hi Walter, > >I finally had the time to read your (and Matt's) article in DDJ on D's >foreach construct. I think it's well-written. I have three suggestions for >even more improvement (in my opinion) of the construct: > > >2) The type declaration >The type declaration in the foreach syntax is redundant, since it should >match the type of elements in the collection. I think the compiler should be >able to determine this somehow (this would require new syntax for collection >classes, similar to templates). Rather similar to the new type safe >collections in Java, which I like too. > > I like this suggestion (I suggested it before). The old syntax could be kept for situations where you need to spell out which opApply to use, but in other cases it's redundant. Almost everytime I use a foreach, I find myself having to look up the type. foreach (n; array) {} Would be a lot easier to remember. One thing I like about D is that in may cases it has removed the redundancies that exist in C++. The think I don't like is that D has brought in new redundancies by not having automatic type deduction. If automatic type deduction is so difficult to implement right, why can't we have a reduced-automatic type deduction. ie template Max(T) { T Max(T a, T b) { } } Instead of: Max!(int).Max(a,b); use: Max!!(a,b); would be equivalent to: Max!(typeof(a))(a,b); Note that there would two types, then the order of the would be important. ie template Foo(T, C) { void Foo(T a, C b) { } } Foo!!(a, b); Equivalent to: Foo!(typeof(a), typeof(b)).Foo(a,b); Anything difficult and the compiler could spit at the coder asking for an explicit definition. -- -Anderson: http://badmama.com.au/~anderson/ |
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to J Anderson | >One thing I like about D is that in may cases it has removed the redundancies that exist in C++. The think I don't like is that D has brought in new redundancies by not having automatic type deduction. If automatic type deduction is so difficult to implement right, why can't we have a reduced-automatic type deduction. ie
>
>template Max(T)
>{
> T Max(T a, T b) { }
>}
>
>Instead of:
>Max!(int).Max(a,b);
>
>use:
>Max!!(a,b);
>
>would be equivalent to:
>Max!(typeof(a))(a,b);
>
>Note that there would two types, then the order of the would be important. ie
>
>template Foo(T, C)
>{
> void Foo(T a, C b) { }
>}
>
>Foo!!(a, b);
>
>Equivalent to:
>Foo!(typeof(a), typeof(b)).Foo(a,b);
>
>Anything difficult and the compiler could spit at the coder asking for an explicit definition.
>
Have you read my proposal about adding "let"?
|
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthias Becker | Matthias Becker wrote: >>One thing I like about D is that in may cases it has removed the redundancies that exist in C++. The think I don't like is that D has brought in new redundancies by not having automatic type deduction. If automatic type deduction is so difficult to implement right, why can't we have a reduced-automatic type deduction. ie >> >>template Max(T) >>{ >> T Max(T a, T b) { } >>} >> >>Instead of: >>Max!(int).Max(a,b); >> >>use: >>Max!!(a,b); >> >>would be equivalent to: >>Max!(typeof(a))(a,b); >> >>Note that there would two types, then the order of the would be important. ie >> >>template Foo(T, C) >>{ >> void Foo(T a, C b) { } >>} >> >>Foo!!(a, b); >> >>Equivalent to: >>Foo!(typeof(a), typeof(b)).Foo(a,b); >> >>Anything difficult and the compiler could spit at the coder asking for an explicit definition. >> >> >> > >Have you read my proposal about adding "let"? > > > Yeah, but it was a while back (and I couldn't find the original suggestion). I'm not sure if I liked it, didn't like it or didn't understand your proposal. -- -Anderson: http://badmama.com.au/~anderson/ |
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jeroen van Bemmel | "Jeroen van Bemmel" <someone@somewhere.com> wrote in message news:c2989f$6a6$1@digitaldaemon.com... | Hi Walter, | | I finally had the time to read your (and Matt's) article in DDJ on D's | foreach construct. I think it's well-written. I have three suggestions for | even more improvement (in my opinion) of the construct: | | 1) The syntax | Current syntax is "foreach( uint v; aa ) { ... }" (from the article), ie | first element is a variable declaration and the second is a variable | denoting some collection. My remark may be an itty bitty detail, but I don't | like the ';' in this. Normally ';' is used as statement separator, and in C | the for ( x ; y ; z ) syntax closely related to the notion that x,y,z are | statements that are put in a particular order (it's syntactic sugar for " x | ; while (y) { .... z }"). "uint v" may be a statement (variable | declaration), but 'aa' isn't, at least not in itself. The semantics are that | 'v' comes from the elements in 'aa', and I think this should be reflected in | the syntax. | | Possible alternatives: | foreach( uint v from aa ) { ... } | foreach( uint v in aa ) { ... } | foreach( uint v <- aa ) { ... } | foreach( uint v : aa ) { ... } | | "from" and "in" would mean additional keywords, which I don't like too much. | My personal preference is the last one using ':' The "foreach" syntax should parallel the "for" syntax: foreach(declaration-list ; expression) body for(declaration-list ; expression ; expression) body The declaration-list is a comma separated list of looping variables. Seems like a pretty natural extension of the "for" syntax. | 2) The type declaration | The type declaration in the foreach syntax is redundant, since it should | match the type of elements in the collection. I think the compiler should be | able to determine this somehow (this would require new syntax for collection | classes, similar to templates). Rather similar to the new type safe | collections in Java, which I like too. Might be nice but if it is added here it would seem odd that foreach is the only place declaration types get inferred. What about void foo() { x=1; // c'mon, D, you know what type I want ;-) } And someone else mentioned template instantiation. There's a can of worms in them thar hills. | 3) The 'opApply' convention | Why not use 'foreach' as the method name? This reflects the context in which | the method is invoked, and also allows syntax such as "aa.foreach( f )" | which IMO is slightly more readable than "aa.opApply( f )" That sounds very reasonable to me. Another problem I have with opApply is that since overloading is fairly weak in D that an opApply meant for foreach could interfere with an opApply meant for ... opApply and result in casts when they shouldn't be needed. One problem with "foreach" is that it is a keyword and so maybe something like "foreachApply" would be better. | | JvB | | |
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | >| Hi Walter, >| >| I finally had the time to read your (and Matt's) article in DDJ on D's >| foreach construct. I think it's well-written. I have three suggestions for >| even more improvement (in my opinion) of the construct: >| >| 1) The syntax >| Current syntax is "foreach( uint v; aa ) { ... }" (from the article), ie >| first element is a variable declaration and the second is a variable >| denoting some collection. My remark may be an itty bitty detail, but I don't >| like the ';' in this. Normally ';' is used as statement separator, and in C >| the for ( x ; y ; z ) syntax closely related to the notion that x,y,z are >| statements that are put in a particular order (it's syntactic sugar for " x >| ; while (y) { .... z }"). "uint v" may be a statement (variable >| declaration), but 'aa' isn't, at least not in itself. The semantics are that >| 'v' comes from the elements in 'aa', and I think this should be reflected in >| the syntax. >| >| Possible alternatives: >| foreach( uint v from aa ) { ... } >| foreach( uint v in aa ) { ... } >| foreach( uint v <- aa ) { ... } >| foreach( uint v : aa ) { ... } >| >| "from" and "in" would mean additional keywords, which I don't like too much. >| My personal preference is the last one using ':' > >The "foreach" syntax should parallel the "for" syntax: > foreach(declaration-list ; expression) body > for(declaration-list ; expression ; expression) body >The declaration-list is a comma separated list of looping variables. Seems like a pretty natural extension of the "for" syntax. Why foreach at all? for (declaration-list; expression) body // like foreach before for(declaration-list ; expression ; expression) body // stays as is >| 2) The type declaration >| The type declaration in the foreach syntax is redundant, since it should >| match the type of elements in the collection. I think the compiler should be >| able to determine this somehow (this would require new syntax for collection >| classes, similar to templates). Rather similar to the new type safe >| collections in Java, which I like too. > >Might be nice but if it is added here it would seem odd that foreach is >the only place declaration types get inferred. What about >void foo() >{ > x=1; // c'mon, D, you know what type I want ;-) >} >And someone else mentioned template instantiation. There's a can of worms >in them thar hills. > That's why I proposed let a while ago. void foo() { let x=1; } Well, it was intended to be used in some template-code, as you otherwise will result in code like typeof(a*b) c = a*b; which is pretty redundant. But I like it in a VERY common case: let x = new SomeClassName(); instead of SomeClassName x = new SomeClassName(); |
March 05, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthias Becker | Matthias Becker wrote: >Why foreach at all? > >for (declaration-list; expression) body // like foreach before >for(declaration-list ; expression ; expression) body // stays as is > > Having foreach instead of for, prevents syntax errors. -- -Anderson: http://badmama.com.au/~anderson/ |
March 08, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | > void foo()
> {
> x=1; // c'mon, D, you know what type I want ;-)
> }
*response from D* "No I don't... I mean sure, you want an integral, but a s a byte, ubyte, short, ushort, int, uint, long, ulong, cent, ucent, or what?"
Hmm.. no, I think I'd just assume have to tell it. Its not like it takes long to type 'int'. As for the type being given for the foreach parameter, what if I have multiple types I can iterate with?
-C. Sauls
-Invironz
|
March 08, 2004 Re: foreach ( foreach <- D ) { change syntax } | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthias Becker | > >| Possible alternatives: > >| foreach( uint v from aa ) { ... } > >| foreach( uint v in aa ) { ... } > >| foreach( uint v <- aa ) { ... } > >| foreach( uint v : aa ) { ... } > >| > >| "from" and "in" would mean additional keywords, which I don't like too much. > >| My personal preference is the last one using ':' > > > >The "foreach" syntax should parallel the "for" syntax: > > foreach(declaration-list ; expression) body > > for(declaration-list ; expression ; expression) body > >The declaration-list is a comma separated list of looping variables. Seems > >like a pretty natural extension of the "for" syntax. But that's just my point: they are not completely parallel. 'declaration-list' can only be 1 variable in foreach, and 'expression' denotes neither a termination conditional expression nor the expression calculated for the next loop. The syntax should be restricted to (as it is currently implemented): foreach( <type-name> <variable> ; <expression> ) So all of the following are wrong (these could be test cases...): foreach( int a,b; as ) { ... } // syntax error foreach( int a; 1 ) { ... } // semantic error: '1' is not a collection type Now that I think about it, how about allowing "foreach( int a : 1..10 ) { ... }" // a..b denotes the sequence of integers from a to b, inclusive, as used in splicing > > Why foreach at all? > > for (declaration-list; expression) body // like foreach before > for(declaration-list ; expression ; expression) body // stays as is > I agree with J Anderson, it's not exactly the same so don't use the same syntax > > >| 2) The type declaration > >| The type declaration in the foreach syntax is redundant, since it should > >| match the type of elements in the collection. I think the compiler should be > >| able to determine this somehow (this would require new syntax for collection > >| classes, similar to templates). Rather similar to the new type safe | collections in Java, which I like too. > > > >Might be nice but if it is added here it would seem odd that foreach is the only place declaration types get inferred. What about Yes, I know there's lots of other places where types might be inferred. But since 'foreach' already pretends to be a syntactic simplification of a common construct, if anywhere it should be applied there > >void foo() > >{ > > x=1; // c'mon, D, you know what type I want ;-) > >} > >And someone else mentioned template instantiation. There's a can of worms > >in them thar hills. > > > > That's why I proposed let a while ago. > > void foo() > { > let x=1; > } > > Well, it was intended to be used in some template-code, as you otherwise will > result in code like > > typeof(a*b) c = a*b; > > which is pretty redundant. But I like it in a VERY common case: > > let x = new SomeClassName(); > > instead of > > SomeClassName x = new SomeClassName(); > > |
Copyright © 1999-2021 by the D Language Foundation