www.digitalmars.com         C & C++   DMDScript  

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