Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we rename nurseries? #504

Closed
njsmith opened this issue Apr 18, 2018 · 88 comments
Closed

Should we rename nurseries? #504

njsmith opened this issue Apr 18, 2018 · 88 comments

Comments

@njsmith
Copy link
Member

njsmith commented Apr 18, 2018

OK, let's do this.

Question: Should we rename "nurseries"? It's something that keeps coming up, and while it would be somewhat painful to change now, it'll be pretty much impossible within the next 6 months... so I guess now is the time to have a discussion, and if we decide not to change it then this can at least become the canonical issue that we link people to when they ask about it.

The most common version of this complaint is something like: "ugh, nursery is so cutesy. What about TaskGroup, or WaitGroup, or TaskScope, or something like that?" I don't find this version of the complaint compelling, so let me start by explaining why that is.

Names like TaskGroup, or TaskScope are excellent names for ordinary classes, the kinds of name we invent every day. For that kind of class, you want something that's descriptive, because you have a lot of them and people don't spend much time with any given one. And of course you want to follow the conventions, so the camelcase itself is informative: even if you aren't familiar with the particular class in question, you at least can tell at a glance that it is a class.

Nurseries, though, are a different kind of thing entirely. They're a new fundamental concept: you have to learn them up front, like you have to learn about for loops, and functions, and the difference between an object attribute and a local variable. Once you've used them for a few days, they recede into the background as part of your basic vocabulary. And they're just different from the concepts most people already know, so trying to give them a familiar descriptive name is actually misleading: you have to look them up and learn them. So, I want a name that feels like a primitive, like "for" or "function" or "variable" – something short and lowercase. And if anything, something that's a bit opaque and unfamiliar is probably better, because it signals "hey, new concept here". You can't have a lot of concepts like that, but nurseries are carrying an entire programming paradigm on their shoulders, so I think 1 new word is within our budget.

And regarding it being "cutesy": This doesn't really bother me, given that (1) this is a domain where "reaping orphan zombie children" is already considered totally ordinary technical language, and (2) after you use nurseries for a few minutes the name stops feeling cutesy, just like you stopped noticing that "trees" have nothing to do with botany, "functions" often don't function (little debugging joke there), "threads" have nothing to do with textiles, etc. So like... ok, it's a bit cutesy but whatever, people will get over it. And being cutesy actually has some upside: the whole joke about "a nursery is where child tasks live" probably does help it stick in people's minds. OTOH, I'm not like super attached to having a cutesy name either; I think it's mostly a neutral attribute.

So that's why I'm convinced that "nursery" is better than TaskGroup or similar.

But...... when talking to @graydon about this today, I did have some doubts about "nursery", for two reasons. The first is, he pointed out that "nursery" is also used as jargon for generational garbage collectors (to refer to the youngest generation, which often gets special handling). So a language implementer might ask "is this task in that nursery?", and "is this Task in the nursery?" and those are two completely unrelated questions. Fortunately it's mostly implementers who encounter the GC version of nursery, but still... this is a legitimate collision.

And the other is, I realized that the name is actually a bit less apropos since #375 landed and we tweaked the nursery semantics. Originally, I really wanted to emphasize the idea of "supervision", because we had the whole "parenting is a full time job" rule where the parent task had to park itself at the end of the nursery block or exceptions wouldn't propagate and stuff. Now the supervision part has dissolved into becoming an implicit part of the runtime, and doesn't really exist as a concept at all anymore – it's just, like, exceptions propagate themselves, what is there to talk about. The code inside the nursery block is just a slightly-special child. So that part of the metaphor has become a bit weird.

So here's another idea: maybe we could use a name that emphasizes that this is a place where your call stack splits/branches/words like that. Like, async with trio.open_split(), or open_branchpoint, or something like that? With the metaphor being that first you make a note "here's a point in my call stack where child tasks might split off", and then calling start_soon actually attaches a new branch there. I'm imagining like a hinge or a hook or something.

Anyway, that's just one idea – if y'all have other ideas I'd be interested to hear them, and ditto any thoughts on how the "nursery" name worked for you as either a newcomer to Trio or as you've become more experienced.

@pquentin
Copy link
Member

The nursery name works fine for me. It's well explained in the tutorial, and I liked the cuteness! 😄

split and branchpoint work too, but how would you call the resulting object? I think nursery.start_soon(fn) works slightly better than split.start_soon(fn)? Or is it because I'm used to nurseries?

Anyway, I'm not personally opposed to a change, as it would be easy to adapt to a new name.

@jab
Copy link
Member

jab commented Apr 18, 2018

What do you think of childminder?

To me it has a lot of the same helpful properties as nursery:

...but isn't (to my knowledge) overloaded with another programming meaning, and also directly refers to the existing-programming-concept "child" in the name, and so maybe avoids some of the cutesiness that some people have found distracting?

That said, I'd be fine with keeping nursery and fine with a change too. </$.02!>

@apexo
Copy link

apexo commented Apr 18, 2018

While I kind of like nursery, just for the heck of it, here's my random proposal:

If parenting isn't a full-time job anymore … maybe it's actually fun? Like a party?

So let's trio.start_party() and invite tasks to party together w/ party.invite(task) ?

@jab
Copy link
Member

jab commented Apr 18, 2018

Not sure about open_split. The word "split" is overloaded, and so doesn't necessarily invoke any obviously-intended associations immediately. Further overloading an overloaded term can add to cognitive load. It also doesn't signal "learn this important foreign concept!" to me as much.

The term "branchpoint" is better than "split" on both counts. But both "split" and "branchpoint" give up direct association with the concept of "children".

@Fuyukai
Copy link
Member

Fuyukai commented Apr 18, 2018

I'm perfectly fine with the nursery name as is.

@smurfix
Copy link
Contributor

smurfix commented Apr 18, 2018

@apexo You still can't leave the party. You (as the "host", i.e. the nursery's initial task) can just decide to do your own thing while the party is ongoing, just like every other party guest.

My preferred name, should we decide to switch the name, would be the rather boring "task manager", or taskmgr.

That being said, I'm also OK with keeping the name. "Branchpoint" … well, maybe. @jab it does for me.

@smurfix
Copy link
Contributor

smurfix commented Apr 18, 2018

Personally: when I came across this nursery thing, I thought, OK, new name, new concept I actually need to think about instead of assuming that I already know what it's about. Which is exactly what we need to get across.

