Live data from Hacker News

Ruby methods are colorless

jpcamara.com

121–130 of 242 posts

Re: Ruby methods are colorless

#121
post #101
post #98

Earlier quoted context omitted.

> is a feature I was quite shocked to read this, as in it never brushed my mind that it could be. I personally doesn't feel like it is and is one of the reasons why I try to avoid working with that stack at all cost. I don't think the neon sign is a good excuse for the mess colored functions are. You easily can create a synchronous O(n^4) function, and there are probably tons of quick async functions. Moreover, your…

Async/await is clearly a feature in JS, though not for the reason the previous poster mentions. Async/await wasn't part of the language until 2017. If you don't like it, you can just use Promises. If you do that, there are no "colored function" (functions of color?). As far as the article goes, I think the pattern in Ruby is great. I prefer it to JS. But the JS approach works fine and the whole controversy about colo…

Using promises is basically no different than using async functions, and definitely doesn't "uncolor" your functions.

Any function that calls another that returns a Promise will have to return a Promise to represent completion correctly. That's the color.

Re: Ruby methods are colorless

#122

Earlier quoted context omitted.

Coming from a heavy TS background into a go-forward company, I’d say the main thing you get with async is it makes it incredibly obvious when computation can be performed non-sequentially (async…). For example, It’s very common to see the below in go code: a := &blah{} rA, err := engine.doSomethingWithA() b := &bloop{} rB, err := engine.doSomethingWithB() This might have started out with both the doSomethings being v…

Of course, the other nice thing about the JS example compared to Go is that it's trivial at the callsite to do this: const [[rA, errA], [rB, errB]] = await Promise.all([ engine.doSomethingWithA(), engine.doSomethingWithB() ]) At least these days you can ask an LLM to write the WaitGroup boilerplate for you in Go.

Which has to do with the incredible lack of expressivity of Go, not with the concurrency model. Nothing precludes doing exactly the same thing with thread-like constructs in an expressive language.

Not to mention waitgroups are way overkill for this. You’d just use a channel or two. Or an errgroup if you want to be fancy.

Re: Ruby methods are colorless

#123
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…

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

This is very rarely necessary in app code. It's usually only a pattern for higher-level utility functions, and even then if you really wanted to you could unify implementations with generators.

Re: Ruby methods are colorless

#124

I don't like colored function for obvious reasons, but fully colorless for async means you don't know when things are async or not. There are a lot of things I dislike in JS, but I think the I/O async model is just right from an ergonomics point of view. The event loop is implicit, any async function returns a promise, you can deal with promises from inside sync code without much trouble. It's just the right balance.

> fully colorless for async means you don't know when things are async or not The IDE can tell you.

> The IDE can tell you.

The only way the IDE can tell you is if the language tells it, or it guesses - and if it guesses then it will get it wrong sometimes. Which things are async or not is exactly the kind of thing that needs to be part of the language definition, so that all tools will agree about it and you won't have functions that are async in one IDE and not another, or async in a profiler but not an IDE, or...

Re: Ruby methods are colorless

#125
post #105

Earlier quoted context omitted.

Of course, the other nice thing about the JS example compared to Go is that it's trivial at the callsite to do this: const [[rA, errA], [rB, errB]] = await Promise.all([ engine.doSomethingWithA(), engine.doSomethingWithB() ]) At least these days you can ask an LLM to write the WaitGroup boilerplate for you in Go.

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.

Re: Ruby methods are colorless

#126

Earlier quoted context omitted.

I think the only place that happens is in programming languages where you actually can choose to do something using a thread-blocking operation? Specifically, I've only seen it in Python. And yeah, it's not very ideal there. In other languages, it's typically only possible to do the operation in async mode, so you never write a foo_sync function in the first place.

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`ed callsites and doesn't yield at all other callsites.

`async` only tells the VM to create the state machine necessary to resume the function after `awaited` calls return.

Re: Ruby methods are colorless

#127
I loved Ruby as a total beginner but hate it as an experienced programmer.

Colorless brings no meaning when i look at the signature of a method, which is a warning !

Async at the boundary, sync at the core is my favorite paradigm.

Re: Ruby methods are colorless

#128
post #115

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. Oh yes, absolutely. But the solution to that is stop using joke languages that can't do kind polymorphism. > Yes, and the IDE can show you that information, exactly like it does the types of arguments. How can it, if the language doesn't give it that informa…

Good luck with that, when we keep using glue languages for full blown applications, and then shelling out to C extensions, instead of ones that could do the job all by themselves.

Re: Ruby methods are colorless

#129
post #51

Earlier quoted context omitted.

Coming from a heavy TS background into a go-forward company, I’d say the main thing you get with async is it makes it incredibly obvious when computation can be performed non-sequentially (async…). For example, It’s very common to see the below in go code: a := &blah{} rA, err := engine.doSomethingWithA() b := &bloop{} rB, err := engine.doSomethingWithB() This might have started out with both the doSomethings being v…

Honestly, despite that blog, async coloring is a feature. The pattern enforces implicit critical sections between yields and the coloring is how the dev can know what will yield.

For some reason requiring the programmer to use additional syntax at the call site to mark behavioural properties of called functions is not a popular language feature generally. I guess eg TypeScript could add it as a user extensible feature. Would it be useful to be able to require things like this in your internal API?

  let gizmos = nocheckperms lookupRequestedGizmos(request);

Re: Ruby methods are colorless

#130
post #98
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…

> is a feature I was quite shocked to read this, as in it never brushed my mind that it could be. I personally doesn't feel like it is and is one of the reasons why I try to avoid working with that stack at all cost. I don't think the neon sign is a good excuse for the mess colored functions are. You easily can create a synchronous O(n^4) function, and there are probably tons of quick async functions. Moreover, your…

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 knowing which function is running asynchronously is even more useful for languages like JavaScript.

Post reply on HN