Short in-line definition of functions, similar to Python.
Module Status: Experimental 2020-10-31.
local Lambda = require('__eradicators-library__/erlib/lua/Lambda')()
|Lambda-todo5||implement multi-argument say()|
|Lambda-todo5-todo6||implmenent and use Memoize for get_loader and __index|
|Lambda(spec[, ...])||The only function of Lambda is itself.|
|LambdaFunctionSpecification||A string that Lambda parses into a function.|
- implement multi-argument say()
- implmenent and use Memoize for get_loader and __index
- Lambda(spec[, ...])
The only function of Lambda is itself. Calling it will generate the
specified function. If any upvalues are given they will be available
from within the lambda function via the capital letter A,B,..,Z in
the order they were given. No other functions or values are otherwise
usable from within a Lambda function.
Lambda function without upvalues are only generated once for every LambdaFunctionSpecification after which the result is cached forever. You can directly call the cached function by indexing Lambda instead of calling it. It will be transparently generated if it's the first time you call it. This is the fastest and most readable way to use Lambda functions, but you can not supply custom upvalues this way.
If you want to use a Lambda function with upvalues you should store it somewhere. Lambda does cache some intermediate generation steps but the final resulting closure is unique for each call.
- spec LambdaFunctionSpecification
- ... AnyValue Upvalues. Accessible as A,B,...,Z (optional)
-- Let's say you want to multiply a number. local f = function(x) return 2*x end -- You can now write that shorter. local f = Lambda('x: return 2*x') -- And shorter. local f = Lambda['x->2*x']
-- You can use multiple arguments. local f = Lambda['x,y,z->2*x+y*z']
-- Or fixed upvalues. local f = Lambda('str->str..A..B','wordA','wordB') local s = f('wordC') print(s) > wordCwordAwordB
-- Use it when you don't want to store the function. print(Lambda'x->x..x'('once')) > onceonce
A string that Lambda parses into a function. It consists of
- head A comma seperated list of arguments that the Lambda should take.
- divider A ":" colon marking the end of the list of arguments or a "->" single arrow marking the end of arguments and simultaenously the beginning of the return values.
Everything after the divider. If the body contains a "=>"
double arrow then everything after that arrow is considered to be
another Lambda function call.
Note: Lambda-nesting with "=>" is an experimental feature subject to change.
-- When you make a call... Lambda('head: return body+A+B',UpValA,UpValB) Lambda('head-> body+A+B',UpValA,UpValB) -- ...this is the closure that Lambda will return to you. local A,B = UpValA,UpValB return function(head) return body+A+B end
-- Nested Lambdas are a bit more complicated... Lambda('head: head = head+1 => "hair -> hair + A ",UpValA2',UpValB) -- ...and produce this: local A = UpValB return function(head) head=head+1 return Lambda("hair -> hair + A",UpValA2) end -- Beware that the second Lambda function will *never* see -- the upvalues of the first one. Even if it has no upvalues itself. -- You must pass them on manually.