Prettier iterator implementations in D?

Alexander Panek a.panek at brainsware.org
Sat Oct 21 02:42:05 PDT 2006


On Fri, 2006-10-20 at 16:50 +0900, Bill Baxter wrote:
> Alexander Panek wrote:
> > I know Ruby, and it's loops are very cool, indeed. But this is D, and as
> > a full blown *system and application programming language*, you can't
> > compare it to Ruby. 
> 
> What is D if not "the speed of C++ with the ease of Ruby"?

D has a C like syntax, Ruby does definitely not. :)

> 
> > I don't think syntactic sugar should be added too
> > hasty. 
> 
> I agree.  That's why plenty of discussion is needed.  So start poking holes!
> 
> > Apart from that I kinda like the delegate / function ptr syntax
> > as it is.
> 
> And you could still use it as is if you like, because the suggestion is 
> to make 'delegate' optional, not mandate it's removal.

Wouldn't it be better to solve such things with a little library (as you
suggested)? I do like the constructs of higher level languages that have
been added to D, but the meaning of each should be recognizable on the
first sight. So when you look at a big fat nested arguments list you'd
use your syntax to shorten it - but would it be readable for others?

What D has made possible [imho] is to make code more readable. You have
explicitly named or styled syntax sugar, that is mostly not used as is
in other languages, and thus can't really be misread through confusion.
I wouldn't want this to be changed, actually.

> 
> About whether sugar is warranted here:  it seems Walter sees this 
> delegate mechanism as becoming *the* primary technique for iteration in 
> D.  That being the case, it should be as easy to read and write as 
> possible.   Being easier to use than C++ iterators is the primary reason 
> he gives for liking it, in fact.  So let's figure out how to make 
> absolutely as simple as possible.

alias! :P

> 
> Right now, say you want to write a generic array iterator factory 
> function 'traverser', which you do because it allows you to do this:
> 
>      foreach(int i; iarray.traverser()) {
>        ...
>      }
> to iterate in some custom way over the elements of any array.
> 
> Here is the signature for that now (returns a delegate that takes a 
> delegate parameter):
> 
>    int delegate(int delegate(inout typeof(ArrayT[0])))
>       traverser(ArrayT)(inout ArrayT array)
>    {
>    }
>    ...
> 
> 
> The int delegate(int delegate ...) business is just too verbose to grok 
> easily.   If I change the ints to voids and drop the 'delegate':
> 
> (( inout typeof(ArrayT[0]) )) reversed(ArrayT)(inout ArrayT array)
> 
> I think that's easier to look at if for no other reason than being 
> shorter.  But I'll admit it probably is more mind boggling at first. 
> But it's not a stretch to say most everybody could get used to reading
> 
>    (int) somefunc() {...}
> 
> as a function that returns a void-returning, int-taking delegate.  Just 
> think of the (int) as a lone argument list ["takes an int"] and it's 
> pretty clear.
> And in that light it's not hard to see the extra sets of parens (( )) 
> mean 'a void returning delegate that takes a void returning delegate'. 
> At some point (( type )) just becomes second nature as the basic return 
> signature for an iterator factory.  It's easy to see once you know to 
> look for it, because its so short and (( )) stands out if spaced properly.
> 
> Another alternative is standard aliases for those complicated types:
> 
> template Types(ArgT) {
>      static if( is (ArgT[0]) ) {
> 	alias typeof(ArgT[0]) elem_t;
>      }
>      else static if( is(ArgT.elem_t) ) {
> 	alias ArgT.elem_t elem_t;
>      }
>      else {
>          alias ArgT elem_t;
>      }
>      alias int delegate(int delegate(inout elem_t)) iter_t;
>      // this works for anything that is either array-like or has an
>      // elem_t alias.
> }
> 
> Then you can use those aliases like:
> 
>    Types!(ArrayT).iter_t  reversed(ArrayT)(inout ArrayT array)
>    { ... }
> 
> that still looks kinda klunky :-/, but maybe better.  At least it's 
> short enough to fit on one line.  But it just replaces having to know 
> what (( )) means with having to know what Types!().iter_t means.  So I'm 
> not sure it's really better.

I doesn't look klunky to me, actually. You can still use standard
aliases to 'beautify' it, for example if you make a library of such
things.

> 
> Well at least it is something that works now!
> 
> --bb
> 

Yes :)

Alex




More information about the Digitalmars-d mailing list