## digitalmars.D.announce - Re: Steve Yegge's rant on The Next Big Language

```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)]

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]
```
Mar 12 2007