epony has quit [Remote host closed the connection]
epony has joined #pypy
derpydoo has quit [Ping timeout: 260 seconds]
jcea has quit [Ping timeout: 260 seconds]
lessshaste has joined #pypy
alice has quit [Remote host closed the connection]
alice has joined #pypy
otisolsen70 has joined #pypy
<cfbolz>
our portable binaries are so nice sometimes. have an old synology with ancient pythons, but I can just drop a pypy nightly there and it works out of the untarred download
otisolsen70 has quit [Quit: Leaving]
<LarstiQ>
cfbolz: yup
otisolsen70 has joined #pypy
<mattip>
:)
lessshaste has quit [Ping timeout: 248 seconds]
derpydoo has joined #pypy
jcea has joined #pypy
lessshaste has joined #pypy
Dejan has quit [Quit: Leaving]
<hexology>
arigato: what do you think is broken about the async/await syntax? i've heard complaints about asyncio, but not much about the syntax.
<hexology>
"broken" seems like a strong word here
<fijal>
hexology: I have some arguments.
<hexology>
i'd like to hear them!
<fijal>
for example various failure modes of failing to call await
<fijal>
if your function is awaitable and you don't call it, the call gets silently ignored
<hexology>
(just to set expectations: i'm not trying to argue that the design is perfect, only that "broken" seems too strong of a criticism)
<fijal>
it's very poorly thought out how it interacts with other parts of python
<fijal>
"broken" really depends on what is your expected quality, right?
<hexology>
"broken" to me implies that it's fundamentally not usable in important common cases, requiring significant workarounds to achieve baseline functionality
<fijal>
right
<fijal>
remember we write compilers - a compiler that once in thousand times will produce you an invalid assembler is broken
<fijal>
I guess we apply the same standard to language design
<hexology>
indeed. i am also interested to hear what a not-broken design would be, in a dynamically- (but strongly-) typed language like python.
<fijal>
I'm not sure I can answer that
<fijal>
because "in python" seems to imply something
<fijal>
I think for armin (and for myself too), having clear errors in case you make a mistake would be a good start
<hexology>
i qualified with "in python" because you can't do something like rely on static type enforcement by a compiler
<fijal>
having a description how does it interact with common things, like debuggers or threads or signals or Ctrl-C would also be cool
<fijal>
I would even go with "ask twisted people how to do it"
<hexology>
doesn't twisted use callbacks and thereby avoid any issues of syntax? you can't forget to await something unless you forget to pass a callback!
<fijal>
I will not even try to answer the question how to do it - I don't know right now and I never really thought about it
<fijal>
what do you mean you can't forget awaiting something?
<fijal>
you can write
<fijal>
instead of "await sleep(5)", you can totally write "sleep(5)"
<fijal>
it compiles, it runs, it does not produce an eror
<fijal>
error
<hexology>
oh i was talking about twisted specifically
<hexology>
yeah that's a problem with `async` functions looking like functions but actually returning awaitable coroutine things. it trips up a lot of beginners.
<fijal>
I meant specifically "consulting people who wrote twisted would have been nice"
<fijal>
not "use twisted and mix it with async"
<fijal>
ok, I think silently eating such an error is quite bad
<fijal>
also, why is await allowed in finally?
<hexology>
well asyncio *will* spit a warning at you when the event loop closes and tasks were left un-awaited. but that's a "late" failure mode.
<fijal>
it *looks to me* like a hack done on top of generators not a fully thought out feature
<hexology>
what's the problem with await-ing inside a finally block?
<fijal>
how do you handle a Ctrl-C in such behavior?
<fijal>
but also, it usually ends up with a cascade of unreadable errors
<fijal>
you can't really be sure what state is your stuff in if you had an error that ends up in finally. For all we know it's MemoryError or SystemError or something very obscure
<hexology>
is that not also true in synchronous code?
<fijal>
I would prefer if no one reads from a socket in finally
<hexology>
i'm not trying to be argumentative, i'm asking questions because i am trying to understand a perspective i've never heard before
<fijal>
how do you use async from pdb?
<hexology>
that's a known feature request :P
<fijal>
haha
<fijal>
well, so it has not been thought out very well, has it?
<hexology>
i guess i just want to be clear about separating "complaints about asyncio" from "complaints about async/await syntax"
<fijal>
right
<fijal>
I don't think you can split the two
<hexology>
trio and curio both use async/await syntax but don't use any asyncio code
<fijal>
they're also awful to use from pdb
<hexology>
sure. so the pdb issue i think is an async/await syntax issue, not an asyncio issue specifically
<fijal>
maybe?
<fijal>
I don't know
<hexology>
it is interesting that they went for special syntactical keywords
<fijal>
it seems to me that asyncio should be something that's usable for everyone and is the official way to use async/await syntax
<fijal>
and has library support
<fijal>
and has an official story how it works with pdb
<fijal>
and has an official story how it works with threads for example
<fijal>
I don't even want to ask how are signals handled
<hexology>
what do you mean about how it works with threads?
<fijal>
it largely doesn't
<fijal>
the behavior is not very well defined
<hexology>
the official story is that you are supposed to have at most 1 event loop per thread, and there are thread-safe primitives for submitting tasks to an event loop running in a different thread
<hexology>
that's the asyncio story, but as far as i know, trio has the same story
<fijal>
how does that support Ctrl-C? or pdb?
<fijal>
there is also no support from the language to make sure that any of it is true
<hexology>
because asyncio is entirely a python library
<fijal>
nor is it very well defined what's atomic what's not
<hexology>
the only thing built into "python the language" is async/await
<fijal>
well, maybe more should be built into the language
<hexology>
perhaps, and/or there should be a pep specifying what is and is not expected of an async, whether it's asyncio or trio or something else
<hexology>
an async implementation*
<fijal>
to me, this seems very rushed
<fijal>
and not well thought out
<fijal>
on the contrary, I am working a lot with C# where you see that before a feature gets introduced, someone has to answer questions like "how do you debug this?" or "how do you support this in IDE?"
<hexology>
fwiw i've never had a problem running pdb inside an async function. the only thing you can't do is invoke `await` on the command prompt. however you can step over and into awaits and coroutines just fine.
<hexology>
ctrl-c is funky because signal handling in asyncio specifically is... deficient
<hexology>
trio has better default behavior iirc
<hexology>
i agree that asyncio has felt very much like a living beta/WIP and that it probably could have benefited from more up-front design
<fijal>
I found trio way too scary and way too magic
<fijal>
doing something basic I ended up with 7 nested exceptions of cancelled tasks and all kinds of crazy shit
<hexology>
but i think this is also a somewhat new design space. no other dynamically-typed language has constructs like this
<fijal>
python to me looks like a collection of postcards these days - there is a lot of stuff, a lot of it is cool, but it's not thought out how does it work all together
<hexology>
has it ever not looked like that? :P
<fijal>
I did a graph of adding C APIs by month or by release at some point
<fijal>
I think it used to be more minimal
<hexology>
the core language has definitely grown
<hexology>
e.g. i think match/case was a big mistake
<hexology>
it is interesting to consider what might have come about from *not* having async/await keywords, and instead sticking to the decorator design. as i understand it, the keyword design was a necessary pre-requisite for constructs like `async with` and `async for`.
<fijal>
so yeah, those are my complaints - but I think armin has more specific ones too
<hexology>
thanks for sharing them
<fijal>
I'm very happy not having async with and async for :-) those look very scary
<fijal>
I also think they have some corner cases that are really bad, but this might be hearsay
<fijal>
and I like the basic idea
<fijal>
I use twisted with async/await syntax these days if I need a network server, for example
<hexology>
what scares you about them? again, i always considered them elegant conveniences, but my perspective is that of a data scientist "scripter" and generalist. compiler devs seem to have very different perspectives from mine.
<fijal>
compiler devs tend to have to consider all corner cases
<fijal>
and if some of the corner cases end up with being either undefined or poorly defined, we end up having to replicate the exact cpython behavior, down to a bug level, because people will rely on it
<fijal>
I mean, no one ever thought about "how do we support async/await efficiently with a JIT" either right?
<fijal>
there is a lot in generator design that makes it a particularly hellish JIT target, for example
<fijal>
I don't feel competent to really comment about async for "looks scary".
<hexology>
that makes sense
<hexology>
i guess that's what i'm wondering: from my perspective, this language spec is good enough for me to work with, but if it's deficient from the perspective of someone trying to implement the language i'm very curious to know what's missing.
<hexology>
or is it the general principle that new language constructs tend to have error cases, and that cpython being both the spec and reference implementation makes it hard for a 3rd-party implementation to implement new constructs "correctly"
<hexology>
s/error cases/edge cases/
<fijal>
I think there are two thiings here
<fijal>
first is that I think that in a language like python there should not be corner cases. And things like "how does it interact with all the other language features" should be answered before it's added. Because someone will mix it
<fijal>
and two, in a language like python if you get something wrong, you should probably get a better error, even if at runtime, then maybe a warning some time later
<fijal>
that's why I think it's a rushed hack, aka broken
<fijal>
amongst other things, it has not seen universal adoption, like one would expect from a better networking paradigm
<fijal>
in fact, there is no real standard what to use for a main event loop for example
<fijal>
people are trying, but well, I still use twisted
<antocuni>
and on top of that, my personal gut feeling is that async code is intrinsically too complex to be understandable
<antocuni>
because you basically have an exponential number of possible code paths
<antocuni>
but then I know that there are people who DO write async code in production, so maybe it's just that I'm not smart enough :)