| ▲ | flohofwoe 7 hours ago |
| If calling the same function with a different argument would be considered 'function coloring', every function in a program is 'colored' and the word loses its meaning ;) Zig actually also had solved the coloring problem in the old and abandondend async-await solution because the compiler simply stamped out a sync- or async-version of the same function based on the calling context (this works because everything is a single compilation unit). |
|
| ▲ | woodruffw 7 hours ago | parent | next [-] |
| > If calling the same function with a different argument would be considered 'function coloring', than every function in a program is 'colored' and the word loses its meaning ;) Well, yes, but in this case the colors (= effects) are actually important. The implications of passing an effect through a system are nontrivial, which is why some languages choose to promote that effect to syntax (Rust) and others choose to make it a latent invariant (Java, with runtime exceptions). Zig chooses another path not unlike Haskell's IO. |
|
| ▲ | SkiFire13 4 hours ago | parent | prev | next [-] |
| > Zig actually also had solved the coloring problem in the old and abandondend async-await solution because the compiler simply stamped out a sync- or async-version of the same function based on the calling context (this works because everything is a single compilation unit). AFAIK this still leaked through function pointers, which were still sync or async (and this was not visible in their type) |
| |
| ▲ | throwawaymaths an hour ago | parent [-] | | Pretty sure the Zig team is aware of this and has plans to fix it before they re-release async. |
|
|
| ▲ | adamwk 6 hours ago | parent | prev | next [-] |
| The subject of the function coloring article was callback APIs in Node, so an argument you need to pass to your IO functions is very much in the spirit of colored functions and has the same limitations. |
| |
| ▲ | jakelazaroff 6 hours ago | parent [-] | | In Zig's case you pass the argument whether or not it's asynchronous, though. The caller controls the behavior, not the function being called. | | |
| ▲ | layer8 5 hours ago | parent [-] | | The coloring is not the concrete argument (Io implementation) that is passed, but whether the function has an Io parameter in the first place. Whether the implementation of a function performs IO is in principle an implementation detail that can change in the future. A function that doesn't take an Io argument but wants to call another function that requires an Io argument can't. So you end up adding Io parameters just in case, and in turn require all callers to do the same. This is very much like function coloring. In a language with objects or closures (which Zig doesn't have first-class support for), one flexibility benefit of the Io object approach is that you can move it to object/closure creation and keep the function/method signature free from it. Still, you have to pass it somewhere. | | |
| ▲ | messe 3 hours ago | parent | next [-] | | > Whether the implementation of a function performs IO is in principle an implementation detail that can change in the future. I think that's where your perspective differs from Zig developers. Performing IO, in my opinion, is categorically not an implementation detail. In the same way that heap allocation is not an implementation detail in idiomatic Zig. I don't want to find out my math library is caching results on disk, or allocating megabytes to memoize. I want to know what functions I can use in a freestanding environment, or somewhere resource constrained. | | |
| ▲ | simonask 22 minutes ago | parent [-] | | This is also why function coloring is not a problem, and is in fact desirable a lot of the time. |
| |
| ▲ | 2 hours ago | parent | prev | next [-] | | [deleted] | |
| ▲ | derriz 3 hours ago | parent | prev | next [-] | | > A function that doesn't take an Io argument but wants to call another function that requires an Io argument can't. Why? Can’t you just create an instance of an Io of whatever flavor you prefer and use that? Or keep one around for use repeatedly? The whole “hide a global event loop behind language syntax” is an example of a leaky abstraction which is also restrictive. The approach here is explicit and doesn’t bind functions to hidden global state. | | | |
| ▲ | quantummagic 4 hours ago | parent | prev [-] | | Is that a problem in practice though? Zig already has this same situation with its memory allocators; you can't allocate memory unless you take a parameter. Now you'll just have to take a memory allocator AND an additional io object. Doesn't sound very ergonomic to me, but if all Zig code conforms to this scheme, in practice there will only-one-way-to-do-it. So one of the colors will never be needed, or used. |
|
|
|
|
| ▲ | jcranmer 7 hours ago | parent | prev | next [-] |
| > If calling the same function with a different argument would be considered 'function coloring', than every function in a program is 'colored' and the word loses its meaning ;) I mean, the concept of "function coloring" in the first place is itself an artificial distinction invented to complain about the incongruent methods of dealing with "do I/O immediately" versus "tell me when the I/O is done"--two methods of I/O that are so very different that it really requires very different designs of your application on top of those I/O methods: in a sync I/O case, I'm going to design my parser to output a DOM because there's little benefit to not doing so; in an async I/O case, I'm instead going to have a streaming API. I'm still somewhat surprised that "function coloring" has become the default lens to understand the semantics of async, because it's a rather big misdirection from the fundamental tradeoffs of different implementation designs. |
| |
| ▲ | omnicognate 16 minutes ago | parent [-] | | 100% agree, but fortunately I don't think it is the "default lens". If it were nobody would be adding new async mechanisms to languages, because "what color is your function" was a self-described rant against async, in favour of lightweight threads. It does seem to have established itself as an unusually persistent meme, though. |
|
|
| ▲ | 6 hours ago | parent | prev | next [-] |
| [deleted] |
|
| ▲ | rowanG077 7 hours ago | parent | prev [-] |
| If your functions suddenly requires (currently)unconstructable instance "Magic" which you now have to pass in from somewhere top level, that indeed suffers from the same issue as async/await. Aka function coloring. But most functions don't. They require some POD or float, string or whatever that can be easily and cheaply constructed in place. |