On 2021-10-31 at 14:56:36 +1100,
Chris Angelico <ros...@gmail.com> wrote:

> 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).

I still see anything more complicated than a constant or an extremely
simple expression (len(a)? well, ok, maybe; (len(a) if is_prime((len(a))
else next_larger_prime(len(a)))? don't push it) as no longer being a
default, but something more serious, but I don't have a better name for
it than "computation" or "part of the function" or even "business logic"
or "a bad API."

> 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 ...

Am I getting ahead of myself, or veering into the weeds, if I ask
whether you can catch the exception or what the stacktrace might show?

(At this point, that's probably more of a rhetorical question.  Again,
this is an itch I don't have, so I probably won't use it much.)

> > 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?

https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node64.html explains it
in great detail with examples; you're interested in &optional, initform,
and possibly supplied-p.  Summarizing what I think is relevant:

    (lambda (&optional x)) is a function with an optional parameter
    called x.  Calling that function without a parameter results in x
    being bound to nil (Lisp's [overloaded] canonical
    "false"/undefined/null value) in the function body.

    (lambda (&optional (x 4))) is a function with an optional parameter
    called x with an initform.  Calling that function without a
    parameter results in x being bound to the value 4 in the function
    body.  Calling that function with a parameter results in x being
    bound to the value of that parameter.

    (lambda (&optional (x 4 p))) is a function with an optional
    parameter called x with an initform and a supplied-p parameter
    called p.  Calling that function without a parameter results in p
    being bound to nil and x being bound to the value 4 in the function
    body.  Calling that function with a parameter results in p being
    bound to t (Lisp's canonical "true" value) and x being bound to the
    value of that parameter.

By default (no pun intended), all of that happens at function call time,
before the function body begins, but Lisp has ways of forcing evaluation
to take place at other times.

(lambda (a &optional (hi (length a)))) works as expected; it's a
function that takes one parameter called a (presumably a sequence), and
an optional parameter called hi (which defaults to the length of a, but
can be overridden by the calling code).

I am by no means an expert, and again, I tend not to use optional
parameters and default values (aka initforms) except in the simplest
ways.
_______________________________________________
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/YZOVN5UX53QPF54EDPJ4C2KEUB5XJBXZ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to