Jump to page: 1 2
Thread overview
foreach iterators in D
Apr 17, 2003
Thomas D. Marsh
Apr 17, 2003
Luna Kid
Apr 18, 2003
Mark Evans
Apr 18, 2003
Chris Lawson
Apr 18, 2003
Mark Evans
Apr 22, 2003
Thomas D. Marsh
Apr 18, 2003
C. Sauls
Apr 22, 2003
Thomas D. Marsh
Apr 22, 2003
Mark Evans
Apr 25, 2003
C. Sauls
Apr 23, 2003
Peter Hercek
Apr 25, 2003
Mark T
Apr 27, 2003
Dario
Apr 27, 2003
Thomas D. Marsh
Apr 28, 2003
Ilya Minkov
Apr 28, 2003
Dario
May 16, 2003
Walter
May 16, 2003
C. Sauls
May 20, 2003
Daniel Yokomiso
May 23, 2003
C. Sauls
April 17, 2003
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
"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
>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
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
>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
"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
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
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
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
"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.


« First   ‹ Prev
1 2