www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - auto in foreach

reply Derek Parnell <derek psych.ward> writes:
I'm sure this has been mentioned before but I couldn't find it.

Would the syntax ...

   foreach(auto elem; array) ...

be a useful addition to D?

The meaning being that as the compiler already knows what data type 'array'
is an array of, it could assume that the coder wants 'elem' to be the same
data type, whatever that happens to be.

We could still use something other than 'auto' when we wanted to override
the obvious data type. 

BTW, 'auto' is just a suggestion, but as its being used for
compiler-determined data types already it might be the easy choice for this
idea.

Further more, if its not to hard to parse, the 'auto' could be omitted
altogether ...

  foreach(elem; array) ...


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"A learning experience is one of those things that says,
 'You know that thing you just did? Don't do that.'" - D.N. Adams
12/12/2005 12:29:48 PM
Dec 11 2005
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Derek Parnell wrote:
 I'm sure this has been mentioned before but I couldn't find it.
 
 Would the syntax ...
 
    foreach(auto elem; array) ...
 
 be a useful addition to D?
 
 The meaning being that as the compiler already knows what data type 'array'
 is an array of, it could assume that the coder wants 'elem' to be the same
 data type, whatever that happens to be.
 
 We could still use something other than 'auto' when we wanted to override
 the obvious data type. 

I agree that this would be nice, but the problem is that for the general case, opApply could be overloaded for different argument types. What is the obvious data type for such container classes? Of course, if there is only one opApply, that argument type would be the obvious choice, but this would be slightly more awkward for the compiler to find out. So, I guess auto should be possible for the cases with only one opApply, and ambigous otherwise.
 BTW, 'auto' is just a suggestion, but as its being used for
 compiler-determined data types already it might be the easy choice for this
 idea.

This is an obvious extension of auto for type inference.
 Further more, if its not to hard to parse, the 'auto' could be omitted
 altogether ...
 
   foreach(elem; array) ...

What should this print then? char x = 'x'; foreach(x; "abc") {} writefln("'%s'",x); Regards, /Oskar
Dec 12 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 12 Dec 2005 10:10:03 +0100, Oskar Linde wrote:

 Derek Parnell wrote:
 I'm sure this has been mentioned before but I couldn't find it.
 
 Would the syntax ...
 
    foreach(auto elem; array) ...
 
 be a useful addition to D?
 
 The meaning being that as the compiler already knows what data type 'array'
 is an array of, it could assume that the coder wants 'elem' to be the same
 data type, whatever that happens to be.
 
 We could still use something other than 'auto' when we wanted to override
 the obvious data type. 

I agree that this would be nice, but the problem is that for the general case, opApply could be overloaded for different argument types. What is the obvious data type for such container classes?

?Huh? Maybe I didn't make myself clear. All I was suggesting was instead of *me* writing ... char[] array_C; foreach(char x; array_C) { ... } int[] array_I; foreach(int x; array_I) { ... } I could write ... char[] array_C; foreach(auto x; array_C) { ... } // x is a char 'cos array_C is char[] int[] array_I; foreach(auto x; array_I) { ... } // x is a int 'cos array_C is int[] It's just a convenience. The 'obvious' data type to use is the data type that the source array is an array of!
 Of course, if there is only one opApply, that argument type would be the 
 obvious choice, but this would be slightly more awkward for the compiler 
 to find out.
 
 So, I guess auto should be possible for the cases with only one opApply, 
 and ambigous otherwise.

Why is it ambiguous letting the compiler make the choice based on the array's data type and not ambiguous when I make *THE SAME DECISION*.
 BTW, 'auto' is just a suggestion, but as its being used for
 compiler-determined data types already it might be the easy choice for this
 idea.

This is an obvious extension of auto for type inference.
 Further more, if its not to hard to parse, the 'auto' could be omitted
 altogether ...
 
   foreach(elem; array) ...

What should this print then? char x = 'x'; foreach(x; "abc") {} writefln("'%s'",x);

