Steve Yegge's rant on The Next Big Language

mario pernici mario.pernici at mi.infn.it
Mon Mar 12 09:48:02 PDT 2007


Frits van Bommel Wrote:

> Foo wrote:
> > I think the syntax of delegate literal should be simplified, like this:
> > int[] squares = numbers.map( int(int x){return x * x;} );
> > 
> > or ruby-like syntax:
> > int[] squares = numbers.map( {int|int x| x * x} );
> 
> *ahem* You just didn't simplify _enough_ ;):
> ---
> $ cat test.d
> import std.stdio;
> 
> R[] map(T,R)(T[] arr, R delegate(T) dg){
>      R[] result = new R[arr.length];
>      foreach(i, item; arr)
>          result[i] = dg(item);
>      return result;
> }
> 
> void main(){
>      int[] numbers = [1, 2, 3, 4, 5, 6, 7, 8];
>      int[] squares = numbers.map( (int x){return x * x;} );
>      writefln(squares);
> }
> $ dmd -run test.d
> [1,4,9,16,25,36,49,64]
> ---
> As you can see, your first example works if you also leave out the 
> return type :).
> (See http://www.digitalmars.com/d/expression.html#FunctionLiteral)
> 
> I'm not quite sure why you're not allowed to explicitly specify the 
> return type without also specifying "function" or "delegate" first, but 
> it could be there's some syntactic ambiguity that would create which I 
> can't think of right now. Or it could just be that Walter overlooked it, 
> thought it too hard to implement, or simply not worth it for some reason...
> 
> 
> [a bit later]
> I just thought of a semi-ambiguity. If the return type and the types of 
> any parameters are user-defined, and all parameters (if any) are 
> anonymous and implicitly 'in', the first part looks just like a function 
> call: "foo(bar)" can then be either a call to a function 'foo' with 
> parameter 'bar', or the start of a delegate returning a value of type 
> 'foo' taking an anonymous parameter of type 'bar'.
> But since IIRC D already requires an infinite-lookahead parser, the next 
> character (either a '{' or not) should disambiguate, which is why I only 
> called this a semi-ambiguity.
> Can anyone think of an actual ambiguity, or think of another reason this 
> is not allowed? Barring fault, oversight or laziness (or perhaps just 
> busy-ness) on Walter's part, of course :P.

With Python's list comprehensions one can do
>>> [x*x for x in numbers if not(x&1)]
[4, 16, 36, 64]

A similar thing can be done in D overloading map() in this thread with

R[] map(T,R,S)(T[] arr, R delegate(T) dg, S delegate(T) df){
     R[] result;
     foreach(i, item; arr) {
         if(df(item))
           result ~= dg(item);
     }
     return result;
}

void main(){
     int[] numbers = [1, 2, 3, 4, 5, 6, 7, 8];
     writefln(numbers.map( (int x){return x * x;} ));
     writefln(numbers.map((int x){return x * x;}, (int x) { return !(x & 1);} ));
}

Output:
[1,4,9,16,25,36,49,64]
[4,16,36,64]




More information about the Digitalmars-d-announce mailing list