So this is a tangent from the main article, but this comment made me curious and I read the original "What color is Your Function" post.
It was an interesting read, but I guess I came away confused about why "coloring" functions is a problem. Isn't "coloring" just another form of static typing? By giving the compiler (or interpreter) more meta data about your code, it can help you avoid mistakes. But instead of the usual "first argument is an integer" type meta data, "coloring" provides useful information like: "this function behaves in this special way" or "this function can be called in these kinds of contexts." Seems reasonable?
Like the author seems very perturbed that there can be different "colors" of functions, but a function that merely calculates (without any IO or side-effects) is different than one that does perform IO. A function with only synchronous code behaves very differently than one that runs code inside another thread or in a different tick of the event loop. Why is it bad to have functions annotated with this meta data? The functions behave in a fundamentally different way whether you give them special annotations/syntax or not. Shouldn't different things look different?
He mentions 2015 era Java as being ok, but as someone that’s written a lot of multithreaded Java code, it’s easy to mess up and people spam the “synchronized” keyword/“color” everywhere as a result. I don’t feel the lack of colors in Java makes it particularly intuitive or conceptually simpler.
Yes, the main character of that article really is mostly JavaScript. The main issue there is that some things must be async, and that doesn't mesh well with things that can't be.
If you're writing a game, and you need to render a new enemy, you might want to reduce performance by blocking rather than being shot by an invisible enemy because you can only load the model async.
But even the article acknowledges that various languages tackle this problem better. Zig does a good job, but claiming it's been defeated completely doesn't really fly for me.
> He mentions 2015 era Java as being ok, but as someone that’s written a lot of multithreaded Java code, it’s easy to mess up and people spam the “synchronized” keyword/“color” everywhere as a result. I don’t feel the lack of colors in Java makes it particularly intuitive or conceptually simpler.
Async as a keyword doesn’t solve this or make writing parallel code any easier. You can still mess this up even if every function is annotated as async.
> A function with only synchronous code behaves very differently than one that runs code inside another thread or in a different tick of the event loop.
I think this is conflating properties of multiple runtimes. This is true in JavaScript because the runtime works on an event loop. In Java an “async” function that reads from a file or makes an http call doesn’t run in a different threads and doesn’t run in a different tick of an event loop. So what value does it have in that type of runtime?
Personally for me I think “async” is putting pain on a lot of developers where 99% of all code is not parallel and doesn’t share memory.
I believe the point is less about "coloring" not having value as a type-system feature, and more about its bad ergonomics, and its viral nature in particular.
> It was an interesting read, but I guess I came away confused about why "coloring" functions is a problem. Isn't "coloring" just another form of static typing?
It is. Function coloring is static typing.
But people never ever agree on what to put in typing system. For example, Java's checked exceptions are a form of typing... and everyone hates them.
Anyway it's always like that. Some people find async painful and say fuck it I'm going to manage threads manually. In the meanwhile another bunch of people work hard to introduce async to their language. Grass is always greener on the other side.
> But people never ever agree on what to put in typing system. For example, Java's checked exceptions are a form of typing... and everyone hates them.
I love checked exceptions. Checked errors are fantastic and I think most developers would agree they want errors to be in the type system, but Java as a language just hasn’t provided the language syntax to make them usable. They haven’t made it easy to “uncheck” when you can’t possibly handle an error. You have to write boilerplate:
Something s;
try {
s = something();
} catch (SomethingException e) {
throw new RuntimeException(e);
}
It sucks when you face that situation a lot. In Swift this is really simple:
var s = try! something();
Java also hasn’t made them usable with lambdas even though both Scala [0] and Swift have shown it’s possible with a sufficiently strong type system:
> Isn't "coloring" just another form of static typing?
In a very direct way. Another example in languages that don't like you ignoring errors, changing a function from infallible to fallible is a breaking change, a la "it's another colour".
I'm glad it is: if a function I call can suddenly fail, at the very least I want to know that it can, even if the only thing I do is ignore it (visibly).
> Isn't "coloring" just another form of static typing?
Yes, and so is declaring what exceptions a function can throw (checked exceptions in Java).
> Why is it bad to have functions annotated with this meta data? The functions behave in a fundamentally different way whether you give them special annotations/syntax or not. Shouldn't different things look different?
It really isn't a problem. The article makes people think they've discovered some clever gotcha when they first read it, but IMHO people who sit down for a bit and think through the issue come to the same conclusion you have - Function coloring isn't a problem in practice.
> but IMHO people who sit down for a bit and think through the issue come to the same conclusion you have - Function coloring isn't a problem in practice.
I dunno man, have you seen people complain about async virality in Rust being annoying? Have you ever tried to read a backtrace from a program that does stackless coroutines (it's not fun)? Have you seen people do basically duplicate work to maintain a blocking and an async version of the same networking library?
The alternative is to jump through a bunch of hoops to hide the "coloring" behind some opaque abstraction that is complicated and that will still get in the way when things go wrong.
Everyone complained when async IO was done with callbacks, so sugar was added to the callbacks, and now everyone has spent over a decade complaining about what flavor of sugar tastes best.
Y'all at Zig have a solution, I trust Zig's solution will be a good one (zig is lots of fun to use as a language) but at the end of the day, IO is slow, that needs to get hidden somehow, or not.
Everyone should have to do embedded for awhile and setup their own DMA controller operations. Having async IO offloaded to an actual hardware block is... A different type of amusing.
It was an interesting read, but I guess I came away confused about why "coloring" functions is a problem. Isn't "coloring" just another form of static typing? By giving the compiler (or interpreter) more meta data about your code, it can help you avoid mistakes. But instead of the usual "first argument is an integer" type meta data, "coloring" provides useful information like: "this function behaves in this special way" or "this function can be called in these kinds of contexts." Seems reasonable?
Like the author seems very perturbed that there can be different "colors" of functions, but a function that merely calculates (without any IO or side-effects) is different than one that does perform IO. A function with only synchronous code behaves very differently than one that runs code inside another thread or in a different tick of the event loop. Why is it bad to have functions annotated with this meta data? The functions behave in a fundamentally different way whether you give them special annotations/syntax or not. Shouldn't different things look different?
He mentions 2015 era Java as being ok, but as someone that’s written a lot of multithreaded Java code, it’s easy to mess up and people spam the “synchronized” keyword/“color” everywhere as a result. I don’t feel the lack of colors in Java makes it particularly intuitive or conceptually simpler.