Add support for true higher-order builtins
Once pattern matching builtins land (see this for a detailed description) we'll be able to return an iterated application from a builtin. Unfortunately, that still doesn't enable us to have higher-order builtins that compute functions supplied as arguments. A prime example of such a builtin is unionWithBSMap, a Plutus version of
The usefulness of such a builtin was discussed here.
So let's say we had the following built-in type:
data T a = B a | L
how would we implement zipWithT such that
zipWithT addInteger (B 1 (B 2 L L) L) (B 3 (B 4 L L) L)
computes to B 4 (B 6 L L) L?
One thing we could try is to do a similar thing to pattern matching builtins and return an iterated application where
(1) the spine is the parts that need to be computed on the Plutus side
(2) the head is a BuiltinRuntime constructed on the fly that expects computed terms from (1) to get fed back into the builtin
Denoting (2) in braces, we get something like this:
headSpine {\x y -> B x (B y) L L} [headSpine addInteger [1, 3], headSpine addInteger [2, 4]]
Here the spine is
[headSpine addInteger [1, 3], headSpine addInteger [2, 4]]
which computes to [4, 6]. And the head is
{\x y -> B x (B y) L L}
which is pseudocode for a BuiltinRuntime expecting two arguments and producing the final result.
You can think of this as adding support for built-in functions that return other built-in functions with some computations being cached inside.
To be continued.