There is a moderate amount of dissatisfaction with Code[T]. I think there are 2 essential issues:
- The need to split up large functions creates a lot of complexity in the emitter. The solution is to hide function splitting inside Code. This doesn’t require an interface change but is involved.
- Code[T] looks like a value of type T, but isn’t. Sometimes you want to be able to refer to values.
I also think code should be emitted in a stateful way. This is the classical design. Therefore, I propose the following:
There are actually two types of values in JVM worth distinguishing: simple or primitive values like constants, variable reads, etc. and large, complex compound (but functional) computations that produce a value. The latter thing you probably don’t want to duplicate in the code, and there’s no point in memoizing something like like the former. This, Code[T] becomes SimpleValue[T] and Value[T] for non-statement code.
For statement code, I want something like
cb: CodeBuilder which builds up code via a series of emit statements:
cb.emitGoto(L) cb.emitTarget(L) cb.emitInvoke(...) cb.emitIfX(...) cb.emit(v)
v: (Simple)Value[T] emits the code for the value computation. CodeBuilder would also force the existence of a context that could support things like memoization. Memoization would return, and be idempotent, on SimpleValues.
CodeBuilder feels like a significant change, so I propose as an intermediate step Code[T] becomes Code (no type parameter) for statements (Unit value), and we continue to build up code blocks functionally. So the above code looks like:
Code( Code.goto(L), Code.target(L), Code.invoke(L), ...)
In this design with Code, EmitTriplet becomes:
case class EmitTriplet[T]( val setup: Code, val m: Value[Bool], val v: Value[T]
Eventually, with CodeBuilder in the context, it just becomes EmitValue with m and v.
With a backend that automatically splits large functions, I think this will allow us to clean up higher levels of the code.
edit: I would appreciate feedback from people in the Code trenches on this.