On Sun, Oct 31, 2021 at 2:43 PM <[email protected]> wrote:
>
> On 2021-10-30 at 18:54:51 -0700,
> Brendan Barnwell <[email protected]> wrote:
>
> > On 2021-10-30 18:29, Chris Angelico wrote:
>
> > > Right. That is a very real difference, which is why there is a very
> > > real difference between early-bound and late-bound defaults. But both
> > > are argument defaults.
> >
> > I don't 100% agree with that.
>
> This seems to be the crux of this whole sub-discussion. This whole
> thing scratches an itch I don't have, likely because of the way I
> learned to design interfaces on all levels. A week or so ago, I was
> firmly in Brendan Barnwell's camp. I really don't like how the phrase
> "default value" applies to PEP-671's late binding, and I'm sure that
> there will remain cases in which actual code inside the function will be
> required. But I'm beginning to see the logic behind the arguments (pun
> intended) for the PEP.
Current versions of the PEP do not use the term "default value" when
referring to late binding (or at least, if I've made a mistake there,
then please point it out so I can fix it). I'm using the term "default
expression", or just "default" (to cover both values and expressions).
And yes; there will always be cases where you can't define the default
with a simple expression. For instance, a one-arg lookup might raise
an exception where a two-arg one could return a default value. That's
currently best written with a dedicated object:
_sentinel = object()
def fetch(thing, default=_sentinel):
... attempt to get stuff
if thing in stuff:
return stuff[thing]
if default is _sentinel:
raise ThingNotFoundError
return default
In theory, optional arguments without defaults could be written
something like this:
def fetch(thing, default=pass):
... as above
if not exists default:
raise ThingNotFoundError
return default
But otherwise, there has to be some sort of value for every parameter.
(I say this as a theory, but actually, the reference implementation of
PEP 671 has code very similar to this. There's a bytecode QUERY_FAST
which yields True if a local has a value, False if not. It's more
efficient than "try: default; True; except UnboundLocalError: False"
but will have the same effect.)
> The human description language/wording is different; , but what Python
> spells "default value," Common Lisp spells "initform." Python is
> currently much less flexible about when and in what context default
> values are evaluated; PEP-671 attempts to close that gap, but is
> hampered by certain technical and emotional baggage.
Lisp's execution model is quite different from Python's, but I'd be
curious to hear more about this. Can you elaborate?
ChrisA
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/O2KQDNY2C3L6GW5AT2OJCOZZ3CMK7JG3/
Code of Conduct: http://python.org/psf/codeofconduct/