Earlier quoted context omitted.
Effect 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…
Go 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?
What Color Is Your Function?
81–90 of 153 posts
Re: What Color Is Your Function?
#82I don't get it ... But hey, it took about six month for me to figure out how to write asynchronous JavaScript ... The key is to not use anonymous functions, it will flatten out the "Christmas tree" of callbacks. And it makes it possible to read what the code does, or at least what the programmer wants the code to do. It's much better then "then", then what, but, then, why complicate things when it's actually possible…
Re: What Color Is Your Function?
#83Earlier quoted context omitted.
Thank you! I know the reader's time is precious so I try to cram as much entertainment and information in there as I can.
Spidermouth the Night Clown will stay with me for years.
Re: What Color Is Your Function?
#84Earlier quoted context omitted.
Effect 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…
Go 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?
Re: What Color Is Your Function?
#85His solutions is threads ? Really? Has he read no history? There are problems with threads. That's why async I/O is hot right now. Threads is a limited resource. Threads are expensive to create and dispose. Context switches are espensive. Threads must be synchronized. Threads can have race conditions. Good rant, but I didn't expect him to serve such a shallow conclusion after a solid and insightful introduction.
His solution isn't raw OS-level threads. Thread semantics are the solution. It could be greenthreads that all run within the same OS-level thread. Basically, when a function A calls function B, if function B blocks it blocks function A as well. The entire stack blocks on whatever it going on the top frame. I've wondered that myself. node-fibers basically does this, but for some reason it's pretty hated in the JS worl…
Re: What Color Is Your Function?
#86We 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, except…
Effect 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…
I'm not claiming that you must program in a language which distinguishes lipstick colors. I'm merely claiming that you can and that it's a valuable tool.
To respond to your concrete criticisms:
The non-composability you refer to is actually what I call composability itself. You want the isolation of effectful worlds so that you have different things to choose to compose in the first place. You can do this "horizontally" with binding or "vertically" with free products or lifting (or any number of other techniques). Without this distinction things "compose automatically", but only because you've decided to mix all of your colors and go with brown.
Proper tracebacks and stack unwinding can be a problem, but fundamentally these are problems of how you compile/interpret languages like this instead of semantically whether these languages allow you to express what you would like to at high fidelity. Both of those problems can be addressed, though. The degree to which they're painful in practice is also a question.
The comment about threads is somewhat off topic. There's nothing in what I was saying which precludes the introduction of nice green threads and competitive scheduling. You can implement Go in Haskell quite neatly, for instance.
But yes, I agree. If your problem is pure multithreading then languages like Go and Erlang make it go away completely. They do so by collapsing layers of semantics down to a single one (completely antithetical to the red/blue distinction here) but choosing one such that multithreading is nice.
This can be an excellent spot in solution space for many problems. I would never suggest otherwise.
But as long as we're ostensibly on the topic of "blue/red"-ness of your language then it's high time to talk about effect typing.
Re: What Color Is Your Function?
#87StratidiedJS completely eliminates the sync/async distinction at the syntax level, with the compiler/runtime managing continuations automatically. A `map` function in SJS works just like you would want, regardless of whether the mapping function is synchronous or not.
In addition, it provides _structured_ forms of concurrency at the language level, as well as cancellation (which most async APIs don't support).
Disclosure: I work on StratifiedJS, and just wish more people knew about it.
Re: What Color Is Your Function?
#88Earlier quoted context omitted.
> 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.
I think the point is that there is no good effect-union type; this has to be pieced together with monad transformers where you might have that types "Atransformer (Btransformer C)" is not equal to "Btransformer (Atransformer C)". This is, for example, why Haskell has one monolithic "IO" monad instead of one for hitting the filesystem, one for HTTP requests, one for IORefs, etc. Haskell does not, for example, represen…
Re: What Color Is Your Function?
#89You can always make a function that sync all async operations: sleep until a global variable is changed by the callback. A pain, but still not that bad.
Yes, I've used a similar technique myself; however I consider it only a last resort. But doesn't that require your language to have threads? Is it possible to do this in eg. Javascript?
Re: What Color Is Your Function?
#90Remember in the early 90s when Windows and Mac OS were "cooperatively" multitasked? Which is to say, you had to explicitly yield to allow other applications to run (or risk locking up the entire system). And then it was replaced with pre-emptive multitasking, which allowed the scheduler to figure out what process deserved CPU time, while allowing the programmer not to have to think about it. You could call a blocking IO function, and the OS would just go do something else while you waited.
All this "async" stuff seems like a return of cooperative multitasking, only worse. Not only do I have to explicitly yield, but now it's to some event loop that can't even properly use multiple cores, or keep a coherent stack trace. It's a nightmare to debug. It's theoretically fast... except if one request forgets to yield, it can clog up the entire thing. I guess you use multiple processes for that and a dispatcher, but at that point you've basically reinvented preemptive multitasking... badly.
Threads aren't perfect, but excluding STM and actor models they definitely suck the least.