4 ms·
> The difference is that in Go you are expected to explicitly send the result via a channel or some other data structure and then synchronize the completion of
by spinningslate 2y ago
> The difference is that in Go you are expected to explicitly send the result via a channel or some other data structure and then synchronize the completion of the execution, where-as with tasks you simply await that.
That may be be the case in Go but it's not an inherent property of green threads. See, for example, Gleam Tasks [0] which are based on green threads and provide the syntatic convenience of being able to await the result rather than receiving a message:
let task = task.async(fn() { do_some_work() })
let value = do_some_other_work()
value + task.await(task, 100)
They do so without the disadvantage of bifurcating the code base into sync and async functions.
[0] https://hexdocs.pm/gleam_otp/gleam/otp/task.html https://hexdocs.pm/gleam_otp/gleam/otp/task.html
- neonsunset 2y agoOf course. The discussion regarding Goroutines is to highlight that, despite prevalent claims of otherwise, they are not doing something unique and for developers who are used to languages with powerful concurrency primitives look like an incomplete task abstraction. "Green Threads" really is an implementation detail, in many ways orthogonal to pros/cons of implicit and explicit suspend points. I hope your opinion about C#'s task system has improved since the last time[0], given what Gleam (and, in many ways, Elixir) does looks practically identical :) [0]: https://news.ycombinator.com/item?id=40427935 https://news.ycombinator.com/item?id=40427935
- spinningslate 2y ago>I hope your opinion about C#'s task system has improved since the last time[0], given what Gleam (and, in many ways, Elixir) does looks practically identical :) Well no, not really I'm afraid. My reservation has always been with the codebase birfircation per my previous post. Gleam/BEAM languages, Go, and now Java, don't have async and sync functions. They have one kind of function which can be called either synchronously or asynchronously. The difference is in who decides: the function caller or function implementer. That a sync function can't call an async one amplifies the problem. I know you dislike the "coloured function" metaphor [0] but for me it's a significant issue. I look at lots of C# and Python code, and see libraries now encumbered with both sync and async function variants (e.g. [1] [2]). That, to me, is a significant downside to async/await as implemented in those languages. The Gleam example has all the convenience and readability of its C#/Python counterpart - but without the downsides. I don't doubt you'll disagree :). [0] https://news.ycombinator.com/item?id=39497110 https://news.ycombinator.com/item?id=39497110 [1] https://learn.microsoft.com/en-us/dotnet/api/system.io.stringreader?view=net-8.0 https://learn.microsoft.com/en-us/dotnet/api/system.io.strin... [2] https://fastapi.tiangolo.com/async/ https://fastapi.tiangolo.com/async/
- neonsunset 2y ago> The Gleam example has all the convenience and readability of its C#/Python counterpart - but without the downsides. https://benchmarksgame-team.pages.debian.net/benchmarksgame/box-plot-summary-charts.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... :) Assuming it is unlikely Gleam does something that makes it outperform Erlang, which it compiles to. Now, it comes down to just how BEAM VM is, but nonetheless an argument - C# is a close to the metal programming language where your choices directly affect what happens under the hood, including the use of async/await. For some it may be an undesirable trait but it's precisely what makes it so fast, in domains where languages that are "more abstracted away" used to historically struggle and continue to have lower performance ceiling. As usual, the "coloring" point misses the patterns that async/await enables, and that it is in many ways an "I/O Monad". Still, mixing faux-concept "differently colored threads" in .NET does not come with the same degree of pain it does in Rust or elsewhere (and there are good reasons for that). You can block threads if you have to (which includes synchronously waiting for tasks), and Threadpool is desiged to deal with that appropriately and increase/decrease worker threads count to maintain optimal throughput. You just don't have to pay for it always, and as multitude of alternate implementations suggest there is no free lunch, as usual. Also, sync vs non-async overloads, as I previously discussed, often do I/O in a completely different way. Other languages sell it with loud buzzwords like "NIO", while .NET keeps it boring - the workload will scale without your explicit effort, never throttling independent execution flows. I continue to be convinced of the sheer degree of harm done by "that one article", and applying C# in practice cures this perception once you stop worrying and love the easy concurrency and parallelism that come with it.
- spinningslate 2y agoyou've made the performance argument before and I don't refute that C# shows up better in benchmarks than BEAM languages. Or many others for that matter (including Python). The reductive argument there is that if performance is the sole priority then write machine code. That's extreme. A more robust one is that, according to the same benchmarks you reference, Rust is meaningfully faster than C# and C faster still. So if performance is the overriding objective then use one of those. You'll justifiably push back on that and raise other factors in favour of .Net. And that's the point: it's about trade-offs and preferences. For the apps I've built and been involved with, real world performance has been within commercial tolerance using languages that, at least according to benchmarks, are slower than the top performers. In teams of moderate size and above, managing codebase size and evolution is usually a bigger challenge. Requiring sync and async variants of functions detracts from that: not to mention the overhead of ensuring some level of consistency in when to use each form. > I continue to be convinced of the sheer degree of harm done by "that one article" We'll just have to disagree agreeably on that one. I see the coloured function metaphor as an elegant articulation of an important limitation, and it has served the community well in describing the problem. > applying C# in practice cures this perception once you stop worrying and love the easy concurrency and parallelism that come with it. Another disagree agreeably. In isolation yes, but with a non-trivial cost in bifurcation and the need for async/sync variants.