Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 17, 2003 foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Okay, we Sather guys have very wordily discussed iterators in the "Using Sather as a Model" thread. The question is, does anyone like them, understand them, or care about them?
The ultimate goal is to be able to express:
int[] myarr = ...
foreach value in myarr
{
printf("%d\n", value);
}
Expressed in terms I have been discussing this might look something like:
int[] myarr = ...
loop
{
printf("%d\n", myarr.elt());
}
Where the .elt() method is an iterator. Of course "foreach" could be
syntactical sugar for "loop ... obj.elt(); .."; or, the implementation of
iterators simply may not be of interest to anyone.
Walter, have you been watching the discussion, and do you have any opinions?
--thomas
--
The UNIX philosophy basically involves giving you enough rope to hang yourself. And then a couple of feet more, just to be sure.
|
April 17, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas D. Marsh | "Thomas D. Marsh" <thomas.marsh@seznam.cz> wrote in message news:b7m2jr$ei0$1@digitaldaemon.com... > Okay, we Sather guys have very wordily discussed iterators in the "Using Sather as a Model" thread. The question is, does anyone like them, understand them, or care about them? > > The ultimate goal is to be able to express: > > int[] myarr = ... > foreach value in myarr > { > printf("%d\n", value); > } For one, I absolutely welcome everything that can cleanly increase my expressive power in a language. In fact, usually, (depending also on the task, though) nothing is more important to me than that, when considering a language. Luna Kid |
April 18, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas D. Marsh |
>The ultimate goal is to be able to express:
>
> int[] myarr = ...
> foreach value in myarr
> {
> printf("%d\n", value);
> }
>
>Expressed in terms I have been discussing this might look something like:
>
> int[] myarr = ...
> loop
> {
> printf("%d\n", myarr.elt());
> }
>
>Where the .elt() method is an iterator.
This example is simpler in functional style:
map(printf("%d\n", #), myarr);
where pound sign (#) is an argument slot. Two arrays side-by-side:
map(printf("%d\t%d\n", #1, #2), myarr, myOtherArr);
Mark
|
April 18, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | Mark Evans wrote:
>
>
> This example is simpler in functional style:
>
> map(printf("%d\n", #), myarr);
>
> where pound sign (#) is an argument slot. Two arrays side-by-side:
>
> map(printf("%d\t%d\n", #1, #2), myarr, myOtherArr);
>
> Mark
>
>
I like this syntax. But, how would you deal with conditionals? Trivial example:
foreach thing in myarray
{
if ( thing > n ) { do stuff }
else { do some other stuff }
}
Chris
|
April 18, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Lawson |
>I like this syntax. But, how would you deal with conditionals? Trivial example:
>
>foreach thing in myarray
>{
> if ( thing > n ) { do stuff }
> else { do some other stuff }
>}
The pound sign was inspired by Mathematica (with deeper
etymology elsewhere I suppose) so here's a working
example to answer your question. If[...]& defines
an anonymous function. (* Comments *) are like so.
Mathematica is an exceptional language but suffers from a fairly bad syntax that I do not advocate.
Mark
myarray = {"Albert", "Sally", "Stephen", "Ingrid"};
i=0;
result= Map[If[OddQ[i++],
(*then*)StringTake[#,1],
(*else*)StringTake[#,2]]&,
myarray]
(* produces result of *)
{"Al","S","St","I"}
|
April 18, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas D. Marsh | "Thomas D. Marsh" <thomas.marsh@seznam.cz> wrote in message news:b7m2jr$ei0$1@digitaldaemon.com... > Okay, we Sather guys have very wordily discussed iterators in the "Using Sather as a Model" thread. The question is, does anyone like them, understand them, or care about them? > > The ultimate goal is to be able to express: > > int[] myarr = ... > foreach value in myarr > { > printf("%d\n", value); > } > > Expressed in terms I have been discussing this might look something like: > > int[] myarr = ... > loop > { > printf("%d\n", myarr.elt()); > } > > Where the .elt() method is an iterator. Of course "foreach" could be > syntactical sugar for "loop ... obj.elt(); .."; or, the implementation of > iterators simply may not be of interest to anyone. > > Walter, have you been watching the discussion, and do you have any opinions? > > --thomas > > -- > The UNIX philosophy basically involves giving you enough rope to hang yourself. And then a couple of feet more, just to be sure. Personally I do love the idea of a foreach loop construct, but have two suggestions. 1) A syntax more like the C-style the rest of the language follows. FOREACH (array; indentifier) 2) Key=>Value pair iteration for associative arrays. FOREACH (array; key, value) For non-associative arrays, the latter could either be illegal, or else the key set to the numeric index. With the .keys and .values type properties in place, this shouldn't be a problem to implement. --Chris |
April 22, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | Are we still talking about D? :) --thomas Mark Evans wrote: > >>I like this syntax. But, how would you deal with conditionals? Trivial example: >> >>foreach thing in myarray >>{ >>if ( thing > n ) { do stuff } >>else { do some other stuff } >>} > > > > The pound sign was inspired by Mathematica (with deeper > etymology elsewhere I suppose) so here's a working > example to answer your question. If[...]& defines > an anonymous function. (* Comments *) are like so. > > Mathematica is an exceptional language but suffers from a fairly bad syntax that I do not advocate. > > Mark > > myarray = {"Albert", "Sally", "Stephen", "Ingrid"}; > i=0; > result= Map[If[OddQ[i++], > (*then*)StringTake[#,1], > (*else*)StringTake[#,2]]&, > myarray] > > (* produces result of *) > {"Al","S","St","I"} -- A truly great man will neither trample on a worm nor sneak to an emperor. -- B. Franklin |
April 22, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to C. Sauls | Hi! As a point of contrast I will give some examples from other languages. A foreach loop as you described would probably look like the following: int [] arr = somfunc(); foreach (arr; int i) { ... } This is syntactically familiar compared to the C-style for loop. Note that I had to add storage for "i". PYTHON Python implements these constructs with a new keyword "in": arr = [1,2,3] for i in arr: ... which I actually find to be clearer. Maybe my eyes just aren't used to "foreach (arr; int i)". Python has the following idiom for iterating over dictionaries: dict = {'a': 1, 'b': 2, ...} for (key,val) in dict.keys(): ... Notably, python 1.2.2 introduces generators/iterators, so these idioms (or perhaps their implementations) may change in order to reduce their cost. RUBY Ruby, which natively supports iterators, allows you to perform the following: arr = [1,3,5] arr.each { |i| .. do something with i.. } Actually, since iterators are pervasive in the language, all other examples will be similar to code snippets I've given in my other posts. C# Interstingly, C# provides their own syntax somewhere between your example and python's: int [] arr = new int [] {1,2,3} foreach (int i in arr) { ... } I don't use C#, so I am not familiar with associative collection iterator constructs. Perhaps there is one, but I couldn't find it PERL This example brought back some bad memories which I had long ago buried: foreach $elem (@arr) { } foreach is just syntactic sugar for the keyword "for", so you can also say: for $elem (@arr) { ... } OTHER FORMS Of course, there is the possibility to depart extravagantly from the ALGOL-ish constructs altogether: map(lambda (x) ...) this example relying on anonymous functions. And, of course the iterators of Sather: arr:ARRAY{INT} := |1,2,3|; loop #OUT+ arr.elt! + "\n"; end; REVERSE FORMS AND THE DIFFERENT APPROACHES One of the items listed on the "Future Directions" on the D home page says: A generic way to iterate across a collection, i.e. a foreach construct instead of a for loop. A reverse iterator will be needed, too. This has some interesting consequences. - The map/apply approach of functional languages requires a list reversal before iteration which may be expensive. Lisp and relatives can optimally handle list operations natively, and hence are well suited to this form. -But without major changes to D to support anonymous functions - the iterator form could be implemented in various forms (elt! and relt!, for example, plus maybe rand_elt!), but there isn't a clear desire for iterators except amongst us Sathery types. Though, by far, I consider this to be the best alternative. - An additional keyword is required in the case of the algo-ish forms, but the actual implementation would look like iterators under the covers. As far as the algol forms I find myself preferring the C#/Python style: foreach (int i in arr) { ... } foreach (int key, int val in coll) { ... } foreach reverse (int i in arr) { ... } foreach reverse (int key, int val in coll) { ... } This is most in keeping with the D style of doing things as far as I can see. --thomas C. Sauls wrote: > Personally I do love the idea of a foreach loop construct, but have two > suggestions. > 1) A syntax more like the C-style the rest of the language follows. > FOREACH (array; indentifier) > 2) Key=>Value pair iteration for associative arrays. > FOREACH (array; key, value) > > For non-associative arrays, the latter could either be illegal, or else > the > key set to the numeric index. With the .keys and .values type properties > in place, this shouldn't be a problem to implement. > > --Chris -- To say you got a vote of confidence would be to say you needed a vote of confidence. -- Andrew Young |
April 22, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas D. Marsh | Functional application requires neither anonymous functions nor list reversal. You can use named functions. If D now offers first-class functions then it should support the functional idiom. Map is a higher-order function of two arguments, a function and a list. The output is a new list. You can also define a scan which does identical list walking, but returns void, i.e. list modification in place. Mark |
April 23, 2003 Re: foreach iterators in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Thomas D. Marsh | "Thomas D. Marsh" <thomas.marsh@seznam.cz> wrote in message news:b83qfj$1cci$1@digitaldaemon.com... > > C# > > Interstingly, C# provides their own syntax somewhere between your example and python's: > > int [] arr = new int [] {1,2,3} > foreach (int i in arr) > { > ... > } > > I don't use C#, so I am not familiar with associative collection iterator constructs. Perhaps there is one, but I couldn't find it It does not have anything special for associativecollections. It works like this: foreach(DictionaryEntry myEntry in myDictionary){ Console.WriteLine(myEntry.Key + ": " + myEntry.Value); } ... or like this: foreach (string myStr in myHastable.Keys){ Console.WriteLine(myStr + ": " + myHastable[myStr]); } When a collection implements a method (GetEnumerator), which returns an iterator (something with MoveNext and Current), then foreach is available for the collection. |
Copyright © 1999-2021 by the D Language Foundation