Difference between revisions of "Function literals"

From D Wiki
Jump to: navigation, search
(literals)
 
m (fix syntax error)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
Function Literals enable embedding anonymous functions directly into expressions.
 
Function Literals enable embedding anonymous functions directly into expressions.
 +
 +
==Functions==
  
 
For example:
 
For example:
 
<syntaxhighlight lang="D">
 
<syntaxhighlight lang="D">
  int function(char c) fp;
+
int function(char c) fp;
  void main()
+
 
  {
+
void main()
    static int foo(char c) { return 6; }
+
{
    fp = &foo;
+
  static int foo(char c) { return 6; }
  }
+
  fp = &foo;
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
 
  
 
is exactly equivalent to:
 
is exactly equivalent to:
  
 
<syntaxhighlight lang="D">
 
<syntaxhighlight lang="D">
  int function(char c) fp;
+
int function(char c) fp;
  void main()
+
 
  {
+
void main()
    fp = function int(char c) { return 6;}; //note the semi-colon at the end
+
{
  }
+
  fp = function int(char c) { return 6;}; //note the semi-colon at the end
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
We now have anonymous functions...
 +
 +
This has brought up the specter of [[Dynamic Closures]]. The nested and/or anonymous functions can only access dynamic scope, which means scope that exists on the stack at the time of execution. This differs from lexical scope, which refers to the scope as indicated by the program text structure.
 +
 +
(More information can be found in the D Spec: [http://www.digitalmars.com/d/function.html#closures Closures] and [http://www.digitalmars.com/d/expression.html#functionliterals Function Literals].)
 +
 +
==Delegates==
 +
 +
Delegates are "fat" function pointers that carry a context pointer with them. They can access local variables in scope at the time of their creation.
 +
 +
Syntax:
 +
 +
<syntaxhighlight lang="d">
 +
auto func(int arg)
 +
{
 +
    // A variable that can hold a delegate
 +
    int delegate(int x) dg;
  
 +
    // Verbose syntax
 +
    dg = delegate(int x) { return arg * x; };
  
We now have anonymous functions...
+
    // Lambda syntax
 +
    dg = (x) => arg * x;
  
 +
    return dg;
 +
}
  
This has brought up the specter of /DynamicClosures. The nested and/or anonymous functions can only access dynamic scope, which means scope that exists on the stack at the time of execution. This differs from lexical scope, which refers to the scope as indicated by the program text structure.
+
void main()
 +
{
 +
    auto dg1 = func(3);
 +
    auto dg2 = func(5);
  
(More information can be found in the D Spec: [http://www.digitalmars.com/d/function.html#closures Closures] and [http://www.digitalmars.com/d/expression.html#functionliterals Function Literals].)
+
    writeln(dg1(2));  // prints 6
 +
    writeln(dg2(2));  // prints 10
 +
}
 +
</syntaxhighlight>
 +
[[Category:HowTo]]

Latest revision as of 13:26, 26 August 2017

Function Literals enable embedding anonymous functions directly into expressions.

Functions

For example:

int function(char c) fp;

void main()
{
   static int foo(char c) { return 6; }
   fp = &foo;
}

is exactly equivalent to:

int function(char c) fp;

void main()
{
   fp = function int(char c) { return 6;}; //note the semi-colon at the end
}

We now have anonymous functions...

This has brought up the specter of Dynamic Closures. The nested and/or anonymous functions can only access dynamic scope, which means scope that exists on the stack at the time of execution. This differs from lexical scope, which refers to the scope as indicated by the program text structure.

(More information can be found in the D Spec: Closures and Function Literals.)

Delegates

Delegates are "fat" function pointers that carry a context pointer with them. They can access local variables in scope at the time of their creation.

Syntax:

auto func(int arg)
{
    // A variable that can hold a delegate
    int delegate(int x) dg;

    // Verbose syntax
    dg = delegate(int x) { return arg * x; };

    // Lambda syntax
    dg = (x) => arg * x;

    return dg;
}

void main()
{
    auto dg1 = func(3);
    auto dg2 = func(5);

    writeln(dg1(2));   // prints 6
    writeln(dg2(2));   // prints 10
}