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