Ummmm ... 'x' ? What has this foreach() got to do with the assignment and writefln()? The 'x' declared in the foreach() is not the same 'x' as the one in the assignment and writefln(). -- Derek Parnell Melbourne, Australia 12/12/2005 10:56:51 PM
Dec 12 2005
next sibling parent Don Clugston <dac nospam.com.au> writes:
Derek Parnell wrote:
 
     char[] array_C;
     foreach(auto x; array_C) { ... } // x is a char 'cos array_C is char[]
 
     int[] array_I;
     foreach(auto x; array_I) { ... } // x is a int 'cos array_C is int[]

 It's just a convenience. The 'obvious' data type to use is the data type
 that the source array is an array of!

Yes, typeof(cont[0]) for array typeof(cont[""]) for AA. BUT...
 Why is it ambiguous letting the compiler make the choice based on the
 array's data type and not ambiguous when I make *THE SAME DECISION*.

It's only the class/struct situation that is the problem. Suppose MyClass defines two opApply()s, so you can write MyClass cont; foreach(int x, cont) {} foreach(char [] x, cont) {} Then: foreach(auto x; cont) {...} what is the type of x? Of course, you could say that 'auto' is not allowed in foreach if a container is being used.
Dec 12 2005
prev sibling next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Hi,

Derek Parnell wrote:
 On Mon, 12 Dec 2005 10:10:03 +0100, Oskar Linde wrote:
 
 
Derek Parnell wrote:

I'm sure this has been mentioned before but I couldn't find it.

Would the syntax ...

   foreach(auto elem; array) ...

be a useful addition to D?

The meaning being that as the compiler already knows what data type 'array'
is an array of, it could assume that the coder wants 'elem' to be the same
data type, whatever that happens to be.

We could still use something other than 'auto' when we wanted to override
the obvious data type. 

I agree that this would be nice, but the problem is that for the general case, opApply could be overloaded for different argument types. What is the obvious data type for such container classes?

?Huh? Maybe I didn't make myself clear. All I was suggesting was instead of *me* writing ... char[] array_C; foreach(char x; array_C) { ... } int[] array_I; foreach(int x; array_I) { ... } I could write ... char[] array_C; foreach(auto x; array_C) { ... } // x is a char 'cos array_C is char[] int[] array_I; foreach(auto x; array_I) { ... } // x is a int 'cos array_C is int[] It's just a convenience. The 'obvious' data type to use is the data type that the source array is an array of!

Yes, you made yourself clear. I was thinking of the more general case, where foreach also has to work on classes implementing opApply. Should this not apply to those cases? Set<int> s = ...; foreach(auto x;s) { ... }
Of course, if there is only one opApply, that argument type would be the 
obvious choice, but this would be slightly more awkward for the compiler 
to find out.

So, I guess auto should be possible for the cases with only one opApply, 
and ambigous otherwise.

Why is it ambiguous letting the compiler make the choice based on the array's data type and not ambiguous when I make *THE SAME DECISION*.

You misunderstood me. It is ambiguous for classes implementing more than one opApply, not for built in array types. So: Auto is possible for built in arrays and classes with only one opApply. It could be ambiguous otherwise. Note: I am in favour of your suggestion and have also wished for the same feature a couple of times. :)
Further more, if its not to hard to parse, the 'auto' could be omitted
altogether ...

  foreach(elem; array) ...

What should this print then? char x = 'x'; foreach(x; "abc") {} writefln("'%s'",x);

Ummmm ... 'x' ? What has this foreach() got to do with the assignment and writefln()? The 'x' declared in the foreach() is not the same 'x' as the one in the assignment and writefln().

