Live data from Hacker News

What color is your function? (2015)

journal.stuffwithstuff.com

41–50 of 63 posts

Re: What color is your function? (2015)

#42
post #41
post #14

Two years after this article was written, async-await was introduced in Javascript as a solution to this problem. As far as I understand.

async/await in js exhibits the exact problem mentioned in the article.

Not really, you can call any async function in JS in sync code. It is automatically scheduled, and it will return a result immediately.

This result is a Promise, that you can pass sync callbacks to, and keep the whole code away from async/await.

You can also decide that async/await is nice, and just use that instead.

I'm a Python dev, but that part is better in JS.

Re: What color is your function? (2015)

#43
post #7

Zig’s functions are colorblind: https://kristoff.it/blog/zig-colorblind-async-await/

Indeed, partially thanks to this article! It was the key piece of material that helped me convince Andrew to make zig's async colour-less.

The internet is pretty cool.

Re: What color is your function? (2015)

#44
post #38
post #35

Earlier quoted context omitted.

> This is interesting, it seems like a global mode that kind of turns normal Zig code into Go or Erlang-like non-blocking code Nope! There's no language magic going on, and the global switch is just a global variable in the root module. It only affects a few functions in the standard library that check that variable. Zig relies heavily on compile time code executing for metaprogramming, and your code can read symbols…

> Nope! There's no language magic going on, and the global switch is just a global variable in the root module. It only affects a few functions in the standard library that check that variable. I didn’t say there was magic, I was describing the practical effect of this feature. On a type-theoretic level, it’s like entering a global async monad, which is roughly the structure that Go and Erlang have. But since you men…

[deleted]

Re: What color is your function? (2015)

#45
post #38
post #35

Earlier quoted context omitted.

> This is interesting, it seems like a global mode that kind of turns normal Zig code into Go or Erlang-like non-blocking code Nope! There's no language magic going on, and the global switch is just a global variable in the root module. It only affects a few functions in the standard library that check that variable. Zig relies heavily on compile time code executing for metaprogramming, and your code can read symbols…

> Nope! There's no language magic going on, and the global switch is just a global variable in the root module. It only affects a few functions in the standard library that check that variable. I didn’t say there was magic, I was describing the practical effect of this feature. On a type-theoretic level, it’s like entering a global async monad, which is roughly the structure that Go and Erlang have. But since you men…

>But since you mentioned it, global variables that have side effects are definitely magic, in my view. If I did this in Ruby by monkey-patching synchronous IO methods in response to a global flag, people would definitely call it magic.

It definitely is "magic", but it's one of the few areas where I welcome it, personally.

What other options are available? The three I know of are function-colored (JavaScript, Python), async/automatic context-switching by default (Go, Erlang), or monkeypatching to go from colored to async/automatic context-switching by default (Zig, Python gevent).

I also hate globals, side effects, and monkeypatches, but I find the monkeypatch method to be the best compromise. I still use gevent in pretty much every Python project, and have for the past 10 years.

Re: What color is your function? (2015)

#46
post #38
post #35

Earlier quoted context omitted.

> This is interesting, it seems like a global mode that kind of turns normal Zig code into Go or Erlang-like non-blocking code Nope! There's no language magic going on, and the global switch is just a global variable in the root module. It only affects a few functions in the standard library that check that variable. Zig relies heavily on compile time code executing for metaprogramming, and your code can read symbols…

> Nope! There's no language magic going on, and the global switch is just a global variable in the root module. It only affects a few functions in the standard library that check that variable. I didn’t say there was magic, I was describing the practical effect of this feature. On a type-theoretic level, it’s like entering a global async monad, which is roughly the structure that Go and Erlang have. But since you men…

> On a type-theoretic level, it’s like entering a global async monad, which is roughly the structure that Go and Erlang have.

This is the most concise summary of what Zig actually does! Thank you.

I always felt it was a little off, but it makes sense when you think about it in terms of "Zig makes all of your functions red, even if you don't want them to be."

In fact, in the article linked above, it says this in the FAQ:

> Q: SO I DON’T EVEN HAVE TO THINK ABOUT NORMAL FUNCTIONS VS COROUTINES IN MY LIBRARY?

> No, occasionally you will have to. As an example, if you’re allowing your users to pass to your library function pointers at runtime, you will need to make sure to use the right calling convention based on whether the function is async or not. You normally don’t have to think about it because the compiler is able to do the work for you at compile-time, but that can’t happen for runtime-known values.

So in essence, Zig actually is still colored, but the compiler handles for you what it can.

Re: What color is your function? (2015)

#48
I dislike all of Ruby's magic, metaprogramming, and that it's almost impossible to statically analyze, however I have come to appreciate how nice it is in Ruby not to have functions with 'color' like this article mentions. I certainly hope TC39 can find a way to bake in similar async-agnostic syntax to Javascript. I'm not sure if it's possible with syntax alone, or if it would require a new language.

Re: What color is your function? (2015)

#49

Earlier quoted context omitted.

You can do that in pretty much every language, it's just that in most of implementations, blocking on an async call can easily dead-lock, .NET is particularly notorious in this regard: you call GetResult(), the scheduler tries to schedule the task to the thread that have just called the GetResult() on it -- and this thread is now deadlocked, because it waits for itself. But since a threadpool has many threads, such d…

I've been burned by this so many times that I just simply will never use async in any code that is beyond trivial complexity and/or has performance requirements attached. I'll recommend breaking your solution into small pieces that execute separately and pass data to one another via messaging, to isolate the "colors" from one another at the process level.

I'm not a huge fan of async/await (though I have to write a fair amount of it) but that's throwing the baby out with the bathwater. The way to avoid "sync-over-async" deadlocks is to not do sync-over-async, i.e. don't call blocking methods/properties like Wait() and Result on tasks from threadpool threads - it's not what they're for (though they have valid, necessary uses and therefore can't simply be removed).

I've never written code that's deadlocked in this way. I've fixed a ton of such deadlocks, though, and every one boils down to somebody not following this simple rule, and more generally not thinking clearly about what their multithreaded code will actually do when it runs. (Encouraging people to be sloppy in their thinking about these issues is one of the reasons I mildly dislike C#'s concurrency facilities - but nonetheless it's perfectly possible to write code with them that isn't riddled with deadlocks.)

Re: What color is your function? (2015)

#50

I dislike all of Ruby's magic, metaprogramming, and that it's almost impossible to statically analyze, however I have come to appreciate how nice it is in Ruby not to have functions with 'color' like this article mentions. I certainly hope TC39 can find a way to bake in similar async-agnostic syntax to Javascript. I'm not sure if it's possible with syntax alone, or if it would require a new language.

Consider yourself fortunate to have (forgive the assumption!) never worked in a ruby codebase that uses eventmachine or promise.rb. It’s less common than in some other languages but ruby is perfectly capable of a callback/promise-based model for performing async io or query batching, for example. And it creates exactly the “function color” problem that this article describes.
Post reply on HN