5 ms·
This proposal reeks of "What color is your function?" https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff
by nayuki 1y ago
This proposal reeks of "What color is your function?" https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... . The distinction between sync functions and async functions keeps intruding into every feature. As we can see here, there are Symbol.dispose and Symbol.asyncDispose, and DisposableStack and AsyncDisposableStack.
I am so glad that Java decided to go down the path of virtual threads (JEP 444, JDK 21, Sep 2023). They decided to put some complexity into the JVM in order to spare application developers, library writers, and human debuggers from even more complexity.
- jupp0r 1y agoI disagree. Hiding async makes reasoning about code harder and not easier. I want to know whether disposal is async and potentially affected by network outages, etc.
- swyx 1y agolook into how React Suspense hides asynchrony (by using fibers). its very commingled with nextjs but the original ideas of why react suspense doesnt use promises (sebmarkbage had a github issue about it) is very compelling
- notnullorvoid 1y agoCompelling? It's freaking terrible, instead of pausing execution to be resumed when a promise is resolved they throw execution and when the promise is resolved the whole execution runs again, and potential throws again if it hits another promise, and so on. It's a hacked solution due to the use of a global to keep track of the rendering context to associate with hook calls, so it all needs to happen synchronously. If they had passed a context value along with props to the function components then they could have had async/await and generator components.
- throw10920 1y agoThis is fallacious. You could use the same logic to argue that we should encode the type of every argument and return value of a function into the function signature, and have to explicitly write it out by hand at every call site, for the same reason: x = number:foo(number:x, string:y) It's absurd. The type system should responsible for keeping track of the async status of the function, and you should get that when hovering over the function in your IDE. It does not belong in the syntax any more than the above does and it's an absolutely terrible reason to duplicate all of your functions and introduce these huge headaches.
- timewizard 1y agoIn plain javascript it's not a problem. Types are ducked so if you receive a result or a promise it doesn't matter. You can functionally work around the "color problem" using this dynamism. It's only when you do something wacky like try to add a whole type system to a fully duck typed language that you run into problems with this. Or if you make the mistake of copying this async/await mechanism and then hamfistedly shove it into a compiled language.
- rtpg 1y agoTypescript has no problem with typing your scenario (or at least nothing that isn’t present in “plain” JavaScript… what if your value is a promise?) And compiled languages don’t have more trouble with this than JavaScript. Or rather, Javascript doesn’t have less issues on this front. The color issue is an issue at the syntactic level!
- timewizard 1y agoExcept you can await on non-Promise objects which just returns the original object. Most other typed languages do not appear have this convenience. C# (the apparent source of the color rant) does not. It sets JavaScript apart. Likewise Promise.resolve() on a promise object just returns the original promise. You can color and uncolor things with far less effort or knowledge of the actual type.
- deleted 1y ago[deleted]
- jakelazaroff 1y agoAwaiting a non-promise doesn’t make it synchronous, though — it still executes any subsequent lines in a microtask. Try running this code. It’ll print “bar” first and then “foo”, even though the function only awaits a string literal and the caller doesn’t await anything at all. const foo = async () => console.log(await "foo"); foo(); console.log("bar");
- neonsunset 1y ago
- vips7L 1y agoBeyond happy Java made that decision as well.
- anon291 1y agoThis is because normal execution and async functions form distinct closed Cartesian categories in which the normal execution category is directly embeddable in the async one. All functions have color (i.e. particular categories in which they can be expressed) but only some languages make it explicit. It's a language design choice, but categories are extremely powerful and applicable beyond just threading. Plus, Java and thread based approaches have to deal with synchronization which is ... Difficult. (JavaScript restricts itself to monadic categories and more specifically to those expressible via call with continuation essentially)
- rtpg 1y agoIt’s so annoying that right now the state of the art is essentially “just write all of your code as async because even sync callers could just spin up a one-off event loop in the worst case” in most languages. The only language I know that navigates this issue well is Purescript, because you can write code that targets Eff (sync effects) or Aff (async effects) and at call time decide. Structured concurrency is wonderful, but my impression is we’re doing all this syntactic work not to get structured concurrency, but mostly to have, like, multiple top-level request handlers in our server. Embarassingly parallel work!
- olalonde 1y agoI'm not sure how it's implemented in the JVM, but in general, multithreading is notoriously difficult to reason about. Entire books are devoted to the pitfalls (race conditions, deadlocks, livelocks, starvation, memory visibility issues, and more). Compared to that, single threaded async programming is a walk in the park. I’d rather deal with "function color" than try to debug a heisenbug in a multithreaded app.
- pton_xd 1y agoShare-nothing via message passing ala Erlang makes multithreading much more tractable. I daresay it's enjoyable. Async is a decent syntax for simple tasks but that simplicity falls apart when composing larger structures and dealing with error handling and whatnot. I find it more difficult to understand what's going on compared to explicit threading.
- olalonde 1y ago> Async is a decent syntax for simple tasks but that simplicity falls apart when composing larger structures and dealing with error handling and whatnot. Do you have a concrete example? It has just never really been an issue for me since async/await (callback hell was a thing though).
- vips7L 1y agoYou don’t know how it works and are commenting on it?? Peak HN.
- olalonde 1y agoMultithreading works similarly across most programming languages, and that was my assumption here as well. Your comment made me second-guess myself a bit, so I went back and checked the spec. Turns out it is indeed just standard multithreading, as I originally thought.
- afiori 1y agoThe implementation and the observable behaviour are two different things
- bla3 1y agoThat's a critique of `async`, not of `using` though, right? This doesn't seem to make functions more colored than they already are as far as I understand.
- dingi 1y agoIndeed. Virtual threads, structured concurrency and scoped values are great features.
- paulddraper 1y agoTo be clear...... This does not introduce function coloring. You are mearly pointing out the effects of pre-existing function coloring, in that there are two related symbols Symbol.dispose and Symobl.asyncDispose. Just like there is Symbol.iterator and Symbol.asyncIterator.