Simple Expressions
There are many ways to write lambda expressions when the body is a single expression:
λ x . x + 1 {x -> x + 1} // Curly braces are common [x -> x + 1] // Not so common, looks like an array (x -> x + 1) // Let the -> operator imply function type fn x => x + 1 // ML lambda (x) x + 1 (lambda (x) (+ x 1)) sub {$0 + 1} // Perl {$0 + 1} {_ + 1} // Scala λ x y . 2 * x + y {x y -> 2 * x + y} fn x y => 2 * x + y fn (x,y) => 2 * x + y lambda (x, y) 2 * x + y sub {2 * $0 + $1} {2 * $0 + $1}
Some of these require a bit more lookahead to parse than others.
Complex Function Bodies
If your language has a sequencing expression, like C's comma expression, where e1, e2, e3 means to evaluate each expression in order and return the value of the last expression encountered, then you can use the sequencing expression in any of the forms above. Operator precedence becomes the only real issue, but parentheses can make it clear exactly what the function is.
{ p, i -> k = p * 0.45359237, m = 0.0254, k / (m * m) }
Let-expressions work well here, too
{ p, i -> let k = p * 0.45359237 and m = 0.0254 in k / (m * m) end }
Lambdas can be arbitrarily complex, with return statements. Some languages allow you to omit the return statement if the expression to return is the last one in the sequence.
TODO
Recursion
To arrange for an anonymous function to be called recursively, it needs to have a name or the language should reserve a special keyword to refer to the currently executing function (watch for scoping rules here).
{[f] n -> n <= 1 ? 1 : f(n - 1) * n}
{n -> n <= 1 ? 1 : CALLEE(n - 1) * n}
Allowing recursion in lambda expressions is far better than requiring the applicative Y combinator.
Closures
Lambdas often refer to variables in outer scopes. Within the lambda expression, these outside variables are called free variables.
function incrementer(int start, int delta) { var current = start - delta; return function () {return current += delta;} }
Calling Lambda Expressions
Calling, or applying a function, is normally done with juxtaposition, though again precedence rules will often come into play.
(x -> x + 1)7 (x -> x + 1)(7) [x -> x + 1](7 * y - 2) [x -> x + 1] 7 * y - 2 // application or multiplication first?fn (x, y) => 2 * x + y (7, y)// too confusing (fn (x, y) => 2 * x + y)(7, y)
Currying
Sketches:[x -> [y -> 2 * x + y]] [x -> y -> 2 * x + y] [x y -> 2 * x + y] fn x => fn y => 2 * x + y fn x y => 2 * x + y
No comments:
Post a Comment