On Sun, Oct 31, 2021 at 4:37 PM Steven D'Aprano <st...@pearwood.info> wrote:
>
> On Sun, Oct 31, 2021 at 02:56:36PM +1100, Chris Angelico wrote:
>
> > 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 was just thinking of suggesting that to you, so I'm glad to see you're
> much faster on the uptake than I am!
>
> Of course all parameters are syntactically an expression, including now:
>
>     # the status quo
>     def func(arg=CONFIG.get('key', NULL)):
>
> The default expression is evaluated at function definition time, and the
> result of that (an object, a.k.a. a value) is cached in the function
> object for later use. With late-binding:
>
>     def func(@arg=CONFIG.get('key', NULL)):
>
> the expression is stashed away somewhere (implementation details), in
> some form (source code? byte-code? an AST?) rather than immediately
> evaluated. At function call time, the expression is evaluated, and the
> result (an object, a.k.a. a value) is bound to the parameter.

The code for it is part of the byte-code, and I'm planning to have
either the source code or the AST (or a reconstituted source code)
stored for documentation purposes. This, in fact, is true at
compilation time regardless of whether it's early-bound or late-bound.
Consider:

def make_func():
    def func(arg=CONFIG.get('key', NULL)): ...

Is the expression for this default argument value "stashed away"
somewhere? Well, kinda, I guess. It's part of the code that the 'def'
statement produces, and will be run when make_func() runs. The
difference is that here:

def make_func():
    def func(arg=>CONFIG.get('key', NULL)): ...

the code is part of func, rather than make_func.

So you're absolutely right: either way, the default is an expression.
I'm using the term "default expression" to mean that the expression is
evaluated at call time rather than def time, but I'm open to other
terminology.

> In neither case is it correct to say that the default value of arg is
> the *expression* `CONFIG.get('key', NULL)`, it is in both the early and
> late bound cases the *result* of *using* (evaluating) the expression to
> generate a value.
>
> https://en.wikipedia.org/wiki/Use%E2%80%93mention_distinction
>
> I'm fairly confident that everyone understands that:
>
> "the default value is CONFIG.get('key', NULL)"
>
> is shorthand for the tediously long and pedantic explanation that it's
> not the expression itself that is the default value, but the result of
> evaluating the expression. Just like we understand it here:
>
>     if arg is None:
>         arg = CONFIG.get('key', NULL)
>
> The only difference is when the expression is evaluated.

Exactly.

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/V56SW3JXK7QGDUEYW35KCMWMQWGQ3GAB/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to