Live data from Hacker News

Ruby methods are colorless

jpcamara.com

71–80 of 242 posts

Re: Ruby methods are colorless

#71
post #34

I feel like I have some intuative understanding of how go achieves colorless concurrency using "go routines" that can park sync/blocking io on a thread "as needed" built into the runtime from the very begining. I don't understand how Ruby added this after the fact, globally to ALL potential cpu/io blocking libraries/functions without somehow expressing `value = await coro` Python is currently going through an "colori…

Java has shown that a sufficiently strong runtime can take the burden onto itself long after the facts have been established. Python in contrast has a runtime ultimately held back by its deep integration with the C-ecosystem which creates more black-boxes inside the runtime than you can find inside a swiss cheese. Similar with C# and Rust. No strong runtime, no colorless functions for you.

C# has a strong runtime.

Re: Ruby methods are colorless

#72

Earlier quoted context omitted.

I'm with you here, actor model is the way to go. I thought Go style could be better, but the Go type system is completely inadequate to support that style: it is impossible to guaranteed that a goroutine is panic free, it is not possible to put a recover in the goroutine unless that code is under author's control (could be a lib) and a goroutine panic takes down the whole app. Suddenly I want a wrapper around each go…

That sounds a lot like async/await. Any errors thrown in an async context bubble to the callsite awaiting it.

Sorry you are right, that was specific to our case where we were already waiting for a result from the goroutines. In an actor model, you would let the "goroutine" die and the supervisor would restart it if it has a restart policy, otherwise it will die and stay dead (without bringing the system down). In erlang you can also "link" the current actor to another actor so that if the linked actor dies, the linker dies too (or receives a message)

Re: Ruby methods are colorless

#73
post #15

I've implemented coroutines in C and C++; my preferred multitasking environment is message-passing between processes. I'm not quite sure what the async/await stuff is buying us (I'm thinking C++, here). Like, I get multi-shot stackless coroutines, i.e., function objects, but I don't get why you'd want to orchestrate some sort of temporal Turing pit of async functions bleeding across your code base. I dunno. Maybe I'm…

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…

Only if those doSomething methods were written as asynchronous to begin with.in your original example, doSomethingA was simple, why would it be an async method. If your answer is write every method async for a rainy day, then whats the point.

Re: Ruby methods are colorless

#74
post #36

I'm confused, and please correct me if I'm wrong. Aren't all these calls blocking? Doesn't `File.read` still block? Sure it's multithreaded, but it still blocks. Threading vs an event loop are two different concurrency models.

> Aren't all these calls blocking? Only locally, which is pretty much the same as when you `await` a call. > Threading vs an event loop are two different concurrency models. The point is that you can build a "threading" (blocking) model on top of an event loop, such that you get a more natural coding style with most of the gain in concurrency. It loses some, because you only have concurrency between tasks (~threads)…

The whole point of async/await is to allow for not blocking the caller though until it's ready for an explicit synchronization point.

If you are blocking the caller you have not "solved" the colored function "problem".

Re: Ruby methods are colorless

#75
99.9% of these "colored" function articles have an incomplete or even flawed understanding of async/await symantics.

Fibers are not fungible with async/await. This is why structured concurrency is a thing.

Re: Ruby methods are colorless

#76
Great article! I'm looking forward to reading the rest of the series.

I noticed a couple details that seem wrong:

- You are passing `context` to `log_then_get` and `get`, but you never use it. Perhaps that is left over from a previous version of the post?

- In the fiber example you do this inside each fiber:

    responses 
and this outside each fiber:

    responses 
Something is not right there. It raised a few questions for me:

- Doesn't this leave `responses` with 8 elements instead of 4?

- What does `Fiber.schedule` return anyway? At best it can only be something like a promise, right? It can't be the result of the block. I don't see the answer in the docs: https://ruby-doc.org/3.3.4/Fiber.html#method-c-schedule

- When each fiber internally appends to `responses`, it is asynchronous, so are there concurrency problems? Array is not thread-safe I believe. So with fibers is this safe? If so, how/why? (I assume the answer is "because we are using a single-threaded scheduler", but that would be interesting to put in the post.)

Re: Ruby methods are colorless

#78
post #15

I've implemented coroutines in C and C++; my preferred multitasking environment is message-passing between processes. I'm not quite sure what the async/await stuff is buying us (I'm thinking C++, here). Like, I get multi-shot stackless coroutines, i.e., function objects, but I don't get why you'd want to orchestrate some sort of temporal Turing pit of async functions bleeding across your code base. I dunno. Maybe I'm…

I have written Ruby, Elixir, and Typescript on Nodejs.

I have yet to see a good reason for async/await, other than syntax sugar on a flawed language architecture. The very thing people like about Nodejs (async reactor), creates a lot of problems in production web and data pipeline code.

As an aside, Elixir’s Task.async and Task.await are function helpers that work with message passing primitives. Code execution can be truly suspended, and messages are queued. Javascript’s async/await queues code execution rather than messages, and I think that leads to error prone code by design.

Re: Ruby methods are colorless

#79

The argument for "color"ed functions in Javascript is flawed and comes from somebody with a (very) shallow understanding of the language. Javascript is as "colorless" any other programming language. You can write "async"-style code without using async/await at all while it being functionally equivalent. Async/await is just syntactic sugar that saves you from writing "thenable" functions and callbacks again and again…

If you program with promises and without async/await, then your language is still missing something compared to languages that have coroutines in which functions that suspend and do not suspend may be composed (used by higher-order functions, etc.) in the same ways as each other. You've moved from the situation where both types of functions were present and must be handled differently to the situation where one type of function is entirely missing.

Re: Ruby methods are colorless

#80

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…

Only if those doSomething methods were written as asynchronous to begin with.in your original example, doSomethingA was simple, why would it be an async method. If your answer is write every method async for a rainy day, then whats the point.

No… that’s the whole point. If you change them to be async, the language forces you to go and rethink what implications that has for the callers. This is a good thing, dumbly sequenced operations are terrible UX. And UX is far more important than whatever it is they call “DX”.
Post reply on HN