www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Syntax question about inlined functions/delegates/lambdas

reply "Gordon" <me home.com> writes:
Hello,

I have a syntax question regarding the correct usage of 
function/delegates/lambdas, arising after a used it incorrectly 
and it took a long time to debug and see what's going on.
I found out there's a syntax which compiles OK but doesn't work 
(as I naively expected).

The following is a concise example:
===
import std.stdio;
import std.functional;

void call_function(FUNC...)()
{
         alias unaryFun!FUNC _Fun;
         _Fun(42);
}

void main()
{
         call_function!( function(x)    { writeln("funcion,  case 
1. X = ",x); } )();
         call_function!( function(x) => { writeln("funcion,  case 
2. X = ",x); } )();
         call_function!( delegate(x)    { writeln("delegate, case 
3. X = ",x); } )();
         call_function!( delegate(x) => { writeln("delegate, case 
4. X = ",x); } )();
         call_function!( (x)            { writeln("funcion,  case 
5. X = ",x); } )();
         call_function!( (x)         => { writeln("lambda,   case 
6. X = ",x); } )();
         call_function!( (x)         =>   writeln("lambda,   case 
7. X = ",x)    )();
}
===

The output is:
===
$ rdmd ./delegate_question.d
funcion,  case 1. X = 42
delegate, case 3. X = 42
funcion,  case 5. X = 42
lambda,   case 7. X = 42
===

So I've learned that syntaxes in cases 2,4,6 are wrong, but they 
still compile.
May question is - what do they do? what usage do they have (since 
they do not trigger a compilation warning)?

Thanks,
  -gordon
Dec 30 2013
next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Monday, 30 December 2013 at 19:00:49 UTC, Gordon wrote:
 So I've learned that syntaxes in cases 2,4,6 are wrong, but 
 they still compile.
 May question is - what do they do? what usage do they have 
 (since they do not trigger a compilation warning)?

 Thanks,
  -gordon
You could notice that syntaxes 2,4,6 are "=>{" which means that what follows next is return value, not body of function, i.e they don't do what is expected but return delegates which do what is expected. You need to wrap them into ()() to make them work. By the way, strictly speaking they are template lambdas.
Dec 30 2013
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Gordon:

 ...
 case 5. X = ",x); } )();
         call_function!( (x)         => { writeln("lambda,   
 case 6. X = ",x); } )();
         call_function!( (x)         =>   writeln("lambda,   
 case 7. X = ",x)    )();
 }
There is also the simpler syntax: x => writeln("lambda, case 8. X = ", x)
 So I've learned that syntaxes in cases 2,4,6 are wrong, but 
 they still compile.
 May question is - what do they do? what usage do they have 
 (since they do not trigger a compilation warning)?
Observe: void main() { import std.stdio; auto f = (int x) => { x.writeln; }; f(10)(); } It prints 10. The syntax for lambdas is "... => ...", while (...){...} was the older syntax. If you use both, you are creating a lambda that returns a lambda. Bye, bearopile
Dec 30 2013
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/30/2013 11:00 AM, Gordon wrote:
 Hello,

 I have a syntax question regarding the correct usage of
 function/delegates/lambdas, arising after a used it incorrectly and it
 took a long time to debug and see what's going on.
 I found out there's a syntax which compiles OK but doesn't work (as I
 naively expected).

 The following is a concise example:
 ===
 import std.stdio;
 import std.functional;

 void call_function(FUNC...)()
 {
          alias unaryFun!FUNC _Fun;
          _Fun(42);
 }

 void main()
 {
          call_function!( function(x)    { writeln("funcion,  case 1. X =
 ",x); } )();
          call_function!( function(x) => { writeln("funcion,  case 2. X =
 ",x); } )();
          call_function!( delegate(x)    { writeln("delegate, case 3. X =
 ",x); } )();
          call_function!( delegate(x) => { writeln("delegate, case 4. X =
 ",x); } )();
          call_function!( (x)            { writeln("funcion,  case 5. X =
 ",x); } )();
          call_function!( (x)         => { writeln("lambda,   case 6. X =
 ",x); } )();
          call_function!( (x)         =>   writeln("lambda,   case 7. X =
 ",x)    )();
 }
 ===

 The output is:
 ===
 $ rdmd ./delegate_question.d
 funcion,  case 1. X = 42
 delegate, case 3. X = 42
 funcion,  case 5. X = 42
 lambda,   case 7. X = 42
 ===

 So I've learned that syntaxes in cases 2,4,6 are wrong, but they still
 compile.
 May question is - what do they do? what usage do they have (since they
 do not trigger a compilation warning)?

 Thanks,
   -gordon
(Note: This thread is more suited to the D.learn newsgroup.) Once we move the incompatible ones away, the function literals work as expected: import std.stdio; import std.functional; void call_function(FUNC...)() { foreach (func; FUNC) { auto f = func(42); f(); } // alias unaryFun!FUNC _Fun; // _Fun(42); } void main() { // call_function!( function(x) { writeln("funcion, case 1. X = ",x); } )(); call_function!( function(x) => { writeln("funcion, case 2. X = ",x); } )(); // call_function!( delegate(x) { writeln("delegate, case 3. X = ",x); } )(); call_function!( delegate(x) => { writeln("delegate, case 4. X = ",x); } )(); // call_function!( (x) { writeln("funcion, case 5. X = ",x); } )(); call_function!( (x) => { writeln("lambda, case 6. X = ",x); } )(); // call_function!( (x) => writeln("lambda, case 7. X = ",x) )(); } The output: funcion, case 2. X = 42 delegate, case 4. X = 42 lambda, case 6. X = 42 Ali
Dec 30 2013