I didn't know about nurseries WRT garbage collection. However our nursery is very obviously not about GC, so I don't think that in practice there's much confusion. I'd be more wary about a name like branch since in if FOO then BAR else BAZ, BAR and BAZ are different branches of execution – a concept which (a) many people have already come across and (b) is in roughly the same realm, so more danger of confusion.

@touilleMan
Copy link
Member

I like nursery

And the other is, I realized that the name is actually a bit less apropos since #375 landed and we tweaked the nursery semantics.

I think the name is still valid even after #375.
Before this change we could see the main coroutine which open the nursery as the nurse which will take care of the child-coroutines.
After the change the main coroutine is just a lazy parent who drops it children-coroutines to the nursery and go have a beer do it own work.

@graydon
Copy link

graydon commented Apr 18, 2018

Attempting to make a positive contribution (browsing thesaurus looking for new names is a favourite pass-time anyways) I might suggest:

  • supervision-related:

    • custodian
    • steward
    • caretaker
    • porter
    • attendant
    • concierge
  • childcare-related:

    • creche
    • cradle
  • tree/splitting-related:

    • outgrowth
    • bifurcation
    • partition
    • branch
    • sprout <-- personal fave
    • offshoot
    • bough
    • limb
  • organization-division related:

    • subsidiary
    • office
    • branch, also
    • division
    • department
    • chapter <-- has a nice "part of a story" secondary resonance

@njsmith
Copy link
Member Author

njsmith commented Apr 21, 2018

My issue with options like sprout/bough/limb is that those sound like they refer to the children, while we need a name for the point where the children are attached.

@smurfix has a good point about "branch" already being overloaded, and as a control flow thing, so that's definitely confusing.

Of the nursery alternatives... maybe "splitpoint" is the best I can come up with so far? (As in, "this is a point where control can split".) It has some resonance with "checkpoint", which is our other bit of funny terminology. Something like:

async with trio.open_splitpoint() as splitpoint:
    splitpoint.start_soon(...)

I actually kind of like how this de-emphasizes the concept of "children", since trio doesn't really reify tasks/threads/whatever-you-wanna-call-them. There are no task ids or task objects or anything (unless you go digging into trio.hazmat). OTOH we still need to refer to the different concurrent functions in conversation -- I suppose we could call them "splits", like: "While the first split is doing name resolution, the other splits are waiting...". Maybe that's too weird?

("sproutpoint" is also an option, but that might be too silly even for me :-).)

I suppose there's also

async with trio.open_family() as family:
    family.start_soon(...)

but I feel like "family" is too commonly used as a kind of generic word for "category". "This family of concurrency frameworks uses families...", ick.

@dhirschfeld
Copy link
Member

kindergarten

@dhirschfeld returns to lurking

@dhirschfeld
Copy link
Member

Seriously though, I thought nurseries was a little cutsie at first, but it didn't really bother me [1]_.
Now, I actually think it's a very good name and better than any alternative I've seen / thought of.

.. [1]: Full Disclosure: I use a data processing library called "pandas" on a daily basis and that also doesn't bother me! 😜

@smurfix
Copy link
Contributor

smurfix commented Apr 21, 2018

My problem with splitpoint or similar pointy names is that a point, conceptually, is just there. Like in geometry, it doesn't do anything.

My personal favorite still is a task manager. Maybe with trio.manage_subtasks() as mgr: await mgr.start(…).

@njsmith
Copy link
Member Author

njsmith commented Apr 22, 2018

My problem with splitpoint or similar pointy names is that a point, conceptually, is just there. Like in geometry, it doesn't do anything.

That would be the point though :-). (No pun intended.) When you type open_splitpoint, you'd be marking a place in the call stack where you could potentially hang off other children/sprouts/whatever:

f1 -> f2 -> (splitpoint) -> f3

This doesn't actually do anything. Then later, when you call start_soon, that's when something actually happens:

f1 -> f2 -> (splitpoint) -> f3
                       |
                       +--> f4

@smurfix
Copy link
Contributor

smurfix commented Apr 22, 2018

Well, in geometry you (mostly) don't just arbitrarily draw a point – the point exists as a consequence of something else (like two lines intersecting). Afterwards, other things exist as a consequence of the point being there (like a line being defined by two points). In both cases the "active" parts are the non-points.

shrug maybe I'm overthinking this … on reflection I'm like -0.1 on splitpoints-or-whatever, -1 on branchwhatever, and +0.1 on keeping nursery.

@sorcio
Copy link
Contributor

sorcio commented Apr 24, 2018

To me, splits/branches/sprouts suggest the point where things go different ways but not so much that they eventually merge. When thinking in spacial terms they might be the same thing, especially if you're used to visualize tasks in a tree, but it doesn't translate well to the idea of concurrency (multiple things running at the same time over parallel lines).

Maybe, given our peculiar semantics, it makes more sense to call the nursery a merge/join/muster point and use splitting/branching/forking/sprouting to refer to what now is the nursery.start operation.

The idea of supervision is lost but, well, so it is in the paradigm of calling/returning functions (either sync or async) which in some ways is a close relative to this. Instead of waiting for one function call to return or raise, you're waiting for many concurrent ones. What's so special about that? 😉

@graydon
Copy link

graydon commented Apr 24, 2018

splits/branches/sprouts suggest the point where things go different ways but not so much that they eventually merge. ... it doesn't translate well to the idea of concurrency (multiple things running at the same time over parallel lines).

This is why I highlighted above the term chapter as having both organizational-structure gloss and a part-of-a-sequential-book gloss: the more I think about this the more I think it might be a good (mixed) metaphor. In the org-chart-sense it's definitely part-of-a-hierarchy. But in the book sense it's a block-structuring element of a sequential story that introduces-and-concludes a bunch of specific scenes, and maybe lets a couple threads of the plot connect-up with those from earlier or later chapters.

It also includes (unlike all the options here -- including nursery!) the concept of conclusion, as you say. The term evokes both "beginning of chapter" and "end of chapter" -- things started and things wrapped-up -- in almost equal measure.

@theelous3
Copy link

theelous3 commented Apr 25, 2018

I like my concurrency libraries like I like my concrete. Bland and functional. TaskManager

To use it in a sentence:

"The TaskManager manages its tasks."

Inessential weirdness and all that.

@jpfed
Copy link

jpfed commented Apr 25, 2018

A common/boring name for a collection of jobs is a batch.

If you want a name that reflects some control-flow analogy...

