Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This. Plus, the cascading effect isn’t necessarily just difficult to account for, sometimes it makes integration effectively impossible.

As an example, a project I work on provides functionality implementing arbitrary computation graphs, with an explicit guarantee that all computations are synchronous, consistent and complete on return from every state change call. This guarantee is a conscious design decision that characterizes both the project itself (and its API boundaries) as well as many of its internals predicated on the same principles. It does explicitly account for asynchronous behavior at the entry point, and at very specific exit points. But introducing async anywhere else in between would mean building a fundamentally different project, and probably revisiting business goals in the process.

The function color problem isn’t just annoying or tedious, it can be fundamental to whether certain projects are even viable.



So, this cascading issue is hitting me right now.

Being real vague here, in order to support a new capability, we need to insert an asynchronous operation in the middle of what has been a synchronous operation. The synchronous operations is done implicitly and explicitly in many, many places in the app (yes I know this sucks, big old codebases are what they are, and you can only refactor so much at one time while continuing to deliver new features).

We have a hard ordering requirement where the new async behavior must be completed before the work can continue.

And it's killing us. What would be a simple case of "call this new function" is spiraling into weeks of work and thrown our planning into question.

Most of the time it's pretty easy to accommodate the contagion. It's a little more work than is ideal, but it is fine in practice because you hit a natural boundary that stops the spread.

But in this case, due partly to tech debt and partly due to deep architectural decisions, it's blocking our ability to move forward in a reasonable amount of time.

We will certainly find a solution, but it's going to be much more expensive to get there than it needs to be.


To me, this actually reads as a reason for function coloring. Your project makes guarantees that neatly match up to the division between async and sync code, and it would be fundamentally incorrect to ever call a function marked as async from most points of your program flow. So in this case, it would be good that the language enforces this for you, right?


Well, yes and no.

Yes: because the language has distinct semantics for asynchrony which fundamentally* cannot be made synchronous, it is good that the language also makes that fundamental inability explicit, and inviolable.

No: the above reasoning is inherently tautological! It’s effectively arguing that it’s good that the language doesn’t have a massive inconsistency between two deeply coupled aspects of the same semantics. That is good! But it’s the kind of good you kind of have to expect, or treat as a tragic design flaw in its absence.

* There are some exceptions, but they’re generally esoteric or niche or have other important caveats.


> it would be fundamentally incorrect to ever call a function marked as async from most points of your program flow

For a language with async/await yes, you need to bifurcate your program into synchronous and asynchronous pieces, and be very careful to maintain that split.

For a language with a synchronous thread abstraction like go, you simply don't need to create this artificial bifurcation in the first place


Yes. The person I replied to described a situation that, to me, is made easier by this bifurcation.


Is it though? In a hypothetical JS with the possibility of, say, “decoloring” async functions—e.g. by optionally blocking on their resolved return value—the situation that function coloring helps… ceases to exist as a situation in need of helping in the first place.

That would be broadly unappealing where single threaded, cooperative concurrency is a baseline assumption! But it’s more fair to say it’s a trade off, and it’s also fair to recognize the things made impossible by a trade off.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: