We don’t support first-class functions very well. Really, we only support lambdas. We’d like to support first-class functions, and need to change the language to do it
5 |> Ok)let x = Int.add)x 5 6)List.map [...] increment)let x y z = …)let x = Result.Ok; x 5)let add5 = Int.add 5)let main () =
let doThing = \\var -> ... // lambda
List.iter listing doThing
When parsed to ProgramTypes.Expr:
ELet ("doThing", ELambda (["var"], ...),
EFnCall ("List.iter", [EVariable "listing"; EVariable "doThing])
doThing is a variable containing the lambda value
This uses
type Expr = // ProgramTypes
...
| ELambda of id * List<id * string> * Expr
| EFnCall of id * FQFnName.T * typeArgs : List<TypeReference> * args : List<Expr>
When converted to RuntimeTypes.Expr:
ELet ("doThing", ELambda(["var"], ...),
EApply (FnName("List.iter), [EVariable "listing; EVariable "doThing"])
Which is defined as
type Expr = // RuntimeTypes
...
| EApply of id * FnTarget * typeArgs : List<TypeReference> * args : List<Expr>
| ELambda of id * List<id * string> * Expr
and FnTarget =
| FnName of FQFnName.T
| FnTargetExpr of Expr
When evaluating ELambda in the interpreter, we get:
DFnVal(Lambda { symtable = st; parameters = parameters; body = body })
DFnVal is:
and LambdaImpl = { parameters : List<id * string>; symtable : Symtable; body : Expr }
and FnValImpl = Lambda of LambdaImpl
and dval =
...
| DFnVal of FnValImpl