On Sun, Oct 31, 2021 at 2:43 PM <2qdxy4rzwzuui...@potatochowder.com> wrote:
>
> On 2021-10-30 at 18:54:51 -0700,
> Brendan Barnwell <brenb...@brenbarn.net> 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 -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/O2KQDNY2C3L6GW5AT2OJCOZZ3CMK7JG3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to