News for hackers. Stuff that matters.
Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @12:24PM (#34666679)
Author here.

It's interesting to see this posted after three years.

In fact, there should be "(2019)" in the Hacker News title.

After looking at the definition, I think it holds up well. I would probably tweak it, but I was three years less experienced back then.

It's weird to think that I posted that just two months before lockdown. It seems like I posted it long before that...

Re:Structured Concurrency Definition by mananaysiempre on Sunday February 05, 2023 @01:02PM (#34667100)
Small quibble with the article:

It refers to Trio nurseries as “scopes”. I thought about them like that for a while, but don’t think that’s not exactly the right view now. As a subroutine, you can’t (usually) reach up into your parent static or dynamic scopes and cause new objects to be created there and outlive your own dynamic extent. (Tcl exempted.)

Because nurseries are first-class objects, though, you’re free to create a root nursery at startup and stick it in a global variable, after which everyone is free to create as many Go-style unaccountable threads as they want to. It’s just that you don’t have to. Yet passing worker threads their originating nursery so that they can spawn more peer workers is a moderately useful pattern.

TL;DR: Firsr-class nurseries are not quite scopes because they don’t enforce strict lifetime nesting between a spawned thread and the thread that caused it to be spawned.

Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @01:16PM (#34667234)
One of the tweaks I would use is to use the word "lifetimes" instead of scopes. I think this would since the problem you see because each object, even a nursery, has a lifetime, and threads are tied to those lifetimes.
Re:Structured Concurrency Definition by MarkMarine on Sunday February 05, 2023 @01:10PM (#34667180)
More than just I read your article about C and memory safety today and went clicking around in the archive. Good work.

When I read the Go statement considered harmful post, I felt the same thing. This just makes sense, everything should be like this. A number of these ideas have been designed into Kotlin’s concurrency library, what are your thoughts about it?

Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @01:20PM (#34667265)
Thank you!

I haven't seen Kotlin's library, so I can't comment.

Do you have a link? I wasn't able to pull up anything good with a search.

Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @03:28PM (#34668965)
Thank you!

To answer the GGP, this looks like true structured concurrency to me. Chalk one up for Kotlin!

Re:Structured Concurrency Definition by manmal on Sunday February 05, 2023 @01:10PM (#34667185)
Do you think that what Swift implemented can be called structured concurrency by your definition?
Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @01:17PM (#34667237)
Yes. Swift beat me to it.
Re:Structured Concurrency Definition by rerdavies on Sunday February 05, 2023 @01:43PM (#34667547)
To the author: The disclaimer is needlessly @ssh0lish.
Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @01:46PM (#34667586)
On the post?

Not really. I've had people you after me for such things.

Re:Structured Concurrency Definition by rerdavies on Sunday February 05, 2023 @01:49PM (#34667612)
Now you have people like me after you for the disclaimer. There is another solution.
Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @03:25PM (#34668918)
Self-censoring isn't an option, but if you have another, I'd be happy to listen.
Re:Structured Concurrency Definition by rerdavies on Sunday February 05, 2023 @02:26PM (#34668119)
Kinda like std::jthread.

Definitely a good thing. But does that really justify the label "structured concurrency"? I was rather hoping to see something more, especially since languages like Rust, Go, JavaScript (and even Python) go much further.

Re:Structured Concurrency Definition by jerf on Monday February 06, 2023 @09:23AM (#34677624)
Go goes "beyond" structured concurrency in the same sense that BASIC goes "beyond" structured programming because it has a "goto" statement. That is, it goes "beyond" it by being incapable of guaranteeing it at all.

The entire point of structured concurrency or structured programming is to build limitations into the system, then build other guarantees on those limitations. If you don't have the limitations, you don't have the things you can build on it. Systems lacking those limitations do not "go beyond" the limitations, they lack the ability to build the guarantees.

I have been influenced in my Go programming by this essay. A lot of my concurrency is actually "structured concurrency" if you look at it. But you have to look at it to see, because there is no way for me to guarantee it structurally. No matter how much I use the ideas, no matter how much I were to write it into an API, I can never prevent anything from blasting a "go" statement whereever they want, whenever they want, and violating the limitations, and thus breaking the guarantees. This is not the end of the world some programmers treat it as; no language can do everything and enforce everything and be perfect without the programmer having to bring some discipline to the party. But neither is it no big deal at all and something you can just wave away with a vague statement about how some programmers just need to be better programmers or something. These things matter.

Re:Structured Concurrency Definition by mananaysiempre on Sunday February 05, 2023 @12:57PM (#34667042)
I like structured concurrency (in its Trio embodiment). I’d love to go all in on structured concurrency... except I see no way to marry it (or async/await-style syntax) to promise pipelining, which seems to be the only sane avenue to avoiding the roundtrip tax on fine-grained remote APIs[1]. Is anyone aware of any attempts in this area?

[1] https://capnproto.org/rpc.html

Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @01:24PM (#34667306)
I could implement something like this.

First, instead of calling a function, just add that function to a list of functions. Then when you're done, spawn a thread and pass it the needed data and the list of functions. The thread will work its way through the chain.

This technique is possible because "closures are just a poor man's object." (I think I saw that on the c2 wiki.)

Re:Structured Concurrency Definition by alwaysbeconsing on Sunday February 05, 2023 @01:50PM (#34667635)
> "closures are just a poor man's object."

Yes; the inverse is also true :) The "koan" is on c2 here: http://wiki.c2.com/?ClosuresAndObjectsAreEquivalent (with a link to its original source).

Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @03:24PM (#34668906)
Yes, that's the one!
Re:Structured Concurrency Definition by mananaysiempre on Sunday February 05, 2023 @04:30PM (#34669649)
(Musings not that relevant to asynchronous ocap messaging, where the problems don’t really depend on whether you’re passing around objects or closures.)

One thing I don’t think I’ve seen mentioned on those pages is the distinction between a “closed” object you can only send messages to and an “open” one you can inherit from / delegate to / mix in / COM-aggregate: the former is indeed a closure, that is some code and an environment, that you feed the message selector and some arguments and get a result out; the latter is also some code and an environment, but you feed it the resend target, the message selector, and some arguments. So depending on what exactly you’re calling an object, an object is a closure... in one of two non-equivalent ways. Maybe not really a closure then?

See also for not-quite-identical points of view: Piumarta’s note on prototypes in his COLA system[1]; Chisnall’s description of the (IIUC now-dead) new Objective-C runtime for Étoilé[2].

[1] https://www.piumarta.com/pepsi/prototypes.html

[2] https://www.jot.fm/issues/issue_2009_01/article4.pdf

Re:Structured Concurrency Definition by jerf on Monday February 06, 2023 @09:14AM (#34677516)
That's actually the point of the koan, in many ways. It is not true that an object is a closure and a closure is an object, in the sense that they are exactly the same in every way. Clearly they aren't, or we couldn't even have separate terms for them.

The point is more that there is not a set of "closure problems" and a set of "object problems" that can only be solved with the relevant technologies. You can always put together a solution to a problem with the other technology. It may have different cost/benefit tradeoffs. It may have different affordances. I would certainly advise against walking into an object system and trying to force it to solve every problem by objects functioning as closures, and I would advise against walking into a closure system and trying to force it to solve every problem by forcing closures to work like objects. One should work with the grain of the wood you are working in rather than insisting on treating the wood like the pottery you are more familiar with.

But it is always helpful to remember that within every object system is a closure system if you really need it, and within every closure system is an object system if you really need it. The resolution to "how can each be a subset of the other without them being equal to each other" is that there is some equivocation here. The object system that closures can implement conveniently is less rich than a dedicated object system, and vice versa. But if you just need to momentarily borrow the alternate concept, you probably don't need all the frippery you need if it is your primary tool for interacting with the world, so it works out.

Re:Structured Concurrency Definition by convolvatron on Sunday February 05, 2023 @01:38PM (#34667485)
is similar to nested dag? not exactly because it can contain loops, but children never outlive their parent?
Re:Structured Concurrency Definition by gavinhoward on Sunday February 05, 2023 @01:45PM (#34667570)
Basically, though I've also extended the idea since.
Re:Structured Concurrency Definition by kzuberi on Sunday February 05, 2023 @01:55PM (#34667714)
A useful introduction to the ideas is in Nathaniel's PyCon 2018 talk on trio [1], where he live-codes a solution to a concurrency-spaghetti problem.

[1] https://www.youtube.com/watch?v=oLkfnc_UMcE

Re:Structured Concurrency Definition by samsquire on Monday February 06, 2023 @08:52AM (#34677257)
Thank you for this.

If you found this interesting then you shall like the following pages:

The Vale language blog post on seamless structured concurrency https://verdagon.dev/blog/seamless-fearless-structured-concu...

The rust book on concurrency https://doc.rust-lang.org/book/ch16-00-concurrency.html

I've been working on implementing Java async/await state machine with switch statements and a scheduling loop. If the user doesn't await the async task handle, then the task's returnvalue is never handled. This is similar to the Go problem with the go statement.

https://github.com/samsquire/multiversion-concurrency-contro...

If your async call returns a handle and the handle is linked to a scope then in theory the async/await could be used as primitive to structured concurrency.

I journal about asynchrony and parallelism everyday in ideas4 (see my HN profile)

Re:Structured Concurrency Definition by TYMorningCoffee on Monday February 06, 2023 @09:24AM (#34677636)
Structured concurrency is in Java 19 early access [1]. Try it out! They reuse the try with resources to implement it.

[1] https://openjdk.org/jeps/428

Re:Structured Concurrency Definition by marssaxman on Monday February 06, 2023 @11:32AM (#34679870)
Thanks! I hadn't encountered this idea before, and the essay kicked off several hours of reading and learning. This will definitely influence my approach to all concurrency problems in the future.