Live data from Hacker News

What color is your function? (2015)

journal.stuffwithstuff.com

151–160 of 198 posts

Re: What color is your function? (2015)

#151
post #3

Go doesn't have colored functions due to its nice fat runtime hiding all the async magic away for us. That makes it a pleasure to code concurrent stuff for IMHO. It does have its own similar problems though - does a function return an error? If so you are going to need to plumb the error return through all the callers. Does a function need a context.Context? Ditto. I guess you can't win them all :-)

Same with the BEAM languages like Erlang, Elixir, and Gleam. Though it still bothers me that they call their green threads "processes".

They are (lightweight) processes since they have no shared memory. Each process has its own stack and heap.

Re: What color is your function? (2015)

#152
post #36

Earlier quoted context omitted.

Rust unsafe functions aren't a good example of colored functions because it doesn't exhibit the main issue brought up in the article, that one color can call the other but not the other way around. In Rust, unsafe code can call safe code, and safe code can call unsafe code. Calling unsafe code in safe code requires an explicit unsafe block, but that's fairly normal and not a hack to get around function coloring. A be…

I don’t really see how declaring an unsafe block is materially different for the purposes of this discussion than, e.g., entering an async runtime. It is code you need to write, tradeoffs you need to weigh, invariants you need to keep.

In Rust, if you have a function containing an unsafe block, you do not need to use another unsafe block to call the function. Therefore, unsafe is not “contagious” like JavaScript’s async.

Re: What color is your function? (2015)

#153

I've exclusively used async/await style languages for my entire life and have not once ran into this supposed problem of function colouring. Basically all IO/async work you do requires a context, does it matter if that context is a parameter or a keyword? I don't think so. The author is inventing a problem to rant about.

The author is definitely not inventing a problem. I ran into this issue at work this month.

We were using WPF, which is C# combined with XAML. I needed to call some async code. First, I tried to call it from synchronous code. That compiled correctly and seemed okay, but then I got vague crashes, and after doing research, I found everyone was like "don't ever call an async function from a sync function" for that exact reason. So instead, I had to change whatever called that to be async, and then whatever called that to be async, and so on. The solution I ended up having to go with was literally changing the code in over a hundred places. This is legacy code that I touch as little as possible, and instead of the one line fix that it felt like it should have been, async turned it into over a hundred small changes throughout the entire project.

I'm not saying there isn't a better approach. I'm pretty new to async/await code as I've been doing asynchronous code through threads my whole programming career. I don't think WPF is a good technology, so maybe some newer tech has solved it better. But what I can say is that this problem was not invented, it is a real problem and it caused a simple change to become a complicated one.

Re: What color is your function? (2015)

#154
post #10

I wish the key word was instead dontawait and was used inversely to how await is used. 99% of the time I'm using an async function, despite however slow it is, there's nothing for my code to do but wait for it to finish. But if for some reason I would like the next line of code to run before the current one is done, I'll let you know . Like, why can't my sync function await something asynchronous? If it has to lock u…

You mean like you just store the Promise in a var and await after you are done with the rest (JS like) ?

Re: What color is your function? (2015)

#155

I've spent the last year working on an async runtime for Zig and I really grew fond of stackful coroutines. Your just program your code as if everything was blocking. The main benefit is that you can use whatever library, it doesn't have to be async aware. Heck, I could even use C libraries, and they would work correctly with my coroutines. I really don't understand why GC-based languages decided to go with stackless…

What are your thoughts on the Io situation? Has your work been with the Io plans in mind from the beginning?

Re: What color is your function? (2015)

#156

I feel like this argument always boils down to explicit vs implicit. It tastes the same as static vs dynamic typing. Personally, I fall well into the explicit camp. I like when I can know stuff about a function without having to read its body, and the bodies of the functions it calls, and the bodies of the functions they call, and so on. And so, I like when I can see from the function signature that it returns an int…

For a lot of architectures its also irrelevant. I use sync code and I use async code in my architecture. But more like independent subsystems. They are sync internally and only few places have connections to outside systems or IO. Those can be async.

I do understand though that it can be annoying for library authors, especially those that need to interact with the FS/Network etc.

Re: What color is your function? (2015)

#157

I've spent the last year working on an async runtime for Zig and I really grew fond of stackful coroutines. Your just program your code as if everything was blocking. The main benefit is that you can use whatever library, it doesn't have to be async aware. Heck, I could even use C libraries, and they would work correctly with my coroutines. I really don't understand why GC-based languages decided to go with stackless…

> I really don't understand why GC-based languages decided to go with stackless coroutines

From what I've read it's due to a general idea that stacks use a lot of memory, which limits how many of them can be spawned. It's only good if it scales to a million concurrent users. A million 16 KiB stacks is over 16 GiB.

Re: What color is your function? (2015)

#158
post #10

I wish the key word was instead dontawait and was used inversely to how await is used. 99% of the time I'm using an async function, despite however slow it is, there's nothing for my code to do but wait for it to finish. But if for some reason I would like the next line of code to run before the current one is done, I'll let you know . Like, why can't my sync function await something asynchronous? If it has to lock u…

That's basically exactly what Go's `go` keyword does. Good design in my opinion.

Re: What color is your function? (2015)

#159
post #147

Earlier quoted context omitted.

The problem with function color exists when you can't abstract over it[1] Some statically typed languages (I believe both Haskell, ocaml) have powerful type system that allow abstracting over function types and function colors. Color is not an issue here. Some other statically typed languages (C#, rust, and C++ (at least with the built-in stackless coroutines)) can abstract over types but not over colors. This is a p…

> The problem with function color exists when you can't abstract over it Hopefully it's safe read this as there's no common static type between function and async function meaning APIs (that take functions as arguments) have to provide seperate methods (or overloading) for these different colours. Like in typescript you can write ` (f: () => T) => T` because an async function statically is just the return type wrappe…

Your first paragraph links having the colour in the type system as allowing you to write functions that take arguments of parametric colour; your last paragraph says you're unconvinced that you might also like to write functions that return results of parametric colour.

An example: a vector of things to a thing of a vector, for "thing" in (promise, option, result, ...). Such a function should only really return a promise if it's given a vector of promises, and, with an interface that "thing" supports, can be written generically for all those things.

(In Rust, there are separate implementations of that for Option and for Future.)

Higher-kinded types are the (a?) design solution, but they _do_ come at a cost, and for some that cost is higher than the cost of colours.

Post reply on HN