try·st·imu·li

13.79965

so i’m playing with a virtual machine idea based on closures. basic idea is that each procedure takes a fixed number of inputs, and a call either adds insufficient inputs and so returns a new closure or adds enough inputs and so invokes the procedure (which returns whatever it returns).

all the actual procedures can do is call closures. they take values from one of two lists, a static one that’s part of the definition of the procedure, and a dynamic one that starts out as the values given to the closure and is where the values returned from the calls go.

this alone can do everything lambda calculus can do (if you only ever return one value it is just an evaluation strategy for lambda calculus). booleans and numbers and all can all be defined in terms of closures. though practically i think they’d usually be builtin. i have a few open questions though:

what should happen if a closure is called with more values than it needs?

  • error
  • silently discard them
  • implicitly call the returned value

i am trying to think of a way to get this last option, in combination with multiple return values to implement n-ary addition. i guess it could call the last output of the procedure with the procedures outputs (except the last one) followed by the extra inputs. so + 1 2 3 returns 3 + which becomes + 3 3 which returns 6 + to the caller (which might only accept one value, and so drop the +). all in all though, it may be better to just error.

what should happen if a builtin value (not a closure) is called?

  • error
  • returns nothing
  • make each type act like a closure that operates on a value

somewhat fond of the last option here (because i like lambda encodings). in particular for booleans - both take two inputs and return one, false returns the first and true returns the second. there are some advantages there in terms of flexibility about what gets integrated into the core runtime and what is implemented inside the virtual machine. but not having type errors may make debugging harder? and what does a builtin do if it’s handed something completely inappropriate - emulate the floating point logarithm of λx.x base 'hello' based on how the equivalent closures would interact?

published