Eve Lambda Expressions
What is a lambda expression
Lambda is a notation, not a type: a lambda expression creates a function in a single statement from one or more expressions. Parentheses are mandatory, a list of expressions creates several results, and the type goes after the parentheses: ():Type or ():(Type, Type). A lambda assigned to an identifier that is not defined is just a pointer; it can be sent to a parameter that receives a pointer @param.
Lambda expressions are simpler functions that respect arithmetic rules. These can receive several arguments and can produce one result. A lambda expression is created with keywords "set" or "new". Lambda expressions do not have local variables or states and do not have side effects.
Lambda expressions can be declared in the global scope but also in a process. Lambda expressions are associated to a variable, sometimes can be associated to a member in a collection.
Example
In next example we define two lambda expressions.
set sum = (p1, p2 :Integer) => (p1 + p2):Integer;
set mul = (p1, p2 :Integer) => (p1 * p2):Integer;
Lambda & states
Lambda expressions can read global or parent scope states, but can not modify them. However, if external values change after expression is defined, the result may be influenced by the new values.
Example:
# verify shared state influence
driver shared_states is
** define global settings
set decimals = 2: Integer;
set trunc = (x:Real) => floor(x* 10^decimals)/10^decimals;
process main is
new x := 10/3;
** call the lambda expression
print trunc(x); ** expected 3.33
** overwrite the initial settings
let decimals := 4;
print trunc(x); ** expected 3.3333
return;
end shared_states;
Disclaimer: We acknowledge, Eve is not a pure functional language. This behavior is present in many other modern languages. Eve is not different. We seek for a balance between the theory and pragmatism.
Where a lambda can stand
| Place | Example |
|---|---|
| assigned to a name | set sum = (a, b: Integer) => (a + b):Integer; |
| an argument of a call (a callback) | useLambda((x, y) => (x + y)); |
| a member of a collection | new ops := ((a, b) => (a + b), (a, b) => (a * b)); |
| the result of a function | function adder(n: Integer) => (@f: Function) is let f := (x) => (x + n); return; |
Rules
- A lambda holds expressions only: no statements, no local variables and no state;
- A lambda does not change anything. It may read values of its creator, and it sees the new value when that changes (see "Lambda & states");
- For a name, a state or several statements, use a function, and for a state kept between calls, a closure (Closures);
- The type of a lambda is a function type: see Callbacks.
set sum = … ; with the declaration order of D-079 and check each one against spec/syntax when the spec is written.(x, y) => (x + y) in the callback example), and when the inference fails.map, filter, sort(by), reduce (Q-026). Then add a section with one example for each.Read next: Callbacks