What Color Is Your Function? (2015)
journal.stuffwithstuff.com
What Color Is Your Function? (2015)
1–10 of 90 posts
Re: What Color Is Your Function? (2015)
#2Re: What Color Is Your Function? (2015)
#3Re: What Color Is Your Function? (2015)
#4I love this about Go. All functions are simple and synchronous, but if you want to call them concurrently, just "go SlowThing()" and coordinate with a channel. Compare that to the async stuff in C#, Python, etc -- it's bolted on later, and you see double of everything.
None of this is really problematic at the top level view of things. But when you need to compose libraries or applications that make use of these things - yes, even channels in Go - you can start running into problems.
Especially if you don't actually control the process you're running in. This is why promises and async/await really exist. E.g. if you have code you need to fork off the main UI thread so you don't block it, but need to re-capture the UI thread so you can call UI update code when you're done with your long running task. async/await is so much cleaner here.
Async/await allow for much more complex control of flow than simple goroutines and channels. Sometimes it's necessary. Sometimes it isn't. It was necessary in nodejs. It's extremely useful in applications where you have a "main thread" that drives your application that you don't want to unnecessarily block. Go doesn't solve this problem out-the-box. There's a reason why c# adopted async/await despite having futures and all sorts of other tools.
Re: What Color Is Your Function? (2015)
#52018: https://news.ycombinator.com/item?id=16732948
discussed at the time: https://news.ycombinator.com/item?id=8984648
a bit more from the same day: https://news.ycombinator.com/item?id=8982494
Re: What Color Is Your Function? (2015)
#6I love this about Go. All functions are simple and synchronous, but if you want to call them concurrently, just "go SlowThing()" and coordinate with a channel. Compare that to the async stuff in C#, Python, etc -- it's bolted on later, and you see double of everything.
In fact there are not function at all, just like generators are not.
Also coroutines can be called from functions and vice versa. You don't have to choose.
The problem is not the color. The problem is the default paradigm is to be blocking I/O, and you add non blocking on top. It's way easier to make everything non blocking, then add blocking things on top.
It's not a matter of syntax, but of core paradigm.
Go and erlang were designed from the non blocking perspective from the get go.
But even go add to use something to manage async control flow, so it uses channels, which you don't need if you have coroutines.
Erland went deeper and made everything immutable, and baked in actors in the runtime. To me that's more impressive.
Re: What Color Is Your Function? (2015)
#7I love this about Go. All functions are simple and synchronous, but if you want to call them concurrently, just "go SlowThing()" and coordinate with a channel. Compare that to the async stuff in C#, Python, etc -- it's bolted on later, and you see double of everything.
Async def are not colored functions in python. In fact there are not function at all, just like generators are not. Also coroutines can be called from functions and vice versa. You don't have to choose. The problem is not the color. The problem is the default paradigm is to be blocking I/O, and you add non blocking on top. It's way easier to make everything non blocking, then add blocking things on top. It's not a ma…
I might use this test: When I wish to add a call to a function that yields control other than by returning to the middle of a regular function, so that the latter portion of the regular function can use the results of yielding, do I then have to change the function declaration and every single call site?
You clearly disagree. What test should we use?
Re: What Color Is Your Function? (2015)
#8Also one of my favourite points about Elixir/Erlang — having no distinctions between async/await makes programming flow better.
Re: What Color Is Your Function? (2015)
#9Earlier quoted context omitted.
Async def are not colored functions in python. In fact there are not function at all, just like generators are not. Also coroutines can be called from functions and vice versa. You don't have to choose. The problem is not the color. The problem is the default paradigm is to be blocking I/O, and you add non blocking on top. It's way easier to make everything non blocking, then add blocking things on top. It's not a ma…
Can you expand on your notion of what is and is not a colored function? I might use this test: When I wish to add a call to a function that yields control other than by returning to the middle of a regular function, so that the latter portion of the regular function can use the results of yielding, do I then have to change the function declaration and every single call site? You clearly disagree. What test should we…
Coroutines are not functions, they are coroutines. Different primitives.
A function has a single exit entry point and a single exit point and no state. If you call a function, you run its body.
A coroutine has several entry points and exit points, and an internal state. If you call a coroutine, you make an instanciation (the body doesn't run).
You can argue than using coroutine for async handling has drawbacks, but colored functions is not the proper analogy and make people very confused about the whole thing.
The fact the syntax to define them is so similar doesn't help, and I see most people difficulties comming from their attempt to reconciliate models that have no reason to be.
Just like a hashmap and an array are 2 different things despite you can index both, functions and coroutines must be understood as separated concepts.
Re: What Color Is Your Function? (2015)
#10I love this about Go. All functions are simple and synchronous, but if you want to call them concurrently, just "go SlowThing()" and coordinate with a channel. Compare that to the async stuff in C#, Python, etc -- it's bolted on later, and you see double of everything.
You're just using the channel as a future. None of this is really problematic at the top level view of things. But when you need to compose libraries or applications that make use of these things - yes, even channels in Go - you can start running into problems. Especially if you don't actually control the process you're running in. This is why promises and async/await really exist. E.g. if you have code you need to f…