Functions that Return Functions
Before we can collapse those eight operator rules, we need to solve a practical problem.
A curried add looks like this in our language:
["add", "=", ["lambda", "x", ["lambda", "y", ["x", "+", "y"]]]]
Calling it means two nested calls: first ["add", 2] returns a new function, then we apply that to 3:
[["add", 2], 3]
But the old call rule couldn’t handle this. It expected the function position to always be a name like "square" — it would look it up directly. Here, the function position is ["add", 2], which is itself an expression that needs to be evaluated first.
The New Call Rule
The match library now passes you the raw expressions: fnExpr (the function position) and argExpr (the argument). Your job is to:
- Evaluate
fnExpr— this might be a name like"square", or a nested call like["add", 2] - The result is a function object. Check what kind:
- A lambda (has
paramandbody) — bind the parameter withset, then evaluate the body - A native function (has
native: trueandfn) — callfn.fnwith the evaluated argument
- A lambda (has
- Return the result
NOTE
The operators +, -, *, /, <, >, ==, != are now pre-defined as native curried functions in the environment. Calling [["+", 2], 3] should return 5.
Write the call rule to handle both kinds of functions.