Long-time JS/TS/Node programmer here. Knowing ahead of time which functions are async is a feature . It's a big neon sign that says "hey, this function call is expensive ". This is a good thing for programmers to easily see and know at the call site. If you make multiple calls with async/await in a row, the performance issues are plainly obvious at the call site. With "colorless" functions, this information is hidden…
Ruby methods are colorless
161–170 of 242 posts
Re: Ruby methods are colorless
#162Earlier quoted context omitted.
Yeah, go's a little boilerplatey, but you have to option to run two sync things concurrently as well with something like: type result[T any] struct { el T err error } chanA := make(chan result[aResultType]) chanB := make(chan result[bResultType]) go func() { defer close(chanA) a := &blah{} rA, err := engine.doSomethingWithA() chanA
One could theoretically pull out the shared boilerplate to a utility function like: func runTask[T any](task func() (T, error)) chan result[T] { ch := make(chan result[T]) go func() { defer close(ch) res, err := task() ch Does that sort of thing happen much in practice?
One of the common pasttimes in the threaded versus async debate is to present code in which one side uses all sorts of helpers and patterns and libraries and the other side is presented through writing it "raw". The great-grandparent of my post here is guilty of this. While there are interesting reasons to debate threaded versus async code, this is not one of them. Both of them are absolutely capable of writing the moral equivalent of "output = parallel_map(myMapFunc, input)" and all similar operations to within practical epsilon of each other, and anyone citing this sort of thing as an argument on either side should probably be ignored. And both languages will feature code written by people who don't know that, and it shouldn't count against either.
Re: Ruby methods are colorless
#163Long-time JS/TS/Node programmer here. Knowing ahead of time which functions are async is a feature . It's a big neon sign that says "hey, this function call is expensive ". This is a good thing for programmers to easily see and know at the call site. If you make multiple calls with async/await in a row, the performance issues are plainly obvious at the call site. With "colorless" functions, this information is hidden…
It's a big neon sign that says " Either this function is expensive, or it isn't but some framework somewhere that sometimes needs to call expensive functions might also need to call this function using the same syntax".
Re: Ruby methods are colorless
#164Earlier quoted context omitted.
Yeah, go's a little boilerplatey, but you have to option to run two sync things concurrently as well with something like: type result[T any] struct { el T err error } chanA := make(chan result[aResultType]) chanB := make(chan result[bResultType]) go func() { defer close(chanA) a := &blah{} rA, err := engine.doSomethingWithA() chanA
Now handle the following that is painlessly solved by runtimes with structured concurrency: If A failed, the whole function is failed, and we don't need B any more. To save resources we should cancel B. And vice versa, cancel A if B failed.
import github.com/carlmjohnson/flowmatic
func whatever(ctx context.Context) {
err := flowmatic.Race(ctx, taskA, taskB)
}
Provide your definition of taskA and taskB, of course.As I said in another message, this is not a particularly fruitful line of attack in either direction. All the languages in question are perfectly capable of abstractions.
Re: Ruby methods are colorless
#165Earlier quoted context omitted.
This is not just about performance. Unlike Go or Ruby, JavaScript is a single-threaded language. Synchronization constructs such as mutexes and semaphores are uncommon and not part of any standard library. When you are calling a synchronous function, you can be completely assured that no race condition can develop while the function is running, but the same guarantee is not true for asynchronous functions. That's why…
"Now you have two problems." Adding async/await was a hack to avoid having to tackle the hard problem of real concurrency, so now you have a) no real concurrency, and b) coloured functions. There is a parallel universe where JS added almost any other concurrency primitive and got a better trade-off than async/await.
For myself, I happen to agree with OP that single threaded plus async/await has honestly been my favorite concurrency model I've ever worked with for the types of programs I tend to write (IO-bound web apps with lots of network requests and no hot loops). The property that they described of having no race conditions of any kind except where you opt into them by calling out to an explicitly tagged async function is an enormous unnecessary mental burden removed.
In other contexts with higher compute demands, a full threading model or something like Go can make a ton of sense. But it's not worth the overhead for your average web app where what you really want is to just resume when that web request finishes.
Use the right tool for the job, don't get dogmatic about programming language features in the abstract.
Re: Ruby methods are colorless
#166Earlier quoted context omitted.
The "it's typically only possible to do the operation in async mode" is part of the problem. If I'm writing a a batch script that parses a file as part of its operation, I don't want or need the read_file() function to be async! My code should just block until the file opens. Alternately, I want to be able to designate a computationally-intense function call (just that call, leaving the other calls alone) as async so…
> The main problem is that someone got it in their head This unnecessarily trivializes the technical problems at hand. This wasn't just something someone got in their head, especially considering... > that the function definition was the right place to designate whether a function was async or not, and it's not. The right place is the call site. This is exactly what JavaScript did. The program only yields at `await`e…
Making a language that automatically generates two versions of a function, one that is async and returns a Promise-wrapped object, and another that is sync, is not hard.
> This is exactly what JavaScript did.
No, it isn't. JavaScript requires you to declare functions as async at the function definition, and you can't call async functions from sync ones. This is exactly the thing I am arguing against, and is the opposite of "The right place is the call site."
Re: Ruby methods are colorless
#167Earlier quoted context omitted.
My theory is that JavaScript programmers who were forced into thinking this way for decades with their single-threaded runtime have infected other languages with the idea that this style of coding is not only good but furthermore that it needs to be explicit. Thank goodness we have wiser language developers out there who have resisted this impulse.
Didn’t async/await originate in c#?
This is one of the most blatent "failure to learn from our history" debates I know of, when people act as if the question started with Javascript just a few years ago, when in fact the programming community has experience with this style that predates when most of us were born. I'm getting to old fogey myself and it still predates my 1978 birthdate. I was never even tempted to get into Node because I'd already made an async/await-style mess in Perl before Node was even released, and the mess had everything to do with the programming style and little to do with Perl qua Perl, and the libraries I used were already old and well-established then, if not outright long in the tooth. There is nothing new about this, except keywords.
Re: Ruby methods are colorless
#168As they should be. I object to doing what a computer can do for me (in programming), and manually creating separate versions of functions that are identical up to async absolutely falls into that category.
So use a language that knows how to be polymorphic over async. Just like you don't want to have to write one version of sort() for each possible array element type, but the solution isn't to make all array elements untyped, the solution is to have a language that can abstract over that.
Re: Ruby methods are colorless
#169Earlier quoted context omitted.
> Knowing ahead of time which functions are async is a feature. "Expensive" is subjective and should be up to the programmer to decide. And, it absolutely should not require creating two identical function definitions to get around the function coloring problem - that's completely indefensible. > This is a good thing for programmers to easily see and know at the call site. Yes, and the IDE can show you that informati…
> And, it absolutely should not require creating two identical function definitions to get around the function coloring problem - that's completely indefensible. Where do you see insanity like this?
Re: Ruby methods are colorless
#170Long-time JS/TS/Node programmer here. Knowing ahead of time which functions are async is a feature . It's a big neon sign that says "hey, this function call is expensive ". This is a good thing for programmers to easily see and know at the call site. If you make multiple calls with async/await in a row, the performance issues are plainly obvious at the call site. With "colorless" functions, this information is hidden…
Or wait for them to finish.