On Sunday, 19 January 2025 at 18:46:23 UTC, Jin wrote:
> I see that you prefer not to notice the problems instead of solving them. Good luck to you with this undertaking - you will need it. But if this cancer of "modern" programming languages creeps into D, I’ll finally switch to some Go.
I think you have a misunderstanding (or mutliple here). Nobody here want's to take away threads or fibers from the language. And also: even threads and fibers have many of the same problems than stackless coroutines; the only difference really is the implementation and somewhat their usage.
>
- [Low performance due to the inability to properly optimize the code.] (https://page.hyoo.ru/#!=btunlj_fp1tum/ View'btunlj_fp1tum'.Details=%D0%90%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B9%20%D0%BA%D0%B5%D0%B9%D1%81)
Benchmarking is always only as good and usefull when used in the right environments. I can easily create benchmarks that also show how "slow" fibers are and how "fast" async is, as well as otherwise. Hell anyone could claim that just spawning more OS threads is "somehow" faster than any greenthread or async continuation if they just tweak their workload enough; because at the end of the day its exactly that whats the key to benchmarks: workload.
Any form of concurrency only really excells at what they are doing if used in an workload where it is key to do things concurrent / in parallel, which mainly is IO bound applications such as webservers. Any linear job, such as calculating a fibonacci number will always be slower when bloated with ANY form of concurrency. Just go ahead and try re-implementing it with fibers or OS Threads where every call to fib(n)
spawns a new thread and joins it. I think anyone would agree that thats just insane waste of performance, which it rightfully is! Nobody in their right mind would try to calculate it in parallel because its still only a "simple" calculation.
Another thing is when you have to deal with Millions (!) of concurrent request on an webserver where there's no gurantee that any of the request resolve in linear time, or with other words, without waiting on another thing in some form, which is a stark contrast to a fibonacci calculation which always be resolveable without any further waiting once it's started. This is due to the purity of these two workloads: fibonacci is pure as it only ever require the inputs you give it directly. But 99.99% of any webrequest deals with some form of waiting: be it because you have an database you need to wait for, an cache adapter like redis or a file you need to read: IO is a large portion of time waiting for it. Thats why we have invented Fibers or async in the first place: spending the precious time we would wait otherwise doing actual work.
>
- [The need to reinvent the stack as an AsyncContext.](https:// github.com/tc39/proposal-async-context)
This need only arises from poorly used global variables / "impure" code, as the example you reference very good demonstrates; the async code captures all explicitly passed values to functions correctly. Only in the example where a "shared" variable (an global for all that matters here), is introduced, problems start to creep in. These problems also arise if one uses fibers btw, as globals are always a source of errors if not managed correctly. Thats one of the reasons D supports writing "pure" code: if you eliminate any implicit outside truth and only consider values explicitly passed via parameters or return values, your code magically gets way safer and also for a compiler to optimize for.
And btw, even threads and fibers have this context problem: because of that, we're invented thread-locals, or for the case of fibers, fiber locals. Just look and vibe.d; they build ontop of fibers and added a fiber-local storage because globals are inheritently a problem in physically all concurrent code, not only async/await stackless coroutines.
> But if this cancer of "modern" programming languages creeps into D, I’ll finally switch to some Go.
Thats funny that you mention go, as it has even some of the flaws you yourself mentioned; it has the same context problem with globals; it expects you (like many other languages) to use an mutex to protect it or use an type literally named 'Context'. Sure it has additionaly some race detection, but that gets you only so far. And your point on how you need an extra CancellationToken type: thats also true for any threading and/or fibers, and in go it's litterally one of the first thing you learn: waitgroups and context (again).
And I would ask you to keep this negativity out of these sort of discussions. Again, nobody will take away threads or fibers; all thats propsed here is that we get another tool in our toolbox. If you want to continue using fibers you're free to go. I also would mention that I wouldn't want fibers to be removed once stackless coroutines landed in D; D is an language for everyone, and as such should give as many tools to people as they need. There will always be some tool thats not used by everyone, but I see that as a win. Better have one tool to much than lacking it and resorting to weird hacks to get stuff working.