6 ms·
We can massively generalize this by calling "blue" "pure" and "red" "impure". The end result is essentially Haskell (but you can take it much further, too!). -
by tel 12y ago
We can massively generalize this by calling "blue" "pure" and "red" "impure". The end result is essentially Haskell (but you can take it much further, too!).
---
There's something horrifyingly restrictive about having merely (blue -> pure, red -> impure), though. All "blue" functions behave roughly the same (e.g., very, very nicely and compositionally) but "red" functions come in many classes: async, stateful, exception-throwing, non-deterministic, CPS'd, IO-effectful, combinations of the prior.
What we want is a nice way of representing different kinds of red functions and how they all interact.
What we'd also like is a nice way of composing different kinds of red functions so that the bundled piece has a sensible kind of redness too and we can keep composing.
And this is exactly monads and monad transformers.
There are other ways to achieve this end as well all under the general name "Effect Typing". Very cool stuff.
But what I'd like to emphasize is that Java/C#/Go have not solved this larger problem. They each introduce a fixed number of "rednesses" and very specific ways that different kinds of red can be connected together. Monads are a generalizable solution.
The situation is exactly the same as HOFs themselves. We've had subroutines and functions for a long time, but first-order and higher-order functions are a marked increase in power since you can now refer to these "function things" directly.
Monads take the notion of "CPS Transform" and allow you to refer to it directly, to mark sections of code which use it and compose them intelligently. They allow you to invent your own kinds of redness on the fly and ensure that your custom colorations compose just as nicely as the built-in ones.
If this article is even slightly interesting then you owe it to yourself to learn much more about effect typing. It'll change your world.
(That and sum types, because nobody is served by a bunch of integers named Token.LEFT_BRACKET.)
- munificent 12y ago> We can massively generalize this by calling "blue" "pure" and "red" "impure". The end result is essentially Haskell (but you can take it much further, too!). Yes, I wish I'd taken the time to work more Haskell into the post but this thing has been marinating on my hard drive for months and I wanted to just get it done before the Superbowl ended and the wife and kids got home. > (That and sum types, because nobody is served by a bunch of integers named Token.LEFT_BRACKET.) What said it was an integer? ;)
- tel 12y ago> What said it was an integer? ;) Ha, well, totally fair. But, as long as this watercooler language is essentially "Javascript++", I'm not going to let it get away ensuring sum types are bolted on :)
- pron 12y agoUnfortunately, monads are a bad way of encapsulating and controlling effects. Effects are the most important -- and most bug prone -- of any interesting software aside from compilers, and monads take this central element and make it un-composable. This is why I don't like the current advanced type systems: they help most where they're least needed (the relatively bug-free portions of the code, namely data transformations), and don't help -- interfere, even -- where they're most needed. Effect systems -- if we can get them right and easy to use -- will be a great help. In the meantime, some of the most production-ready effect systems (though they're not general, but have to be built ad-hoc for a specific use) can be found in Java 8's pluggable type systems provided by the Checker framework[1]. It's got a rudimentary lock-use effect system and a GUI effect system (plus some other cool type systems, like physical units, immutability, security and even a linear type system for aliasing). [1]: http://types.cs.washington.edu/checker-framework/current/checker-framework-manual.html http://types.cs.washington.edu/checker-framework/current/che...
- dragonwriter 12y ago> Effects are the most important -- and most bug prone -- of any interesting software aside from compilers, and monads take this central element and make it un-composable. Can you elaborate on this? Because, AFAICT, the big selling point for monads for dealing with effects is precisely composability.
- jallmann 12y agoMonads themselves are composable via bind, but the values encapsulated by the monad are not. Consider there is no real converse to the return operator: once something has been wrapped by a monad, then it is forever stuck in that monadic world. That can be rather annoying, because in languages such as OCaml (not sure about Haskell &c), monad-like interfaces are a convenient abstraction, yet using them leads to highly idiosyncratic code. Rather similar to the sync/async, red/blue distinction in the original article.
- dragonwriter 12y ago
- Nitramp 12y agoEffect Typing and Monads are yet another colour for the lipstick you put on the pig. You still have non-composability (i.e. the async monad spreads through your code), you still have the complexity, you still don't have proper tracebacks without special runtime support, and you still have the inefficiency that Bob didn't actually mention (unwinding all those stacks all the time). Languages with threads (Java, C#) don't quite solve the problem as their threads have other disadvantages, e.g. creating too many threads causing contention, though it's much less of a problem than people make it to be. Go actually completely removes the problem - you don't get a nice tool to pack the problem into boxes more easily, you don't get a different fancy colour for your lipstick, you just don't have the problem at all - you wouldn't know it existed was it not for those other languages. There might be a deeper lesson here about good, pragmatic engineering vs awesome computer language geekery.
- Guvante 12y agoGo seems to have solved the IO problem, but what about the general asynchronous issue? How do you handle calling a function several thousand times on dozens of threads and combine the results?
- rco8786 12y agoIs there any reason you couldn't just spin up so goroutines to do this?
- Guvante 12y agoTelling a hundred threads to do work is easy, figuring out how to sync all of the answers is the hard part. I am not saying you can't pull it off, but the proposed solution doesn't simplify the complex part of those operations.
- the_af 12y agoHow does Go solve "the IO problem"? (Probably what I want to ask is: which IO problem does Go solve? It can't be the one about purity and side-effects, and if it doesn't solve that...)
- deleted 12y ago[deleted]