I’ve started poking around at connecting Radian to LLVM. The current backend translates the flowgraph to a linear intermediate code, then translates the LIC instructions to C source code, then passes that through gcc to get machine code. I’m not sure whether to leave the LIC pass in place, then convert to LLVM instead of C source code, or to emit LLVM IR from Radian’s data flow graph. The significant semantic difference is that LLVM IR includes type information, which is implicit in LIC.
While I think about this, I’m playing around with using Church encoding for booleans. Instead of including a “boolean” data type with two predefined values which represent true and false, then implementing a “branch” operation which chooses between two values based on a boolean value, true and false themselves become the implementation of the branching operation. It’s as though they were defined like this:
function true(thenclause, elseclause) = thenclause
function false(thenclause, elseclause) = elseclause
If you have a reference to one of these functions, you can use the function itself to perform the branch: you just call the boolean value, passing in the option you want to use for “true” and the option you want to use for “false”, and it returns the one that matches the boolean’s value.
This wouldn’t be appropriate in every language, but in a functional language like Radian the only thing you can do with a boolean value is to select which of two expressions you want to use. It makes sense to do away with the custom “branch” instruction and just use function invocation.