Live data from Hacker News

Ruby methods are colorless

jpcamara.com

161–170 of 242 posts

Re: Ruby methods are colorless

#161
post #81

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…

Not really. What it really means is that some function in this callstack is expensive. Async Await bubbles to the top of your program. Eventually, you might just read this as this application as a whole might be expensive.

Re: Ruby methods are colorless

#162
post #105

Earlier 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?

Yes, it does, and Go is perfectly capable of it, and many libraries exist for you to choose which exact method suits your problem and temperment.

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

#163
post #81

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…

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".

This feels very true in Rust but not sure about JS. In JS you can `await` non-promise values without issue.

Re: Ruby methods are colorless

#164
post #105

Earlier 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

#165

Earlier 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.

Having interacted with a bunch of other concurrency models in a bunch of other languages, I call. Concurrency is hard, every concurrency model has flaws, and which flaws you want to live with is largely a matter of personal preference and what type of problem you are working on.

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

#166

Earlier 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…

> This unnecessarily trivializes the technical problems at hand.

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

#167
post #25

Earlier 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#?

async/await may have originated as keywords in C#, I don't know, but the programming style itself is ancient. Almost every GUI ever written is programmed in the style. Network servers were written this way back when threads were just a fever dream of academics yet. The entire Mac OS ecosystem prior to OSX had to be written in this style because time was cooperatively shared across the entire OS.

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

#168
post #117

As 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.

Yeah, that's the correct solution. I'm not arguing for the solution, I'm arguing for the problem, because a lot of people seem to think that the problem isn't real.

Re: Ruby methods are colorless

#169

Earlier 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?

Everywhere in the C# ecosystem. You’ll see things like x.Read() and x.ReadAsync().

Re: Ruby methods are colorless

#170
post #81

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…

> Also, a nitpick - you can call async functions from sync ones, you just can't access the return value.

Or wait for them to finish.

Post reply on HN