7 ms·
Here's a minimalistic way to resolve this. First let's observe that Option and Result types can be roughly generalized by lists. Option is just a list of lengt
by snidane 7y ago
Here's a minimalistic way to resolve this.
First let's observe that Option and Result types can be roughly generalized by lists. Option is just a list of length 1.
Next, make a language where each function returns a 'list of equation solutions'. This handles cases when there are no solutions as well as cases when there are multiple solutions:
sqrt(-2) -> []
sqrt(0) -> [0]
sqrt(4) -> [2, -2]
4/2 -> [2]
1/0 -> []
fibs(5) -> [0, 1, 2, 3, 5]
idx_of(0, [1, 0, 0, 1]) -> [1, 2]
webserver(reqs...) -> resps...
Instead of lists, streams of results can be produced lazily as the algorithm progresses to successively finds solutions.
What always puzzled me was the disconnect between pure functional programming and theoretical computer science, both obsessed with functions, compared to real life computing where it is all about having a 'function' which consumes some stream of inputs and produces another stream of outputs. In many cases the streams are unbounded (servers) - which is contrary to terminating functions.
I wonder why we keep implementing languages with functions as primitives when we should have iterators, generators and stream transformers as primitives somehow instead.
Also IO monad in pure functional languages feels like just a hack around functions not being able to capture streaming nature of real world problems.
- wnoise 7y agoIt's because corecursion is harder to reason about than recursion, requiring a slightly different set of fundamental tools and vocabulary, which aren't taught, because it would have to be on top of the current set.
- eximius 7y agoThis demonstrates how to represent a failed computation (empty list), but doesn't show how to distinguish a failed computation and a successful one with no solution. Or how to represent errors. What does Result look like?
- kmill 7y agoThat's known in Haskell as the List monad. There's a function to transform Maybe (like Rust's Option) to lists. In Haskell, lists can be infinitely long. Regarding the IO monad, Simon Peyton Jones has an article explaining why they went with that rather than streams. Sadly I don't remember what it was, but it had something to do with proper interleaving of input and output. (Btw, in a way, the IO monad is a stream of commands to the RTS.)
- heavenlyblue 7y agoThat will just make all of the logical mistakes you make in your program return an an empty list. We keep implementing languages this way because it solves our problems; not the problems of architectural astronauts.
- chowells 7y agoYou were scooped in 1985... https://link.springer.com/chapter/10.1007%2F3-540-15975-4_33 https://link.springer.com/chapter/10.1007%2F3-540-15975-4_33 Note that Philip Wadler was active in the Haskell committee. Early versions of Haskell did use a system like that. It was too error-prone. Monadic IO turned out to be theoretically equivalent, but without the easy ways to break it. See https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/history.pdf https://www.microsoft.com/en-us/research/wp-content/uploads/... for more details.