Collections of threadlike things bound together at both ends are

  • bundles
  • fascicles (okay, that's weird, but maybe? They're hierarchical bundles of bundles of.., which is pretty cool)
  • sheaves (maybe confusing if someone knows the mathematical definition of sheaf, which I don't)

Places that things leave and then return to

  • nest (keep the cutesy!)
  • camp

Portmanteau silliness: daglet

@canadaduane
Copy link

chapter really works for me. It's short, concise, and builds on a well-known literary concept with an emphasis on beginning and ending, with stuff happening in between. It doesn't assume anything about the nature of the story--whether child labor or worker robots--and it makes sense to talk about passing a chapter around to functions, e.g. "Which chapter [of the overall book/app] am I in?".

@feluxe
Copy link

feluxe commented Apr 26, 2018

This is fun! :)

Some more:

  • track
  • passage
  • stage
  • phase
  • portion
  • hive

@albertogomcas
Copy link
Contributor

I have no issues with nursery, this is a python library and playfully named libraries are commonplace.

Anyway, nobody is shocked in this context about parents, children, (and infanticidal moves as killing children!), nursery is just a little blip that stops felling weird after you have seen it 12 times.

One analogy that has not been raised yet is the hub/spokes, but I am not fully convinced myself...

@oremanj
Copy link
Member

oremanj commented Apr 26, 2018

I like the name "nursery". If we choose a new one, I'd hope that it share some of the properties of "nursery" that make me like it:

  • not in common usage elsewhere (as mentioned, maybe we can do even better than "nursery" in this regard, but I don't think the GC term overloading is a substantial issue)
  • short and easy to type (I think seven characters is substantially better even than the ten in "splitpoint")
  • doesn't invite ambiguous abbreviations (mgr could be a ThingManager for just about any value of Thing, and a large program might have a lot of those)
  • reads well in the trio pattern of open_thing() being a function that returns a context manager that scopes the lifetime of a new thing
  • not too cutesy (I think "party" might be going a bit too far in that direction)
  • suits the context in which it's used reasonably well - it doesn't have to be obvious without an explanation, but the explanation should make sense

I'm not sure it makes sense to switch for a name that's only infinitesimally better than "nursery", since there are switching costs. I don't feel like any of the names proposed so far are substantially better than "nursery", though I do like several of them.

Some random further thoughts:

  • "custodian" is in common usage in Scheme, I think, and refers to a sort of scope for all resources - when a custodian is shut down, all files created in its scope are closed, threads are killed, etc. IMO it's similar enough to the nursery idea to make the differences a potential point of confusion for Schemers.
  • The unit-of-an-organization meaning of "chapter" doesn't jump out at me nearly as much as the book-subdivision one does, so it feels like a mixed metaphor - the instinctive objection is "my program isn't made of chapters, that's for books! programs are made of (modules|packages|functions|...)". Nursery doesn't have this problem because nobody talks about dividing things into nurseries, in any domain.
  • I quite like "hive" and "nest", and they're very short and non-overloaded (as long as no one tries to write a trio library for controlling a certain trendy home thermostat...), but I think they score worse on "likely preexisting associations link to correct concepts" than nursery does.

@zmitchell
Copy link
Contributor

I don't really mind the nursery naming. If we do change it I wonder about a transportation analogy. Buses/trains/airlines tend to have hubs or central dispatches that buses/trains/planes leave from and eventually come back to. Something along those lines has the connotations of management, coordination, or authority.

@Mec-iS
Copy link

Mec-iS commented Apr 28, 2018

Just an aesthetical subjective opinion from an amateur philologist, I would call them 'beacons' or 'cocoons' if you want to keep a biological-like sounding. If you want a more techie-industrial-crafting narration, maybe 'foundries' or 'workshops' it is more appropriate. A potentially helpful note, the whole library's concept and the arrows-like diagrams in your post made me think much about 3D-printing.

Thanks for your work.

@agadabanka
Copy link

The name nursery feels very dynamic and apt. It represents progress (growth) and chaos that is being constantly monitored on behalf of the parent process, which was responsible for the creation or the split. The metaphor is great - parent can just let the nursery manage the process while they take care of their work, with the how's of nursery being a black-box. Also, the name nursery stands out in the excellent blog post as something familiar w.r.t concurrency in everyday life, yet something I would want to read more about in the context of Trio. Irrespective of the simplifications in the implementations, the core idea behind a nursery resonates almost immediately for a first time reader and makes it approachable to take their first steps.

@linkmonitor
Copy link

linkmonitor commented Apr 29, 2018

A coworker of mine suggested spool.

One could make the obvious connections with threads/threading and, if we stretch it, (sp)awn p(ool).

@maffoo
Copy link

maffoo commented May 4, 2018

One problem with the name "nursery" is it only conveys that this is a place where new tasks can be spawned. But the really important thing about a trio nursery as I understand it, and in particular the thing that distinguishes it from other libraries' APIs for launching concurrent tasks, is that it also bounds the execution of all the tasks launched within it. That is, the nursery doesn't exit until all its child tasks have exited. The "nursery" metaphor doesn't convey this, in fact quite the opposite: most things born in nurseries grow up and leave the nursery to live their adult lives (especially if the nursery is working well and not prematurely killing it's charges :-) ).

I would favor a name that covey's this "boundedness", that no task started by this object will outlive that object. But I don't really have a good suggestion. I like variants of "scope", but @njsmith already rejected "TaskScope". I also like "lifetime", but that doesn't have the whimsy of the current name.

@dsentinel
Copy link

