A modest terminological proposal
I've found that when talking about async/await stuff recently, I've mostly dropped the word "coroutine" from my vocabulary and replaced it with "async function". I'm writing to suggest that we might want to make this switch as a community, and do it now, before the next 10x increase in the async/await userbase. Rationale: *Consistency*: If the only two words to keep track of were function vs coroutine, that would be one thing. But here's a list of syntax constructs we have now, and how we talk about them in English: with -> applies a *context manager* to a *with block* async with -> applies an *async context manager* to an *async with block* for -> does a *loop* over an *iterator* async for -> does an *async loop* over an *async iterator* def + yield -> makes a *generator* async def + yield -> makes an *async generator* [... for ...] -> is a *comprehension* [... async for ...] -> is an *async comprehension* def -> creates a *function* async def -> creates a *coroutine* One of these is not like the others. Why? It's a pointless toe-stub for newcomers. *Expressivity:* Once I started talking about async functions, I've found my vocabulary suddenly expanding with useful new bonus terms, like "async method" (= an async def inside a class body), or "async callable" (= any callable that returns an awaitable, emphasizing the duck type rather than the concrete type). *Approachability*: What is a "coroutine" anyway? Is it like a monad? Am I going to have to learn about endofunctors and continuations next? Of course we've all gotten used to the term now so we don't notice, but for a new user this is an obviously jargony "if you don't have a PhD then this isn't *for* you" kind of word. It's not hospitable. Plus, it emphasizes the implementor under-the-hood point of view, not the user point of view. (Which is totally understandable! Because we're just now transitioning from the internal implementors hacking things out phase to the broad general user base phase, but that's why we should fix this now.) For an end-user, especially one starting out, they don't need to know or care about all the coroutine stuff that async/await is using to make the magic happen, they can learn that later. To get started, all you need to know is that you do async stuff by using async functions and sticking an 'await' onto your I/O calls. A lot of work went into abstracting away that magic and giving it a friendly Python syntax; the English syntax should follow suit. *Accuracy*: Speaking of jargon, the term "coroutine" *is* an existing piece of jargon in computer science, and our term and their term don't quite match up. This isn't a huge deal, but it's unnecessary confusion. According to Wikipedia I guess technically we don't even have "true" coroutines, just "semicoroutines"? And every generator has just as much claim to being a coroutine-in-the-CS-sense as an async function does, but when we say coroutine we don't mean generators. (Except when we do.) This confusion might partly reflect the somewhat confusing transition from 'yield from' to async/await, as demonstrated by the official doc's somewhat confusing definition of "coroutine": https://docs.python.org/3/library/asyncio-task.html#coroutine But going forward, yield-from-based coroutines and @asyncio.coroutine and all that are quickly becoming a historical curiosity, and most of the time what we really want to be talking about are just async functions. *So:* I'm not suggesting we modify Python itself to rename types.coroutine or the .cr_* fields or anything, that's all expert internal stuff (possible exception: the __repr__ for async functions). But I do propose that we all agree to do a search/replace for s/coroutine/async function/g on our end-user docs and when generally talking about these things, and announce that we're doing so. It's a small thing and a bit of work, but if there's a general agreement to do it in a coordinated way then I think it could be pretty straightforward transition that will pay dividends for a long time. -n -- Nathaniel J. Smith -- https://vorpus.org
I've heard people call it an "async def" too. I don't think it's quite as dramatic as you worry about. People also talk about generators (not generator functions) and even though there's a further ambiguity between the function and the type of object it returns, we still get along. There's also the @coroutine decorator. If you have a specific piece of documentation in mind, let's talk -- maybe it's fine to change. On Sat, Oct 8, 2016 at 5:00 PM, Nathaniel Smith <njs@pobox.com> wrote:
I've found that when talking about async/await stuff recently, I've mostly dropped the word "coroutine" from my vocabulary and replaced it with "async function". I'm writing to suggest that we might want to make this switch as a community, and do it now, before the next 10x increase in the async/await userbase. Rationale:
Consistency: If the only two words to keep track of were function vs coroutine, that would be one thing. But here's a list of syntax constructs we have now, and how we talk about them in English:
with -> applies a context manager to a with block async with -> applies an async context manager to an async with block
for -> does a loop over an iterator async for -> does an async loop over an async iterator
def + yield -> makes a generator async def + yield -> makes an async generator
[... for ...] -> is a comprehension [... async for ...] -> is an async comprehension
def -> creates a function async def -> creates a coroutine
One of these is not like the others. Why? It's a pointless toe-stub for newcomers.
Expressivity: Once I started talking about async functions, I've found my vocabulary suddenly expanding with useful new bonus terms, like "async method" (= an async def inside a class body), or "async callable" (= any callable that returns an awaitable, emphasizing the duck type rather than the concrete type).
Approachability: What is a "coroutine" anyway? Is it like a monad? Am I going to have to learn about endofunctors and continuations next? Of course we've all gotten used to the term now so we don't notice, but for a new user this is an obviously jargony "if you don't have a PhD then this isn't *for* you" kind of word. It's not hospitable.
Plus, it emphasizes the implementor under-the-hood point of view, not the user point of view. (Which is totally understandable! Because we're just now transitioning from the internal implementors hacking things out phase to the broad general user base phase, but that's why we should fix this now.) For an end-user, especially one starting out, they don't need to know or care about all the coroutine stuff that async/await is using to make the magic happen, they can learn that later. To get started, all you need to know is that you do async stuff by using async functions and sticking an 'await' onto your I/O calls. A lot of work went into abstracting away that magic and giving it a friendly Python syntax; the English syntax should follow suit.
Accuracy: Speaking of jargon, the term "coroutine" *is* an existing piece of jargon in computer science, and our term and their term don't quite match up. This isn't a huge deal, but it's unnecessary confusion. According to Wikipedia I guess technically we don't even have "true" coroutines, just "semicoroutines"? And every generator has just as much claim to being a coroutine-in-the-CS-sense as an async function does, but when we say coroutine we don't mean generators. (Except when we do.) This confusion might partly reflect the somewhat confusing transition from 'yield from' to async/await, as demonstrated by the official doc's somewhat confusing definition of "coroutine":
https://docs.python.org/3/library/asyncio-task.html#coroutine
But going forward, yield-from-based coroutines and @asyncio.coroutine and all that are quickly becoming a historical curiosity, and most of the time what we really want to be talking about are just async functions.
So: I'm not suggesting we modify Python itself to rename types.coroutine or the .cr_* fields or anything, that's all expert internal stuff (possible exception: the __repr__ for async functions). But I do propose that we all agree to do a search/replace for s/coroutine/async function/g on our end-user docs and when generally talking about these things, and announce that we're doing so. It's a small thing and a bit of work, but if there's a general agreement to do it in a coordinated way then I think it could be pretty straightforward transition that will pay dividends for a long time.
-n
-- Nathaniel J. Smith -- https://vorpus.org
_______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also talk about generators (not generator functions) and even though there's a further ambiguity between the function and the type of object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if we keep using "coroutine" as the standard term :-). I just think that calling them "async functions" (and "async function objects" when the distinction is important) would be a nice unambiguous win for pedagogy and clarity, and that it's worth grabbing those when you get the chance. "coroutine" says more about the history of how we got here than about what these things actually mean to a regular end-user; "async function" is so transparent that you can skip the vocab discussion and go straight to talking about how to use them.
There's also the @coroutine decorator.
There's two of them, even: @types.coroutine and @asyncio.coroutine. I'm not really sure what the difference is -- I think at this point we could delete some code by making the latter an alias for the former? But for now they're still independent and I might be missing something. And unless I am missing something, these are only useful in rather unusual situations: either because you're trying to maintain compatibility with 3.4 (which I think will rapidly become irrelevant for most asyncio users, if it isn't already) or you're implementing your own trampoline (e.g. [1][2]). So even if we leave the decorators alone, it doesn't really stop us from switching to clearer terminology for day-to-day usage -- most people will never encounter @coroutine anyway. (For completeness: the other stdlib identifiers I see that mention "coroutine" are: sys.{get,set}_coroutine_wrapper, several functions in inspect, and asyncio.run_coroutine_threadsafe.)
If you have a specific piece of documentation in mind, let's talk -- maybe it's fine to change.
Well, it's a basic concept that gets mentioned constantly throughout all discussions... For example, I count 29 instances in [3] and 53 instances in [4]. Clearly it's useful to have a standard term for these things. -n [1] https://github.com/dabeaz/curio/blob/6166a54a731df59c15fe27791d1c6b048f09f94... [2] https://github.com/njsmith/async_generator/blob/fab4af987cb86c6db549131b66d3... [3] https://docs.python.org/3/library/asyncio-stream.html [4] https://curio.readthedocs.io/en/latest/reference.html -- Nathaniel J. Smith -- https://vorpus.org
I'd like input from others, but maybe it's worth expanding the scope to python-ideas? Not too many people read async-sig. (Or should that be coroutine-sig? :-) On Sat, Oct 8, 2016 at 8:50 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also talk about generators (not generator functions) and even though there's a further ambiguity between the function and the type of object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if we keep using "coroutine" as the standard term :-). I just think that calling them "async functions" (and "async function objects" when the distinction is important) would be a nice unambiguous win for pedagogy and clarity, and that it's worth grabbing those when you get the chance. "coroutine" says more about the history of how we got here than about what these things actually mean to a regular end-user; "async function" is so transparent that you can skip the vocab discussion and go straight to talking about how to use them.
There's also the @coroutine decorator.
There's two of them, even: @types.coroutine and @asyncio.coroutine. I'm not really sure what the difference is -- I think at this point we could delete some code by making the latter an alias for the former? But for now they're still independent and I might be missing something.
And unless I am missing something, these are only useful in rather unusual situations: either because you're trying to maintain compatibility with 3.4 (which I think will rapidly become irrelevant for most asyncio users, if it isn't already) or you're implementing your own trampoline (e.g. [1][2]). So even if we leave the decorators alone, it doesn't really stop us from switching to clearer terminology for day-to-day usage -- most people will never encounter @coroutine anyway.
(For completeness: the other stdlib identifiers I see that mention "coroutine" are: sys.{get,set}_coroutine_wrapper, several functions in inspect, and asyncio.run_coroutine_threadsafe.)
If you have a specific piece of documentation in mind, let's talk -- maybe it's fine to change.
Well, it's a basic concept that gets mentioned constantly throughout all discussions... For example, I count 29 instances in [3] and 53 instances in [4]. Clearly it's useful to have a standard term for these things.
-n
[1] https://github.com/dabeaz/curio/blob/6166a54a731df59c15fe27791d1c6b048f09f94... [2] https://github.com/njsmith/async_generator/blob/fab4af987cb86c6db549131b66d3... [3] https://docs.python.org/3/library/asyncio-stream.html [4] https://curio.readthedocs.io/en/latest/reference.html
-- Nathaniel J. Smith -- https://vorpus.org
-- --Guido van Rossum (python.org/~guido)
I figured I'd throw it out here for initial feedback on the theory that it'd be higher signal to noise, and then proceed to python-ideas if the async aficionados seemed generally in favor. On Sat, Oct 8, 2016 at 8:59 PM, Guido van Rossum <guido@python.org> wrote:
I'd like input from others, but maybe it's worth expanding the scope to python-ideas? Not too many people read async-sig. (Or should that be coroutine-sig? :-)
On Sat, Oct 8, 2016 at 8:50 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also talk about generators (not generator functions) and even though there's a further ambiguity between the function and the type of object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if we keep using "coroutine" as the standard term :-). I just think that calling them "async functions" (and "async function objects" when the distinction is important) would be a nice unambiguous win for pedagogy and clarity, and that it's worth grabbing those when you get the chance. "coroutine" says more about the history of how we got here than about what these things actually mean to a regular end-user; "async function" is so transparent that you can skip the vocab discussion and go straight to talking about how to use them.
There's also the @coroutine decorator.
There's two of them, even: @types.coroutine and @asyncio.coroutine. I'm not really sure what the difference is -- I think at this point we could delete some code by making the latter an alias for the former? But for now they're still independent and I might be missing something.
And unless I am missing something, these are only useful in rather unusual situations: either because you're trying to maintain compatibility with 3.4 (which I think will rapidly become irrelevant for most asyncio users, if it isn't already) or you're implementing your own trampoline (e.g. [1][2]). So even if we leave the decorators alone, it doesn't really stop us from switching to clearer terminology for day-to-day usage -- most people will never encounter @coroutine anyway.
(For completeness: the other stdlib identifiers I see that mention "coroutine" are: sys.{get,set}_coroutine_wrapper, several functions in inspect, and asyncio.run_coroutine_threadsafe.)
If you have a specific piece of documentation in mind, let's talk -- maybe it's fine to change.
Well, it's a basic concept that gets mentioned constantly throughout all discussions... For example, I count 29 instances in [3] and 53 instances in [4]. Clearly it's useful to have a standard term for these things.
-n
[1] https://github.com/dabeaz/curio/blob/6166a54a731df59c15fe27791d1c6b048f09f94... [2] https://github.com/njsmith/async_generator/blob/fab4af987cb86c6db549131b66d3... [3] https://docs.python.org/3/library/asyncio-stream.html [4] https://curio.readthedocs.io/en/latest/reference.html
-- Nathaniel J. Smith -- https://vorpus.org
-- --Guido van Rossum (python.org/~guido)
-- Nathaniel J. Smith -- https://vorpus.org
I generally like the idea of calling the result of `async def` an "async function", and replacing most uses of "coroutine" in the docs with "async function". The potential confusion with "asynchronous function" (which in my taxonomy is a broader category including both coroutines and functions that take callbacks) is unfortunate, but as long as the syntax is `async def` the term "async function" is almost inevitable and we might as well embrace it. In Tornado, though, I'm going to keep using the term "coroutine" because our `yield`-based decorated coroutines are important for as long as Python 2 is around. -Ben On Sun, Oct 9, 2016 at 12:00 PM Guido van Rossum <guido@python.org> wrote:
I'd like input from others, but maybe it's worth expanding the scope
to python-ideas? Not too many people read async-sig. (Or should that
be coroutine-sig? :-)
On Sat, Oct 8, 2016 at 8:50 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also
talk about generators (not generator functions) and even though
there's a further ambiguity between the function and the type of
object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if
we keep using "coroutine" as the standard term :-). I just think that
calling them "async functions" (and "async function objects" when the
distinction is important) would be a nice unambiguous win for pedagogy
and clarity, and that it's worth grabbing those when you get the
chance. "coroutine" says more about the history of how we got here
than about what these things actually mean to a regular end-user;
"async function" is so transparent that you can skip the vocab
discussion and go straight to talking about how to use them.
There's also the @coroutine decorator.
There's two of them, even: @types.coroutine and @asyncio.coroutine.
I'm not really sure what the difference is -- I think at this point we
could delete some code by making the latter an alias for the former?
But for now they're still independent and I might be missing
something.
And unless I am missing something, these are only useful in rather
unusual situations: either because you're trying to maintain
compatibility with 3.4 (which I think will rapidly become irrelevant
for most asyncio users, if it isn't already) or you're implementing
your own trampoline (e.g. [1][2]). So even if we leave the decorators
alone, it doesn't really stop us from switching to clearer terminology
for day-to-day usage -- most people will never encounter @coroutine
anyway.
(For completeness: the other stdlib identifiers I see that mention
"coroutine" are: sys.{get,set}_coroutine_wrapper, several functions in
inspect, and asyncio.run_coroutine_threadsafe.)
If you have a specific piece of documentation in mind, let's talk --
maybe it's fine to change.
Well, it's a basic concept that gets mentioned constantly throughout
all discussions... For example, I count 29 instances in [3] and 53
instances in [4]. Clearly it's useful to have a standard term for
these things.
-n
[1] https://github.com/dabeaz/curio/blob/6166a54a731df59c15fe27791d1c6b048f09f94...
[2] https://github.com/njsmith/async_generator/blob/fab4af987cb86c6db549131b66d3...
--
Nathaniel J. Smith -- https://vorpus.org
--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Async-sig mailing list
Async-sig@python.org
https://mail.python.org/mailman/listinfo/async-sig
Code of Conduct: https://www.python.org/psf/codeofconduct/
I think I'm convinced by Amber's argument. Coroutines are something you can look up in e.g. Knuth (or Wikipedia) and you'll find something a pretty good match. All queries for "async functions" seem to go to some ECMAScript proposal (similar in nature to PEP 492 actually) and I am not particularly eager to throw ourselves in front of that bandwagon. On Sun, Oct 9, 2016 at 12:34 AM, Ben Darnell <ben@bendarnell.com> wrote:
I generally like the idea of calling the result of `async def` an "async function", and replacing most uses of "coroutine" in the docs with "async function". The potential confusion with "asynchronous function" (which in my taxonomy is a broader category including both coroutines and functions that take callbacks) is unfortunate, but as long as the syntax is `async def` the term "async function" is almost inevitable and we might as well embrace it.
In Tornado, though, I'm going to keep using the term "coroutine" because our `yield`-based decorated coroutines are important for as long as Python 2 is around.
-Ben
On Sun, Oct 9, 2016 at 12:00 PM Guido van Rossum <guido@python.org> wrote:
I'd like input from others, but maybe it's worth expanding the scope
to python-ideas? Not too many people read async-sig. (Or should that
be coroutine-sig? :-)
On Sat, Oct 8, 2016 at 8:50 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also
talk about generators (not generator functions) and even though
there's a further ambiguity between the function and the type of
object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if
we keep using "coroutine" as the standard term :-). I just think that
calling them "async functions" (and "async function objects" when the
distinction is important) would be a nice unambiguous win for pedagogy
and clarity, and that it's worth grabbing those when you get the
chance. "coroutine" says more about the history of how we got here
than about what these things actually mean to a regular end-user;
"async function" is so transparent that you can skip the vocab
discussion and go straight to talking about how to use them.
There's also the @coroutine decorator.
There's two of them, even: @types.coroutine and @asyncio.coroutine.
I'm not really sure what the difference is -- I think at this point we
could delete some code by making the latter an alias for the former?
But for now they're still independent and I might be missing
something.
And unless I am missing something, these are only useful in rather
unusual situations: either because you're trying to maintain
compatibility with 3.4 (which I think will rapidly become irrelevant
for most asyncio users, if it isn't already) or you're implementing
your own trampoline (e.g. [1][2]). So even if we leave the decorators
alone, it doesn't really stop us from switching to clearer terminology
for day-to-day usage -- most people will never encounter @coroutine
anyway.
(For completeness: the other stdlib identifiers I see that mention
"coroutine" are: sys.{get,set}_coroutine_wrapper, several functions in
inspect, and asyncio.run_coroutine_threadsafe.)
If you have a specific piece of documentation in mind, let's talk --
maybe it's fine to change.
Well, it's a basic concept that gets mentioned constantly throughout
all discussions... For example, I count 29 instances in [3] and 53
instances in [4]. Clearly it's useful to have a standard term for
these things.
-n
[1] https://github.com/dabeaz/curio/blob/6166a54a731df59c15fe27791d1c6b048f09f94...
[2] https://github.com/njsmith/async_generator/blob/fab4af987cb86c6db549131b66d3...
--
Nathaniel J. Smith -- https://vorpus.org
--
--Guido van Rossum (python.org/~guido)
_______________________________________________
Async-sig mailing list
Async-sig@python.org
https://mail.python.org/mailman/listinfo/async-sig
Code of Conduct: https://www.python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
On Sun, Oct 9, 2016 at 9:50 AM, Guido van Rossum <guido@python.org> wrote:
I think I'm convinced by Amber's argument. Coroutines are something you can look up in e.g. Knuth (or Wikipedia) and you'll find something a pretty good match. All queries for "async functions" seem to go to some ECMAScript proposal (similar in nature to PEP 492 actually)
You got me curious and I did some reading... it looks like this proposal has been finalized and is starting to ship in browsers now, and that it's *very* similar to PEP 492. As in, the working group was explicitly studying "Python and C#" [1] for implementation experience, and from the user point of view the final syntax and semantics are essentially identical to our async functions / coroutines [2]. They even have Yury's async-toggles-the-keyword-status-of-await lexer hack :-). I guess personally I like it when different languages that have the same concept use the same name for it? Knuth will get you into the right ballpark, but between Python and Javascript's async functions, it looks like knowing how to use one is ~100% directly transferable to knowing how to use the other. (Apparently C# went with "async method" for their terminology, so they're consistent too.)
and I am not particularly eager to throw ourselves in front of that bandwagon.
I vote that we think of this as them throwing themselves in front of your bandwagon ;-). -n [1] e.g. https://github.com/tc39/ecmascript-asyncawait/issues/89#issuecomment-1850868... [2] There is one interesting difference: since they already have an event loop + future implementation baked into their runtime, they elected not to separate out the coroutine trampoline as a user-replaceable library component, like Python did. Instead, their 'await foo' is effectively hard-coded to do 'foo.add_done_callback(current continuation) + suspend'. Which is identical to what the standard asyncio.Task trampoline does anyway, so this is not a difference that matters to anyone who isn't writing their own I/O library. Though I guess it means we won't be seeing a curio.js anytime soon. -- Nathaniel J. Smith -- https://vorpus.org
On 9 Oct. 2016, at 14:50, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also talk about generators (not generator functions) and even though there's a further ambiguity between the function and the type of object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if we keep using "coroutine" as the standard term :-). I just think that calling them "async functions" (and "async function objects" when the distinction is important) would be a nice unambiguous win for pedagogy and clarity, and that it's worth grabbing those when you get the chance. "coroutine" says more about the history of how we got here than about what these things actually mean to a regular end-user; "async function" is so transparent that you can skip the vocab discussion and go straight to talking about how to use them.
I am of the reverse opinion -- they should be called coroutines, not asynchronous functions. Calling them "async functions" implies that they are asynchronous; they are actually completely synchronous constructs built of potentially asynchronous code and used in larger asynchronous systems. A coroutine, by itself, is not asynchronous. But I guess it's 'async def' and not 'coro def'... :) As an example of the consequences of naming, there have been several cases where asyncio users of Autobahn have attempted to do large file I/O, and thought that because they were using 'asyncio' it would be fine, and have ended up blocking the event loop because of it. There's no such thing as asynchronous file system access, which is one of the most basic kinds of I/O, which has lead to this impression. - Amber
On Sat, Oct 8, 2016 at 9:10 PM, Amber "Hawkie" Brown <hawkowl@atleastfornow.net> wrote:
On 9 Oct. 2016, at 14:50, Nathaniel Smith <njs@pobox.com> wrote:
On Sat, Oct 8, 2016 at 7:48 PM, Guido van Rossum <guido@python.org> wrote:
I've heard people call it an "async def" too.
I don't think it's quite as dramatic as you worry about. People also talk about generators (not generator functions) and even though there's a further ambiguity between the function and the type of object it returns, we still get along.
Hmm, I don't mean to be dramatic. Obviously the world will not end if we keep using "coroutine" as the standard term :-). I just think that calling them "async functions" (and "async function objects" when the distinction is important) would be a nice unambiguous win for pedagogy and clarity, and that it's worth grabbing those when you get the chance. "coroutine" says more about the history of how we got here than about what these things actually mean to a regular end-user; "async function" is so transparent that you can skip the vocab discussion and go straight to talking about how to use them.
I am of the reverse opinion -- they should be called coroutines, not asynchronous functions.
Small but meaningful nitpick: the proposal is to call them "async functions", not "asynchronous functions". It's named after the "async" keyword. Any resemblance of that keyword to an English word is ... a separate problem :-).
Calling them "async functions" implies that they are asynchronous; they are actually completely synchronous constructs built of potentially asynchronous code and used in larger asynchronous systems. A coroutine, by itself, is not asynchronous. But I guess it's 'async def' and not 'coro def'... :)
As an example of the consequences of naming, there have been several cases where asyncio users of Autobahn have attempted to do large file I/O, and thought that because they were using 'asyncio' it would be fine, and have ended up blocking the event loop because of it. There's no such thing as asynchronous file system access, which is one of the most basic kinds of I/O, which has lead to this impression.
Oh yeah, communicating this is definitely a huge challenge. But I feel like as long as the keyword is 'async' and the words "async" or "asynchronous" are on the book covers and the for loops and generally attached to every single thing except for the documentation-term-for-the-function-like-thingummies, then this confusion is going to happen and we're going to have to do the work to explain what we mean when we say 'async'. Throwing in "coroutine" as an extra piece of opaque jargon doesn't really help this, IMO. And if we have to explain what 'async' means anyway, then 'async function' comes along for free. (Of course if teaching someone about this stuff I still have the *option* of explaining what coroutines are and how async functions are an example of the concept, if I think that well help -- just now it's my decision whether I want to go there or not :-).) -n -- Nathaniel J. Smith -- https://vorpus.org
On Oct 8, 2016, at 5:00 PM, Nathaniel Smith <njs@pobox.com> wrote:
with -> applies a context manager to a with block async with -> applies an async context manager to an async with block
for -> does a loop over an iterator async for -> does an async loop over an async iterator
def + yield -> makes a generator async def + yield -> makes an async generator
[... for ...] -> is a comprehension [... async for ...] -> is an async comprehension
def -> creates a function async def -> creates a coroutine
When I teach asyncio, I make the distinction between: async def coro(): -> is a coroutine function coro() -> creates a coroutine This is something asyncio's documentation does itself, see: https://docs.python.org/3/library/asyncio-dev.html#detect-coroutine-objects-... I find that the parallel between "classes" and "objects" explains it well to people. Classes create objects. Coroutine functions create coroutines. With this nitpicking in mind, using "async functions" to describe "coroutine functions" makes perfect sense to me, especially if we keep calling the instantiated object a "coroutine". -- Lukasz Langa | Facebook Production Engineer | The Ministry of Silly Walks (+1) 650-681-7811
participants (5)
-
Amber "Hawkie" Brown
-
Ben Darnell
-
Guido van Rossum
-
Lukasz Langa
-
Nathaniel Smith