I'm sorry. I've just assumed that the above would (in current D) make the loop variable refer to the x in the outer scope when written without type declarator. This is how foreach works in another language I'm used to. Referring to the D spec, this is obviously not the case. Getting slightly carried away: This "implicit auto" could be used at other places too. Implicit mini-templates for instance. square(x) { return x*x; } Most useful as simple one-shot function literals. The following example should work in D currently (minus bugs... not tested): // Map an array over a function template map(T:T[]) { T[] map(T[] x, T function (T x) fun) { T[] ret; ret.length = x.length; foreach(int i, T v;x) ret[i] = fun(v); return ret; } } void main() { const int[] x = [1,2,3,4]; int[] x2 = map!(int[])(x, function int(int x) { return x*x; } ); writefln(x2); } With a more powerful auto, line 2 of main could be written as: auto x2 = map!(int[])(x, function auto(auto x) { return x*x; } ); With implicit template instantiation: auto x2 = map(x, function auto(auto x) { return x*x; } ); With implicit auto: auto x2 = map(x, function (x) { return x*x; } ); Getting really carried away as usual: It would also be neat if it was some way to define single expression function literals with a shorthand notation, like: auto x2 = map(x, {x | x*x }); In conclusion: Auto became implicit in C, so why not in D? ;) Regards, Oskar
Dec 12 2005
parent Derek Parnell <derek psych.ward> writes:
On Mon, 12 Dec 2005 14:24:49 +0100, Oskar Linde wrote:


[snip]
 
 You misunderstood me. It is ambiguous for classes implementing more than 
 one opApply, not for built in array types.
 
 So: Auto is possible for built in arrays and classes with only one 
 opApply. It could be ambiguous otherwise.

Got you. Yes, I didn't understand this as I forgot about classes and structs being allowed in the foreach() construct. So then I should have said something more like ... one can use 'auto' to refer to the data type in a foreach(), when and only when, there is no ambiguity.
 Note: I am in favour of your suggestion and have also wished for the 
 same feature a couple of times. :)

[snip]
 In conclusion: Auto became implicit in C, so why not in D? ;)

-- Derek Parnell Melbourne, Australia 13/12/2005 8:21:07 AM
Dec 12 2005
prev sibling parent pragma <pragma_member pathlink.com> writes:
In article <49dh751rgpvu.1m9e5pel4ftby.dlg 40tude.net>, Derek Parnell says...
On Mon, 12 Dec 2005 10:10:03 +0100, Oskar Linde wrote:
 
 What should this print then?
 
 char x = 'x';
 foreach(x; "abc")
 {}
 writefln("'%s'",x);
 

Ummmm ... 'x' ? What has this foreach() got to do with the assignment and writefln()? The 'x' declared in the foreach() is not the same 'x' as the one in the assignment and writefln().

If it helps, I agree with you both. A new variable x would be declared as a char (implicitly as Oskar suggests) for the foreach, but it does have the rather odd visual ambiguity as a variable x just happens to be declared outside the foreach. I stress that the ambiguity is *visual* only, as this would only be confusing to those not aware of the neuances of D. For example, C/C++'s for() doesn't scope within its declaration, so it could be easy to assume that D's foreach wouldn't either. Anyway, its probably best to stick with the 'auto' version and leave it at that. - EricAnderton at yahoo
Dec 12 2005
prev sibling parent MicroWizard <MicroWizard_member pathlink.com> writes:
I like it, regardless of it's implications.
Just because ... it looks very useful (and clear :-).

Tamás Nagy

In article <1dzu1z97zl5jf.1psziq1ikywpo$.dlg 40tude.net>, Derek Parnell says...
I'm sure this has been mentioned before but I couldn't find it.

Would the syntax ...

   foreach(auto elem; array) ...

be a useful addition to D?

The meaning being that as the compiler already knows what data type 'array'
is an array of, it could assume that the coder wants 'elem' to be the same
data type, whatever that happens to be.

We could still use something other than 'auto' when we wanted to override
the obvious data type. 

BTW, 'auto' is just a suggestion, but as its being used for
compiler-determined data types already it might be the easy choice for this
idea.

Further more, if its not to hard to parse, the 'auto' could be omitted
altogether ...

  foreach(elem; array) ...


-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"A learning experience is one of those things that says,
 'You know that thing you just did? Don't do that.'" - D.N. Adams
12/12/2005 12:29:48 PM

Dec 12 2005