Apologies if this has been considered above already (this is a very long thread and I am still working my way through it)
Have we considered just keeping a stack of some common currency type (for a particular builder), and then passing each statement to a build function which transforms it to that common currency type and places it on the stack. If we have each build function take the stack inout, then optimizations should still be possible.
This should have several advantages:
- You should be able to use normal control flow (skipped expressions just won't have a chance to alter the stack)
- You don't run into the same 10 children are ok, but 11 are not problem (without needing variadic generics)
- You should be able to type check each expression individually (based on whether there is a matching build function for that expression)
- Build functions can make optimizations as they go by looking at the stack
- It still allows arbitrary nesting