What color is your function? (2015)
tosh
114 points
140 comments
May 26, 2026
Related Discussions
Found 5 related stories in 91.8ms across 8,541 title embeddings via pgvector HNSW
- Apple CMF (Color-Matching Functions) 2026 HeyMeco · 37 pts · April 28, 2026 · 49% similar
- Show HN: What's my JND? – a colour guessing game Keithamus · 40 pts · March 10, 2026 · 48% similar
- Stop Using Grey Text (2025) catskull · 59 pts · March 05, 2026 · 41% similar
- Why So Many Control Rooms Were Seafoam Green (2025) Amorymeltzer · 11 pts · March 25, 2026 · 41% similar
- Is my blue your blue? theogravity · 436 pts · April 27, 2026 · 41% similar
Discussion Highlights (17 comments)
frankfrank13
My first ever EM showed me this piece ~10 years ago, and I still think about it a lot. One pattern I've adopted is to keep as much code to be synchronous as possible. On larger teams, especially when the slop-cannon is really going, I can at least depend on codeowners to tag me if someone tries to convert something to async (eg. adding a DB call somewhere), because they chain of things that need to be converted to async is so long. Then I can jump in and say "this entire chain of code is sync, if you want a DB call, do it somewhere else"
nickcw
Go doesn't have colored functions due to its nice fat runtime hiding all the async magic away for us. That makes it a pleasure to code concurrent stuff for IMHO. It does have its own similar problems though - does a function return an error? If so you are going to need to plumb the error return through all the callers. Does a function need a context.Context? Ditto. I guess you can't win them all :-)
preommr
> You still can’t call a function that returns a future from synchronous code. (Well, you can, but if you do, the person who later maintains your code will invent a time machine, travel back in time to the moment that you did this and stab you in the face with a #2 pencil.) Author makes up a lie. Then lampshades it away with a colorful non sequitur. --- The alternatives that people praise like golang, have other tradeoffs that are much worse because the async logic is now implicit. Your entire codebase is now a surface area that is at risk of being blocked by waiting on a channel; the the mitigation of this is through responsible use of coroutines, but then you're right back around to extra information about your code that is analogous to colring, except not as explicit as async/await.
satvikpendem
We need algebraic effects in more languages, this solves the function coloring problem. OCaml 5 has them and it seems to be doing quite well, combine that with the semantics of the borrow checker in the form of OxCaml and we might just have an ideal language. I'd like to see algebraic effects in Rust as well but sadly it seems their keyword generics initiative is languishing. Related, one of the former React maintainers wrote a primer on algebraic effects that's a good read: https://overreacted.io/algebraic-effects-for-the-rest-of-us/
bre1010
I wish the key word was instead dontawait and was used inversely to how await is used. 99% of the time I'm using an async function, despite however slow it is, there's nothing for my code to do but wait for it to finish. But if for some reason I would like the next line of code to run before the current one is done, I'll let you know . Like, why can't my sync function await something asynchronous? If it has to lock up the whole thread while that function executes, that's fine because that's how it was going to work anyway 99% of the time
gnarlouse
> Spidermouth the Night Clown Thanks for my next horror shortfilm plot. Twist: he's the protagonist
qihqi
Colored functions are good. It reflects the language design on signaling what is important, and what are the properties it want the writer to pay attention. Other examples of colored functions: * Haskell: pure function and non-pure (IO monads) looks different. * Rust: unsafe functions (or block) requires special markers.
rendaw
I really don't like this article. It has a catchy, profound-sounding title that people bandy about to argue against stuff they don't like. All functions, even non-async functions, are colored. In any large system codebase you'll have functions that can only be called in certain situations, with the right setup, whatever, and if you're lucky this is communicated by types but regardless those restrictions can't be avoided. It's easy to call low-restriction functions from high-restriction ones and not the other way around. Furthermore, it's not like the alternative to explicit await doesn't have issues too (that the article doesn't mention). There is inherent complexity, it's a tradeoff, you can't just syntax it away.
wesselbindt
I feel like this argument always boils down to explicit vs implicit. It tastes the same as static vs dynamic typing. Personally, I fall well into the explicit camp. I like when I can know stuff about a function without having to read its body, and the bodies of the functions it calls, and the bodies of the functions they call, and so on. And so, I like when I can see from the function signature that it returns an integer, or when I can see from the function signature that it might do IO. This comes at a cost, namely that of reading five extra characters in a function signature, and I could kind of imagine (truly!) how that gets in the way for some people. There is a cost of writing the five characters as well (and like the author mentions, in a poorly designed codebase, this may have to go down the call stack), but code is read more often than written, so in a sense this is negligible. Like the dynamic vs static typing debate, I feel like this ultimately boils down to context and personal taste, and some amount of intelligence as well. I'm impressed by the amount of stuff the dynamic typing / non-async crowd is able to keep in their working or long term memory while coding. I don't have that kind of mental bandwidth, sadly. Having said all that, this argument is disingenuous in that it completely ignores the fact that the async keyword tells you something useful (rather than some made up nonsense like color), and most of the argument basically boils down to "if you ignore the benefits, this syntax has no benefits", and I really don't respect that as an argument.
viktorcode
If I understand correctly, Go language praised in the article still has red and blue functions, only now they the colours are handled implicitly, and you as a programmer reading the code will have harder time guessing which is which on the call site.
fastforwardius
Having functions literally color coded based on type would be nice improvement.
wasmperson
IMO the function coloring problem was solved with async/await. This article was posted before Javascript's async/await syntax cleaned up that ecosystem, so the author is only guessing when they say it doesn't fix the issue. It did fix the issue, and now function coloring isn't really a problem. If async/await doesn't solve the coloring problem, then neither do threads. Why would you ever need to start a thread to invoke a function when you could just invoke the function directly? Because the function is a red function.
slopinthebag
I've exclusively used async/await style languages for my entire life and have not once ran into this supposed problem of function colouring. Basically all IO/async work you do requires a context, does it matter if that context is a parameter or a keyword? I don't think so. The author is inventing a problem to rant about.
overgard
I think a few things are simultaneously true here: 1. async/await is a huge improvement over callbacks. 2. doing asynchronous programming through callbacks has always been a messy hack, primarily coming from languages that couldn't/wouldn't do real concurrency in their runtimes and async/await just papers over it without fixing the fundamental problems 3. threads are a lot more elegant from a language design standpoint and a lot more powerful, but.. 4. .. I would much rather fuss with what color my function needs to be than deal with the average concurrency bug that results from threads.
darepublic
I believe I remember reading this back at the time of release. Incredible how far we've come from there
Yokohiii
Apparently this comment section...has color.
capl
will always upvote this post when I see it virtual threads (stackful coroutines) in Java is most of the reason why I’m defaulting to it nowadays instead of C#, Rust, etc