I like nurseries, the cuteness is moderately (subjectively) appealing, but this may lend itself to the larger appeal below, and it maintains with the analogy that it contains children (although breaks a bit as the child coro's entire life is in the nursery (death in nurseries! :)).
The biggest appeal is that it doesn't have a namespace collision with the abstract mental stack dev's have
e.g.
'Process' is a bad name it as it already has a vague, abstract definition and dev's could already have other uses in there mental and design model, in and out of programming; I have to process this file as input, this munge process, these sequential steps are a process, design process, etc...
Or worse, if they're developing at a factory and the design spec has 'process' throughout, and they're writing mutli (posix) process code. Every time a dev types, reads or thinks process they have to disambiguate. A small extra mental tax.

Whereas 'thread' is wonderful (thanks Victor A. Vyssotsky!) it has a decent analogy; 'interwoven', 'light', 'thin', 'many together create something larger' but when you read 'thread' in code you know exactly what it is! It was coopted with email, sorry for the devs' of multi-threaded email apps.

Guess what the first threads were call? "TASKS" (OS /360 MVT) another terrible name that would be causing a collision on some of the suggestions already placed here, and if it stuck asyncio would have perhaps avoided using the name 'Task' to avoid confusion with what is now threads.

Working on a project with data streams and io streams I needed a name for a higher order 'data flow pipeline' at first I coopted and reused the name 'stream'. Halfway through I renamed it to 'creek'. I didn't like that it felt 'small and unperformant' but it removed a mound of confusion.

For this reason create names that unique and concrete first, and have a fitting analogy second. Nurseries are good in this way. Yes it's completely foreign at first, but as soon as you learn it's definition, which is necessary as a central concept to curio's async block model, you know it's that curio block thing, never any confusion.

As the nursery model is not specific to curio, perhaps a better fitting and widely adoptable name is out there to be found. Perhaps nurseries are fine, and just have to stick.
Perhaps 'thread' was considered cute or unfitting and had opposition in 1966, but I'm glad it stuck. Likewise for port/stream/stack/queue. All of these were coopted from something physical and are concrete. It's nice when the analogy is very well aligned, but once it's adopted it feels correct.

I wish that abstract names like process, job, and task were left out of the stack of OS's/languages/frameworks so devs could use them without collisions.

@stevenjackson121
Copy link

stevenjackson121 commented Jul 3, 2019

@njsmith, you speculated one year ago that a name change could become practically impossible within 6 months or so. Is there still any merit in debating the best/most appropriate name? (If so, do you have an updated estimate on how quickly it would have to happen, if it does?). I know you mentioned two months ago letting it ride "a bit longer" while you figure other things out, but I agree more with your initial reasoning that such a central part of trio should be stabilized ASAP

My thought is that this issue has been open for a year, nothing has come up in that time that's obviously better than nursery (and better enough to justify the cost of switching) and I feel it's increasingly unlikely any such name will be found (I personally favor taskgroup but not enough to argue strongly for it). On the flip side the cost to switch is only increasing.

We might be better off closing thus issue and devoting our collective mental energy in areas with a better chance of having a return on that investment.

@markfink
Copy link

markfink commented Jul 18, 2019

to be honest I was a bit irritated at first by the name open_nursery but now I am totally fine with it.
Anyway, I believe in good names and if you are going to rename this you should IMHO use "split_control" since it is what the context manager does:

async with trio.split_control() as split:
    split.start_soon(sum_numbers, 0, 50000000)
    split.start_soon(sum_numbers, 50000000, 100000000)

@Ricyteach
Copy link

Ricyteach commented Sep 20, 2019

This discussion has probably run its course.

But after reading over the thread this morning I had an original idea that I think communicates a lot of things at the same time, and also remains true to the whimsy of nursery:

asylum

Similar to a task in an asynchronous part of a program: you generally don't leave the asylum, and lot of crrraaaazy things go on inside.

@mentalisttraceur
Copy link

mentalisttraceur commented Jan 15, 2020

Should this still be open?

If so, I have four things to say:

  1. Description of my initial reaction to the name "nursery"
  2. An aside, countering the idea of prioritizing shorter identifiers
  3. A suggested rename (which has very short identifiers anyway)
  4. A defense of "nursery".

Initial Reaction to "nursery"

When I first encountered Trio a year or so ago, I found the name awkward to fit for like a literal second, but then I just internalized it and moved on.

For me it was a mentally cheap operation to mutate the meaning of "nursery" in Trio's context from "somewhere that children live" to += " and die".

(Actually I did at least two parallel ways of making it make sense in my mind. The other one that I currently remember is: a child coroutines is always a child, so it can never leave the nursery.)

I maybe experienced subtle brief background irritation at the choice to use a name that was more "cutesy" than it was self-explaining, but once I understood it I could see it as "close enough" to self-explaining and felt fine with it.

My first exposure to structured concurrency was Sustrik's libdill and blog articles, not Trio, so that probably influenced something, but I do not remember debug traces of that cognition.

Aside On The Push For Short Names

I am trying my best to empathize that some people actually feel the extra effort or tedium of typing "long" identifiers starting around seven or eight characters (which is just mind-boggling to me, but I'm trying to stay mindful that experience is relative).

However, I have learned to not consider it even acceptable - let alone good - to optimize code for writing convenience, unless uncompromising priority is given to optimizing for reading.

Code must be optimized at every turn to guide as many future readers as possible to a correct decode. This includes not only its big-picture intent and its business logic but also of every assumption, expectation, and implementation detail which is at all relevant to it working right.

That is not to say that short identifiers are bad - all else being equal, shorter identifiers are strictly better - in fact more readable - than longer ones.

But those are still optimizations for reading. They are emphatically not optimizations for writing.

Rarely have I seen optimization for shortness that did not neglect some aspect of what goes in to making code readable - including being informative, self-describing, and easy to search, navigate, and hop around.

Optimization for writing convenience was almost always a key cognition flow causing that neglect.

If you want or need to type short names for writing convenience, I truly wish you the best experience with that, but please don't inflict code optimized for your writing experience onto other people to read.

That cost should be borne by automated tooling, once, when the code is written or saved or committed, not by every reader of the code who comes later.

Thankfully I'm fairly confident that @njsmith will not trade readability/clarity/self-explanation/guiding-to-correct-interpretation for writability, based on what I've seen of his work so far.

What about fork?

I haven't decided if this is actually better, but I like it, and no one has suggested it:

async with trio.open_fork() as fork:
    fork.start_soon(foo, ...)
    # or maybe even just:
    fork.soon(foo, ...)
    ...

The biggest advantage is that the code that a nursery covers is a fork in the execution paths - the spot where a linear call flow forks into a call tree.

The biggest disadvantage is that the word "fork" is already used in Unix-y programming for forking a new process.

Now I have rarely needed to refer to that as "the fork" or "a fork" - in those cases I usually say "child", "forked child", or "forked process", or naturally use the verb "fork" in a phrase like "the process forks" or "forks a process" - so I don't think the collision is too bad. Even in a codebase that does both, the terminology naturally lends itself to disambiguation: "forks a coroutine", "the coroutine forks a new process", "by forks a coroutine or forks a process?", etc.

It's also not ideal for searchability or for signaling that there is a new concept, but a good point was made that as structured concurrency gains ground, it will just be a standard concept.

"Fork" does not imply the boundedness that structured concurrency makes its central tenet - forked processes outlive their parents all the time. But if unstructured concurrency goes the way of the goto, we won't need to disambiguate that. The "for loop" term does not try to encode or hint at the exclusion of unstructured jumps into or out of it - it is simply a feature of a language to make that impossible.

Anyway, I like start_soon a lot already, but I can defend fork.soon, because as a verb, "fork" already implies starting the execution path, and "soon" retains the important reminder that it will be scheduled later, once permitted.

(I also considered: fork.branch but people above mentioned that "branch" already has a strong and nearly universal association in programming to mutually exclusive execution paths; fork.prong but it loses the "soon" reminder; fork.tooth but I think people are less likely to recognize it than "prong"; and fork.tine but that's just even more obscure.)

Also, the physical object that maps to the word, a fork, has a clearly defined end. A fork's prongs stay attached to its body - it takes some effort and force to break a fork's prong off its body, and it's an obviously bad idea which leaves you with a broken fork.

We could even start calling unstructured concurrency as "fork breaking": like

  • "wow that code was so hard to follow, it had broken-off forks everywhere" (that just sounds bad even if you don't know what it is, which is a good property for stuff like this), or

  • "hey Bob, good code, just one thing to fix before we can merge: you broke off one of the ends of the fork over here, let's think of a way to do this with structured concurrency instead."

Nursery is Fine

Honestly, if you just left it as "nursery", I wouldn't be bothered.

A key advantage that I haven't seen explicitly mentioned is that it is searchable - that nursery does not collide with any existing programming term is not just helpful to human cognition: it also helps searching, whether in some code with a dumb text find or in a search engine, etc.

I mean sure, you can add "structured concurrency" to a search engine to narrow things down, but that's only if you already know what to look for. Imagine an unfamiliar newbie trying to look up "programming nursery" after hearing about the concept vs "programming {split,fork,tree,task group}" or whatever.

@mentalisttraceur
Copy link

I was thinking more about the above fork suggestion, and I've updated my last comment with some of these thoughts, but I want to elaborate on some of those additions:

"Fork" does not imply the "boundedness" that structured concurrency makes its central tenet - forked processes outlive their parents all the time. But if unstructured concurrency goes the way of the goto, we won't need to disambiguate that. The "for loop" term does not try to encode or hint at the exclusion of unstructured jumps into or out of it - it is simply a feature of the language that such a thing is impossible.

I think the key thing here: "nursery" is optimized for a world where structured concurrency is new, a world where it needs to be discovered and searched for and distinguished because it is beset on all sides by unstructured concurrency.

What would we name it in a world where structured concurrency is the way? If unstructured concurrency was simply unavailable or even unconceivable to most programmers, even treated with knee-jerk bigotry by some in its more limited forms, like the modern goto?

I'm reminded of some of the discussions I've seen on @njsmith's "Notes On Structured Concurrency". I've seen at least one person respond to it by saying "well, a function call is still a jump to anywhere", not seeing that it's a distinctly more limited jump that can be expected to go only to well-defined entry-points and to always come back out of the same spot. Presumably because they've never had enough reason to mentally step through code able violate that expectation, so their mind simply does not automatically conceptualize such code flows vividly and clearly enough for them to fully connect and feel the weight of the comparison.

If the world was similar with structured concurrency, does that change the way we think about what the best name should be?

Would my idea about optimizing for searchability make as big of a difference? Would the need for a distinctly new term make as big of a difference? Probably not.

At that point I wouldn't even worry about "'fork' does not disclaim the association with how a forked child process can outlive its parent", because by then operating systems and every library would provide robust primitives that prevented child processes from outliving their parents too, and "oh actually a forked process/thread/coroutine can outlive its parent if you [old deprecated API]... it's a backwards compatibility thing from back in the day, in a modern system you'll never run into it" would be the only way a typical person even learns that it is possible.

(Aside: I think we can actually implement structured concurrency at the OS process level already, using things like process groups and sessions, which have existed since old UNIX days on every UNIX-y system. It's just that there are no libraries or CLI interfaces in widespread usage that do this, as far as I know.)

Anyway.

When we get to that point, "nursery" will stand solely on its association to the concept of children, and from that word the association to the concept of child coroutines.

Let's look at it this way:

What do you call the block of code inside the async with trio.whatever() as whatever2?

Now does that term still work if it was a built-in language feature, with dedicated syntax, like whatever { /* my coroutine forking code here */ }?

One of the reasons why I think I'm drawn to my "fork" suggestion is that it generalizes. I spend enough time dealing with multiple programming languages that I've gotten used to looking for terms and wording habits I can reuse regardless of language.

If I needed to refer to that spot of code verbally, without referring to a specific implementation's word choices, I think I'd call that the "fork block" or even just the "fork" - if I needed more context I'd say something more verbose or specific once per conversation to pin it down, and then thereafter use "fork".

Why? Because I could keep reusing that term no matter what language I switched to, or even if the underlying way of concurrency was coroutines or threads or processes.

Now maybe that's a rare and irrelevant use case. I usually do use the terminology of the language/library/whatever I'm dealing with in context.

Also, I just realized (or more like remembered or even more like consciously pinned down): even in the absence of a culture where structured concurrency is the norm, a "fork" brings up a nice physical analogy, which I've gone ahead and edited into my prior post but which I'll quote here for linear reading flow:

Also, the physical object that maps to the word, a fork, has a clearly defined end. A fork's prongs stay attached to its body - it takes some effort and force to break a fork's prong off its body, and it's an obviously bad idea which leaves you with a broken fork.

We could even start calling unstructured concurrency as "fork breaking": like

  • "wow that code was so hard to follow, it had broken-off forks everywhere" (that just sounds bad even if you don't know what it is, which is a good property for stuff like this), or

  • "hey Bob, good code, just one thing to fix before we can merge: you broke off one of the ends of the fork over here, let's think of a way to do this with structured concurrency instead."

That analogy will be weaker for people who deal enough with Unix-y programming to strongly associate "fork" with splitting processes, but the terminology is still unambiguous per my earlier remarks, and Windows-y programmers or programmers who stick to higher level APIs will be untainted and free to benefit from the association/analogy/visual.

Anyway, returning to my point:

When we get to the point that structured concurrency is the norm, if "nursery" is not enough of a stable optimum, it will simply get evolutionarily outcompeted. People will start calling it something else, whatever is more mentally easy and accessible, until eventually one of those alternatives catches on to the point that its usage hits critical mass.

For example, we already do use a general language-neutral term, not for this exactly, but in the general vicinity of it, a more general concurrency concept: call tree.

It also implies boundedness, the same way that "call stack" does - a child function can't just re-parent itself to a different spot in the call tree just like it can't re-parent itself up the call stack (semantically, anyway - tail call optimization or trampolines may avoid a traditional call stacks/trees at the implementation level).

But it doesn't map as well to Trio's API "shape"... best I can think of right now is something like:

async with trio.call_tree() as call_tree:
    call_tree.branch_soon(foo, ...)
    # or maybe
    call_tree.fork_soon(foo, ...)
    # or maybe even `as call` above and then:
    call.soon(foo, ...)

And that's not ideal. Furthermore each nursery only represents a branch point or... ahem, fork... in a program's call tree, not a full actual call tree, because it does not contain or represent any of the nurseries opened below/within it.

Of course "fork" was my attempt to extract the same meaning that "branch" gives in the context of talking about call trees into an independently stable form.

So we can already see the process in action, which once again finally brings me back to my original point:

At some point, a new term will catch on, if "nursery" isn't "good enough".

The term nursery can live on past that point for a while in code which keeps using Trio or other libraries which have the term wired into their API, and those working with such code will get used to the exchange "what's a nursery?" "oh it's just this library's term for {task group,fork,split,call tree}", until enough pull requests or issues or forks or alternative libraries build up expressing humanity's want for a different term.

And that's probably okay. It's okay to just wait for that, wait for "humanity to decide", wait for natural selection to bring the most currently human-friendly term to the most widespread usage.

It might not get us the best terms, but it'll get us terms, whether or not we try to come up with our own. And usually the terms are alright. Usable enough. Precise enough and unambiguous enough in context, etc.

On the other hand, trying to talk about it is us participating in that process - picking a better word is influencing the process. In theory, a convincing argument here, or a change in naming in Trio, could help spread a given terminology that needs just that edge to win.

Which is fine - but the question is:

Are we at that point yet? Because if we're past the point where structured concurrency itself has reached memetic and cognetic critical mass, then we need terminology that works best then. Until then, we might as well stick with nurseries, because I think it has clear advantages in searchability and unfamiliarity and so on, and just wait and see what catches on. Once something does, it will eventually be obvious, assuming Trio is still flourishing and relevant to the wider programming community.

And if the change has to happen later, backwards compatibility is not exactly hard - for example if open_nursery gets renamed to fork, just open_nursery = fork at the bottom of the top-level trio import, and if we don't want to carry that around indefinitely (I know, it is a heavy burden) we have SemVer for that, and Python is so dynamic that someone maintaining a legacy codebase (but for some reason not just pinning their pip dependencies to specific versions even though they're unwilling to go through and update their code) can just do trio.open_nursery = trio.fork just under their import trio.

Most Important Part

In the meantime, I think where it really shakes out is conversational usage - how easy it is to say, understand, remember, etc, and in so far as misunderstandings matter, how resistant it is to nuance decay, double illusion of transparency, etc.

Now that I've thought of "fork" and "fork breaking" and so on, I'm going to be test-driving those when talking specifically about structured concurrency or code spots that use it or fail to use it (as opposed to places where "call tree" is sufficient), and seeing if I run into problems or misunderstandings with it.

I encourage others to do the same. I'd say "may the best memes win", but the "best" memes will win, no may about it.

@mentalisttraceur
Copy link

mentalisttraceur commented Jan 16, 2020

On further thought: any terminology needs to fit nicely with the "you have to pass the nursery as an argument to the coroutine to create children that outlive it".

Nursery is fairly nice for that:

  1. "nursery" is exclusively a noun - unlike "fork" it doesn't pull double duty as a verb.

    Compare: "the nursery", "the fork", "the fork object".

    (Poor "split" pulls triple duty as an adjective, so even adding a noun to it to make it unambiguously a noun doesn't save it from sounding weird: "the split object".)

  2. More importantly: you can put things into a nursery - namely children.

Why does this matter so much?

Because a key feature of the nursery primitive is passing a nursery through code to let that code put
child talks into that nursery.

I think per the usage point above, we should check all alternative names against that pattern. For example, these seem to flow well

  • "oh you need to pass the {nursery,lifetime,scope,task group} you want the task to live under through to where you want to start it from", or

  • "the reason we want to explicitly pass a longer-lasting {nursery,lifetime,scope,task group} instead of implicitly is so we can know when we might be creating something that has effects or leaks beyond the scope of the block".

Notably, my earlier suggestion of "fork" really gets clumsy around here, and I think this reveals it as deficient in a way that those other alternatives aren't.

Edit:

I mean I guess "you need to pass the fork object you want the new coroutine to fork from" and "we want to explicitly pass an an outer fork object so we can make code that breaks off forks externally visible" kinda works, but it took me more effort to proactively think it up, which isn't a good sign.

@mentalisttraceur
Copy link

mentalisttraceur commented Feb 13, 2020

The word "branch" should not be reserved for non-concurrent branches, no matter how strongly associated it is with that right now.

A branch is a branch is a branch, regardless of whether it is traversed in parallel or exclusively or not at all.

The call tree visual/metaphor is very valuable for thinking about structured concurrency - and trees have branches!

We should fight for an equal share of that word.

So there are exclusive branches, and there are concurrent branches.

Structured programming brought order to exclusive branches. Structured concurrency brings order to concurrent branches.

@mentalisttraceur
Copy link

mentalisttraceur commented Feb 14, 2020

The more I think about it, the more "split point" feels right as the term for what a nursery is, maybe not for Trio but definitely for structured concurrency as a whole.

It ties really well with the call tree metaphor and visual:

  1. Picture a call tree.
  2. Look at one of the points where it splits.
  3. Boom. Notice how naturally those words fit. But we're not done:
  4. What are you doing when you pass a nursery down the call tree?
  5. You are letting that code split off from the same point in the call tree!

If I'm teaching the idea of structured concurrency to someone, or at least the passing nurseries part, I want to set up the idea and visual of a call tree anyway - this terminology comes for free.

So "split" is the action, "split point" is the object.

The addition of "point" does a great job of making it a noun: it is natural once we introduce split point objects as references to a specific point where the call tree splits, existing for the purpose of letting other code split more concurrent branches from the same point.

It's short. "split" is one syllable, five phonemes, five characters. (Any complaints about "while" being too long?)

It's free. As far as I know, the word "split" is not used for any one established programming concept, and no mainstream language uses "split" as a language keyword. Certainly the term "split point" is not in use (except for drill bits, apparently).

Yes "split" is generic (but "split point" isn't, and that compensates), but I'm imagining what this should be named in a world where it is a fully established fundamental programming concept, equal with if and while, taught in introductory classes, and in that world, it should be a generic word, because if we do this right, soon enough breaking off a concurrent branch will be just as inconceivable as a goto from inside one function into the middle of another.

I am more excited about this as a generic structured concurrency term proposal than I am for it in Trio - don't care if Trio just keeps calling them nurseries (see my first comment), but if I had to try to apply this to Trio, I imagine something like this isn't too bad:

async with trio.split() as split_point:
    split_point.start_soon(foo, ...)
    # People who want short could do `as sp`!

Also in languages like C or Go, a split point can be represented by a pointer to an object of a type called "split", and that feels like the right alignment of naming between implementation details and abstract concept.

P.S. The entire time I was writing this comment, I kept thinking "I feel like maybe someone said this before and maybe I was subconsciously influenced by it?" - so just before hitting submit I just searched the thread and apparently I've just reinvented the terminology that @njsmith first proposed in the very first comment two years ago. But I had totally forgotten, and arrived at it again from a completely different direction: while thinking about how I would add structured concurrency as a language feature to something like C. So I think there is something more universally true to it.

@mentalisttraceur
Copy link

mentalisttraceur commented Feb 14, 2020

Thing is, when I first read @njsmith's "split point" suggestion I didn't like it either, and did not think it fit Trio's API shape well.

To the best of my ability to remember.

I clearly didn't like it enough, because I completely forgot about it consciously.

But this also reveals that I did not dislike it strongly enough, and did not identify any bad enough problem with the term itself, because I would have remembered that by now.

@smurfix mentioned it not signaling a new, unfamiliar concept strongly enough, and I agree with that as a circumstantial reason, but I think as structured concurrency gets going, that rapidly goes from being a downside to being an upside.

When structured concurrency was new and unfamiliar, a new and unfamiliar and opaque term was good. Once it is established and normal, a simple term that implies it is the simplest and most familiar and most intuitive concept in the world, like "if", is more fitting.

Anyway, I think it is very notable that I did not like or remember the terms "split" and "split point" initially, and did not think they were a particularly great fit for Trio's API shape, but then rediscovered them while thinking about the best terms for a completely different language.

(Reminder: I'm not trying to push for removing the name nursery right now - see my first comment, and also my previous one, and also remember that it is trivial and not necessarily a bad thing for Trio to keep the nursery name for backwards compatibility when it does decide to adopt "split" and "split point".)

@mentalisttraceur
Copy link

mentalisttraceur commented Feb 19, 2020

I had occasion to try using both "split point" and "fork breaking" in conversation the other day, when trying to talk about structured concurrency, with a call tree diagram on a whiteboard.

Two very noticeable observations:

  1. "branch point" (which I think @njsmith also suggested in the same early post he suggested "split point" in) is better than "split point", unless someone else has anecdata to the contrary:

    I keep slipping into saying (and typing) "switch point" instead of "split point", and don't even notice it at first.

    Not sure if there is a more fundamental reason beyond the term just not fitting into the patterns of words my brain is used to, but I misspoke so consistently I just announced I was switching to "branch point" mid-conversation, and it went smoothly from there, without loss of clarity.

  2. "branch breaking" was much less "out-of-the-way" and less awkward to say than "fork breaking".

    It felt like introducing "fork breaking" spontaneously into the speech flow was adding a new term, and one which due to unexpectedness might not even immediately phonetically parse to someone.

    I could tell that in order to mitigate this, I would have to say something like "because alternatively we could call a branch a fork", which in context just seemed like it would be an arbitrary and unjustified word-hop from "branch" to "fork" for no good reason to the audience, and thus not particularly memorable, since memory is so dependent on things systematically sensibly fitting in together.

    So after trying to use "fork breaking" once, I just accepted the natural flow of statements like "or in unstructured concurrency, the branch can also be broken off".

I've also found that the distinction and terminology of "concurrent branch" vs "exclusive branch" takes me all of one sentence to establish and was accepted as self-evident without any resistance or confusion the one time it came up in conversation where I could observe the reaction.

@mentalisttraceur
Copy link

mentalisttraceur commented Feb 19, 2020

The moment I accepted "branch" as the more natural term than "split" to use, I started also finding myself wanting to contemplate whether or not there is some deeper value that could be extracted by reifying the branch point of an exclusive branch (the moment an if or while or switch statement opens) the same way that reifying the branch point of a concurrent branch into a nursery has produced value.

This is getting a bit too esoteric, some weird language design theory direction abstracting beyond structured concurrency as a whole even, but I find myself wondering what we can make of this.

Because it's very interesting that structured programming manages to make do without reifying either the branch execution or the branch point, and yet every structured concurrency design I like reifies either the branch point (Trio's nursery) or the branch execution (libdill's coroutine handle).

@mentalisttraceur
Copy link

One of these days I'm going to just make an account on the structured concurrency forum @njsmith started and relocate all these thoughts to there, but for now streaming them here is just much more accessible of a workflow for me.

@mentalisttraceur
Copy link

The above having been said, I think split is still the more right language keyword than branch, the same way that if and switch are better language keywords than branch.

@mentalisttraceur
Copy link

mentalisttraceur commented Apr 24, 2020

Structured Concurrency's nursery is Structured Programming's jmp_buf.

@mentalisttraceur
Copy link

mentalisttraceur commented Apr 24, 2020

This analogy might not stretch far enough to be useful, but here's what I mean by:

Structured Concurrency's nursery is Structured Programming's jmp_buf.

I said in one of my last comments that since modern structured concurrency had reified the concurrent branch point (nursery), it was interesting to think about if there was any value to reifying structured programming's exclusive branch points.

After I thought that, I kept trying to figure out why structured programming managed to make do without any explicit reification of branch points.

I think this is why. It did exist, at first, as a partial controlled escape hatch in languages like C. Like a nursery, a C jmp_buf has to be set up higher up in the call tree, and it had to be passed to the code that wanted to branch off of it.

Of course, we could implement everything (if, while, for, switch, break, continue, return, raise, yield, etc) with some clever combination of longjmp, function pointers, and mutable state.

But we discovered these narrower limited and common variants of code jumps, and built them into our languages. Probably something like that exists for structured concurrency. Certainly there is a "shape" difference between commonest case of creating a new nursery to branch off some concurrent stuff at that spot of the call tree, and the less common case of passing around a nursery from elsewhere so that code in one part of the call tree can branch off of a point elsewhere on the tree.

The place where this analogy might break down to the point of uselessness is that maybe the difference between the reified concurrent branch point (nursery) and primitives like split wait and split race and whatever else we discover might not be big enough to justify an almost-vanishing of the reified branch point, but we already empirically know that the difference between the reified exclusive branch point (jmp_buf) and primitives discovered for structured programming is big enough.

Anyway, that's just what I've been mulling on, and it connects to the question of "should we rename nurseries" because if this really is a jmp_buf analogue, then the exact name won't matter at all in the historical big picture that's coming, because a few less flexible primitives will fill most usecases.

I think the important way to check if this is where structured concurrency is going is to look really, really hard at the cases where the "pass a nursery around" actually occurs, and think really, really persistently about how it might be done elegantly with only more limited local-only concurrency primitives like wait and race, or what primitives would be needed to do it.

I think this is important to really try to do, because when we can see the low-level commonality, the fundamental principle, it is easy to keep mentally reaching back to that as "well obviously this one thing covers this too". From the vantage point of seeing the one elegantly unifying thing, it can be a lot harder to find or even look for the few less unifying things that are good enough for almost every case. wait and race are definitely not enough, but they seem like they cover about as much ground as for and if - maybe structured concurrency just needs a couple more structure-breaking primitives like return/continue/break or raise/except or yield.

Conversely, it still seems worthwhile to keep doing the opposite - looking for if there is some way for a reified exclusive branch point to elegantly and usefully replace all of those structured programming primitives. If we find such a way, it might inform the nursery discussion in the other direction, by revealing that nurseries really are here to stay as the primitive of structured concurrency.

(By the way, if anyone wishes to quote or discuss the comments I make here in other places like the Structured Concurrency Trio subforum even if I am not there to participate - feel free, I encourage it.)

@ksamuel
Copy link

ksamuel commented Apr 24, 2020

Well, this thread has been going since mid 2018, so I doubt nurseries are every going to change name.
If it ever does, I'll add my voice to the crowd asking for something succinct and boring like trio.scope, which is clear enough, short, has no surprise, it's already wildly used and known for communicating boundaries and lifetime.

@frederikaalund
Copy link

frederikaalund commented Jun 5, 2020

I like the nursery term. Modulus the GC ambiguity, it is unique, which is what you want for a new programming concept.

I also like the split term. It conveys the semantics in the name itself. Something that nursery doesn't quite achieve IMHO. I concur with the others about split being a bit overloaded already.

I propose rift. I find that it both:

  • Conveys the semantics nearly as well as split does.
  • Is a unique term in the software world.

Anyhow, maybe it's a moot point at this point in time. nursery works.

That's my two cents.

@stuaxo
Copy link

stuaxo commented Jun 13, 2020

How about mutual as a name ?

Edit: I have no horse in this race, nursery is fine.

Edit 2:
I think its not a bad word, as cancellation is mutual between them.

They have a mutual agreement to continue until any one is cancelled then all are cancelled.

Or it can be short for "mutual cancellation" or similar.

@rednafi
Copy link
Member

rednafi commented Dec 29, 2020

At this point, is there any reason to keep this open? Nursery seems fine and there is no ambiguity there. Also, over 2.5 years after the announcement, I think it will be extremely difficult to change this now. @njsmith

@Kochise
Copy link

Kochise commented May 4, 2021

Pretty much more for the 'group' or 'band' naming (after all it's about a 'trio').

Can be ungrouped or disbanded...
A 'session' or 'event' can be canceled...

Not as fancy as 'nursery' but sounding more professional imho.

@mentalisttraceur
Copy link

mentalisttraceur commented Jun 10, 2021

A little over a year later, my position remains:

  1. The best name for the abstract concept is "branch point".
  2. Trio names its concrete branch point object implementation "nursery", and that's fine.

@efiring
Copy link

efiring commented Oct 1, 2021

@njsmith I recommend that you simply make an executive decision, close this issue, and move on. I would very much like to see Trio move forward and become widely adopted. Instead, it seems to have stalled, with non-critical issues like this hanging around and with no decisions in sight. Please don't let the perfect (perfect decision, or perfect consensus) be the enemy of the good.

@rednafi
Copy link
Member

rednafi commented Oct 1, 2021

+1 to @efiring's argument.

@Hnasar
Copy link

Hnasar commented Jul 12, 2022

I'm a newcomer to structured programming/trio (I just learned about it last week) and wanted to share my thoughts.

After recently pair programming and quickly going through the docs, I didn't understand the significance of a "nursery". In my mind, I just thought of it as some quirky structure and weird object name trio required; and after getting used to Twisted's peanut-butter-jelly-reactors, I didn't pay much thought to the weird name).

Only after reading the blog post and seeing this image, did the significance finally click:

image
(aside: is this three-pronged graphic the inspiration behind the name 'Trio'??)

When referring to the point in time (regardless of which name we use for it "branch", "fork", "split", etc.) the novel idea Structured Concurrency brings is that this point in time is necessarily bounded with a corresponding end/join point. (And with Python's context managers, this represents a concurrent block.) So when teaching these concepts, it makes sense to say things like:

  • "a nursery represents a bounded fork of concurrent tasks"
  • "in structured concurrency, branch points are bound"
  • "the fork syscall doesn't enforce children are joined, so it can be considered unbound, unlike in structured concurrency".

Upon reflecting on these previous messages:

Collections of threadlike things bound together at both ends are...

"Fork" does not imply the boundedness that structured concurrency makes its central tenet..

We can simply rely on the innovation inherent in structured programming and use "bound" as an adjective. Therefore I would amend what @mentalisttraceur said with:

  1. The best name for the abstract concept is "bounded branch point".
  2. Trio names its concrete bounded branch point object implementation "nursery", and that's fine.

For what it's worth, now in 2022:

Neither of these names are very special, and that's probably the point.

It's like @smurfix said:

Nurseries/taskgroups no longer are novel concepts, they {are | should be | are going to be} the "new normal". You get to name normal everyday ideas with normal everyday names.

As humanity coalesces on a new name and Structured Concurrency becomes mainstream, at the very least, it'd be good to document that a nursery is Trio's name for a Task{Group,Scope}.

@pquentin
Copy link
Member

pquentin commented Jul 13, 2022

Python 3.11 uses the name TaskGroup: https://docs.python.org/3.11/library/asyncio-task.html#asyncio.TaskGroup

If we rename at all I think we should use this name.

@Zac-HD
Copy link
Member

Zac-HD commented Mar 17, 2023

It's now been almost five years since njs said:

Should we rename "nurseries"? It's something that keeps coming up, and while it would be somewhat painful to change now, it'll be pretty much impossible within the next 6 months.

and, well, we haven't changed it. I'm going to close this issue, because I expect any eventual renaming to be a much more focussed discussion of "(should / how do) we rename to match asyncio and anyio?"... but I'm not in any hurry.

@Zac-HD Zac-HD closed this as completed Mar 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests