digitalmars.D.learn - delegate from lambda expression
- timotheecour (31/31) Sep 09 2012 I'd like to achieve the following:
- bearophile (21/40) Sep 09 2012 Your code doesn't look good, I suggest to write less golfed D
- bearophile (4/5) Sep 09 2012 On the other hand it's not impossible to invent a syntax for
- Timon Gehr (2/3) Sep 09 2012 Yes it does.
- Timon Gehr (10/39) Sep 09 2012 Those need full type information. The lambda as shown is generic.
- timotheecour (9/10) Sep 09 2012 What was wrong with it and what would you suggest to improve it?
- bearophile (11/15) Sep 09 2012 Nothing serious, I just suggest to give a bit more air to your
- Timon Gehr (4/15) Sep 09 2012 (That means it is here to stay.)
- Jacob Carlborg (7/31) Sep 10 2012 Try this:
I'd like to achieve the following: ---- import std.stdio,std.range,std.algorithm,std.array; void main(){ auto dg=a=>a*2; auto a=iota(0,10); writeln(a.map!dg.array); } ---- but this doesn't compile: Error: variable [...]dg type void is inferred from initializer delegate (__T26 a) { return a * 2; } , and variables cannot be of type void However this works: writeln(a.map!(a=>a*2).array); but I want to reuse dg in other expressions (and avoid repeating myself) Also, I want to avoid using string litteral enum dg=`a*2` as in my case dg is much more complicated and this is cleaner without a string IMHO. My questions: 1) why can't the compiler infer the type int(int) for dg? 2) how to convert a lambda a=>a*2 to a delegate or function? 3) if 2 is not possible, how to achieve what I'm trying to do WITHOUT having to make the type explicit as in "int delegate(int) dg=(int a){return a*2;}"? 4) is there a way to have template delegates, and what's the syntax in this simple example?
Sep 09 2012
timotheecour:I'd like to achieve the following: ---- import std.stdio,std.range,std.algorithm,std.array; void main(){ auto dg=a=>a*2; auto a=iota(0,10); writeln(a.map!dg.array); } ---- but this doesn't compile: Error: variable [...]dg type void is inferred from initializer delegate (__T26 a) { return a * 2; } , and variables cannot be of type void However this works: writeln(a.map!(a=>a*2).array);Your code doesn't look good, I suggest to write less golfed D code. One solution to your problem is to define a function template (note the static, that is currently needed, but maybe not in future): import std.stdio, std.range, std.algorithm, std.array; void main() { static dg(T)(T a) { return a * 2; } auto items = iota(10); items.map!dg().array().writeln(); }1) why can't the compiler infer the type int(int) for dg?Because in D there is no global inferencer, like a Hindley–Milner (and you can't defer typing as in one recent language). I think not even Scala allows you to write code similar to: auto dg = a => a * 2; You need a language with global inferencing, like Haskell, ShedSkin, Idris, etc. Bye, bearophile
Sep 09 2012
Because in D there is no global inferencer,On the other hand it's not impossible to invent a syntax for templated lambdas, etc :-) Bye, bearophile
Sep 09 2012
On 09/10/2012 01:55 AM, bearophile wrote:Your code doesn't look good,Yes it does.
Sep 09 2012
On 09/10/2012 01:20 AM, timotheecour wrote:I'd like to achieve the following: ---- import std.stdio,std.range,std.algorithm,std.array; void main(){ auto dg=a=>a*2; auto a=iota(0,10); writeln(a.map!dg.array); } ---- but this doesn't compile: Error: variable [...]dg type void is inferred from initializer delegate (__T26 a) { return a * 2; } , and variables cannot be of type void However this works: writeln(a.map!(a=>a*2).array); but I want to reuse dg in other expressions (and avoid repeating myself) Also, I want to avoid using string litteral enum dg=`a*2` as in my case dg is much more complicated and this is cleaner without a string IMHO. My questions: 1) why can't the compiler infer the type int(int) for dg?Because it can't. D unfortunately does not have powerful type inference.2) how to convert a lambda a=>a*2 to a delegate or function?Those need full type information. The lambda as shown is generic.3) if 2 is not possible, how to achieve what I'm trying to do WITHOUT having to make the type explicit as in "int delegate(int) dg=(int a){return a*2;}"?template ID(alias a){ alias a ID; } void main(){ alias ID!(a=>a*2) dg; auto a=iota(0,10); writeln(a.map!dg.array); }4) is there a way to have template delegates, and what's the syntax in this simple example?Already shown.
Sep 09 2012
Thanks! the template alias ID solves my problem.What was wrong with it and what would you suggest to improve it? Also, I noticed you replaced (among other things): a.map!dg.array by a.map!dg().array() Will the way I'm skipping "()" ever be deprecated? One of the points of UFCS was to avoid writing too much parentheses (in addition to avoiding writing nested parentheses).Your code doesn't look good,
Sep 09 2012
timotheecour:What was wrong with it and what would you suggest to improve it?Nothing serious, I just suggest to give a bit more air to your code, adding a space around operators, after commas, etc. Otherwise your code risk looking like Timon's code ;-) I have also compiled the code with -property. Some people don't like this. The choice is yours, but you need to express an informed choice.Will the way I'm skipping "()" ever be deprecated?Who knows. People disagree on this :-)One of the points of UFCS was to avoid writing too much parenthesesWhere did you read this? Bye, bearophile
Sep 09 2012
On 09/10/2012 02:56 AM, bearophile wrote:timotheecour:Which is usually extremely beautiful. This is not a liability.What was wrong with it and what would you suggest to improve it?Nothing serious, I just suggest to give a bit more air to your code, adding a space around operators, after commas, etc. Otherwise your code risk looking like Timon's code ;-)I have also compiled the code with -property. Some people don't like this. The choice is yours, but you need to express an informed choice.(That means it is here to stay.)Will the way I'm skipping "()" ever be deprecated?Who knows. People disagree on this :-)He most definitely has a point there.One of the points of UFCS was to avoid writing too much parenthesesWhere did you read this?
Sep 09 2012
On 2012-09-10 01:20, timotheecour wrote:I'd like to achieve the following: ---- import std.stdio,std.range,std.algorithm,std.array; void main(){ auto dg=a=>a*2; auto a=iota(0,10); writeln(a.map!dg.array); } ---- but this doesn't compile: Error: variable [...]dg type void is inferred from initializer delegate (__T26 a) { return a * 2; } , and variables cannot be of type void However this works: writeln(a.map!(a=>a*2).array); but I want to reuse dg in other expressions (and avoid repeating myself) Also, I want to avoid using string litteral enum dg=`a*2` as in my case dg is much more complicated and this is cleaner without a string IMHO. My questions: 1) why can't the compiler infer the type int(int) for dg? 2) how to convert a lambda a=>a*2 to a delegate or function?Try this: auto dg = (int a) => a * 2; If that doesn't work, this should: auto dg = (int a) { return a * 2; }; -- /Jacob Carlborg
Sep 10 2012