3 ms·
The "what color is my function" problem is insurmountable in Javascript, because the runtime does not allow you to call an async function from a non-async one.
by lalaithion 6y ago
The "what color is my function" problem is insurmountable in Javascript, because the runtime does not allow you to call an async function from a non-async one. However, most effects aren't like this. If you say "this function needs randomness" then you can create a pure PRNG and call the function with the PRNG providing randomness. If you say "this function needs logging" you can tell it to log to a string and parse/ignore the string. If it throws an exception, you can catch the exception. Haskell even provides `unsafePerformIO`, which lets you run arbitrary computations as if they were pure.
- skybrian 6y agoThere is the specific issue with async functions, but that's only one example of a general problem, what I'm calling "function coloring." Workarounds are often possible, but they are still workarounds and often result in bad code. We've been there with Java. An API takes a Runnable. You need to do something that does IO, so you catch the exception... and then what? Log and suppress it? This is how bad code happens. At best you get chained exceptions. With Callable, they got smarter and declared it to throw Exception, which means it can only be easily propagated by other methods that declare they throw Exception. So it's a viral declaration, unless you engage in workarounds like exception wrapping. You don't need an effect system for this to happen, though. In Go, you don't have the problem with different kinds of errors, but you can still classify functions into two categories: those that may return an error, and those that (apparently) always succeed. If you need to fix the API, you might end up with lots of refactoring [1]. Mistakes at the API level can be hard to fix without touching lots of API's. This is unsolvable in general. The only way to avoid workarounds (via escape hatches or by mocking things out) is to standardize whatever you can so it works together. [1] https://www.dolthub.com/blog/2020-11-16-panics-to-errors/ https://www.dolthub.com/blog/2020-11-16-panics-to-errors/
- lalaithion 6y agoNothing prevents having a type system capable of dealing with those problems. Yes, Java and Golang make this difficult, but if you have a language that supports it, there's nothing which prevents writing an API that says "Whatever the effects of the Callable you passed me are, I also perform those effects".
- skybrian 6y agoIntroducing generic types doesn't make the function-coloring problem go away. Now, instead of having a single function that has some effects, you have a family of closely-related functions, each with different effects. These functions are incompatible with each other. The function-coloring problem has gotten worse! :) (Generic types are still useful though.)
- lalaithion 6y agoNo, it doesn't make it go away, but it makes the "function coloring problem" about as much a problem as the "colors" of functions as determined by their return types. You can't pass a `func () string` to an api accepting a `func () int`.
- karlicoss 6y agoAnd indeed, JS Flow detects such async issues pretty well
- no_wizard 6y agoI think the reactive/rx/observer patter might be an acceptable solution around the what color is my function problem and it tends to be very popular with the functional programming wing of the JS community from what I’ve seen. Never understood why the browser didn’t ship a full access to something like an EventEmitter. Since you can dispatch events on window document DOM elements etc seems like being able to subscribe to events in a more arbitrary fashion that worked in parallel to the other events would have been useful and solved callback hell all the same
- the_benno 6y agoWe built an effect system to enforce thread safety in Rx-based android apps a few years ago and published a paper on it at ASE, if you're interested: plv.colorado.edu/benno/ase18.pdf the idea should generalize to whatever thread-pool/effect constraints you want to express, but the paper and implementation are focused on keeping UI effects on the android main thread.