I don’t know a lot about Haskell or pure functional programming. Composing entire programs sounds really desirable though, and while imagining what that would look like I came up with this:<p>Suppose we had a runtime comprised of objects, and execution was represented as messages sent between objects, as in Smalltalk. Unlike Smalltalk, however, objects would never be created or destroyed.
All of our program’s logic and behavior would be represented as a pure transformation on every message between objects.
In pseudo-Haskell:<p><pre><code> -- A message is a receiver identifying an object, like “Program”, and a selector, perhaps containing data
myProgram :: Msg -> Msg
myProgram (Program {begin}) = Window {createWindowWithName="myWindow"}
myProgram (Program {windowCreatedWithName=name}) = (Window {windowWithName=name, setTitleTo="Hello world"})
myProgram (Program {windowWithName=name, didChangeTitle=title}) = (Console {print=title})
myProgram msg = msg
</code></pre>
Here the runtime begins execution by trying to send the message [Program begin], but myProgram([Program begin]) evaluates to [Window createWindowWithName:"myWindow"], so that is sent instead. The “Window” object, when sent [Window createWindowWithName:String], both puts a new window on the screen, and sends the message myProgram([Program windowCreatedWithName]), and so execution continues.<p>It would be easy to compose programs written using this paradigm, and not hard to imagine what composition of executable programs would mean. For example, to log the name of every window created to the console:<p><pre><code> logWindowName :: Msg -> Msg
logWindowName (Program {windowCreatedWithName=name}) = Multicast {messages=[Program {windowCreatedWithName=name}), Console {print=name}]}
finalProgram = logWindowName . myProgram
</code></pre>
(Here “Multicast” is supposed to be an object that can take several messages and, with no notion of order, send them out all at once.)<p>We could add yet another object representing mutable state, with messages describing changes to it and responses containing data stored there. Without using something like this to explicitly model it, I don't see any explicit sequencing of instructions as in the IO monad.<p>Are there obvious problems with this approach, or has anything very similar been tried?