4 ms·
Go's "good, pragmatic engineering" solution to the problem - lightweight threads, channels, and the communicating sequential processes model - is built on the b
by rntz 12y ago
Go's "good, pragmatic engineering" solution to the problem - lightweight threads, channels, and the communicating sequential processes model - is built on the back of decades of academic research, including programming languages research.
And now for some computer language geekery:
Go solves one "code color" problem (concurrency/asynchrony), by hard-coding the solution into the language. Go programs are written in a particular monad (the "Go" monad, if you will), and so have one color. Indeed, monads originally arose in the study of the semantics of imperative languages; to be imperative is to be inside a particular monad. This is exactly the "async monad spreading through your code" problem taken to its logical conclusion: just put everything in the same monad!
This hard-coding solution has very concrete advantages. For one, you don't need to think about separate colors and how to transition between them, combine them, define them, etc. (IOW, monads are complex; by picking one, you reduce cognitive load.) For another, it's easier to optimize your implementation and tooling for that monad (lightweight threads, useful tracebacks).
But PL academics aren't satisfied with this solution, because it only solves one color problem, and it solves it non-composably: you can't put the solution in a library, you have to invent a whole new language for it. That's the holy grail (some) PL research is chasing. It's a question of concrete benefits in the here-and-now versus abstract benefits in the hopeful-future. But it pays to remember that today's concrete benefits are yesterday's green-field research.
- Nitramp 12y agoIndeed, Go only solves one problem by baking it into the language/runtime, it doesn't have a generic mechanism to solve similar problems. But my point is that it solves the problem much better than monads do - in particular if you don't just look at the syntax/user interface level, but at the non-functional aspects, like debuggability, performance, etc. I remember a time when Aspect Oriented Programming was all the rage, with point cuts etc to capture cross-cutting aspects of your program. AOP is certainly less generic than monads, but even with rather specialized tools, it turns out the two "killer apps" of AOP were much better served by runtime support in the VM (logging/debugging) and explicit code (transactions). I'm skeptical about the holy grail that you describe. I see how it's attractive, but in my work experience, the pragmatics of solving a particular issue often turn out to be harder (sometimes much) than the theoretical aspects. There's certainly influence from more theoretical research in all we do in CS, but for example with Go, it's only based on Hoare's CSP model in the most abstract sense, and its implementation of lightweight threads, its stack model etc are definitely in the domain of clever engineering, not breakthrough research.
- jerf 12y ago"AOP is certainly less generic than monads, but even with rather specialized tools, it turns out the two "killer apps" of AOP were much better served by runtime support in the VM (logging/debugging) and explicit code (transactions)." Indeed... beware the tech promoted with the same example over and over again. That's a huge red flag.
- chriswarbo 12y ago> This hard-coding solution has very concrete advantages. True, but you missed the major disadvantage of doing everything in a monad: there may be horrible side-effect demons lurking in every line of code! In my experience, the most egregious offenders are shared mutable state (AKA multithreading) and exceptions. Introducing multithreading or exceptions into an application which previously shunned them feels like switching to a whole different language; one where all our intuitions and guarantees can be undermined at any time.