> The calls are not yet made—we’re only building a blueprint of those calls:<p><pre><code> <alert>
<concat>
Hello,
<prompt>Who are you?</prompt>
</concat>
</alert>
</code></pre>
> This blueprint of “potential calls” looks code, but it acts like data. It’s structurally similar to function calls but it is more passive, inert, open to interpretation. We’re yet to send this blueprint to the other computer which will actually interpret it.<p>You've reinvented Free Monads: <a href="https://www.haskellforall.com/2012/06/you-could-have-invented-free-monads.html" rel="nofollow">https://www.haskellforall.com/2012/06/you-could-have-invente...</a><p>That article is a bit dense if you're less familiar with Haskell, but the basic idea is that you can write code that looks like:<p><pre><code> do
name <- prompt "Who are you?"
message <- concat "Hello, " name
alert message
</code></pre>
And what actually gets assembled is something resembling a syntax tree of operations, waiting to be interpreted.<p>You could interpret it locally, or have the interpreter send requests to another computer. And (if such are your desired semantics) the interpreter can short-circuit the whole thing and return an error message if any step fails - similar to how you describe these as being "potential function calls", i.e. calls which as of yet may or may not successfully execute.<p>Analogously, JavaScript already has a monad-like construct which can achieve something similar:<p><pre><code> async () => {
const name = await prompt()
const message = await concat("Hello, ", World)
const result = await alert(message)
return result
}
</code></pre>
But this is pure code, rather than data that can be interpreted in a custom way - it will always be "interpreted" by the runtime itself. The Haskell example is somewhat of a blend between data and code (it desugars to a tree of closures calling each other in sequence, which you have a lot of control over the execution of).<p>Your React-style example attempts to make this concept into pure data. Though in some ways, a DSL becoming pure data wraps around and becomes pure code again. You need to parse it, semantically analyze it, and then execute it - in other words, you've invented a compiler.