On Wed, Nov 3, 2021 at 6:01 PM Stephen J. Turnbull
<stephenjturnb...@gmail.com> wrote:
>
> Steven D'Aprano writes:
>
>  > "Write `arg=default` if you want the default to be evaluated just once,
>  > and `arg=late default` if you want the default to be evaluated each time
>  > it is needed. If you are not sure which one you need, use the
>  > first."
>
> Which of course is ambiguous, since the argument may be referenced
> many times in the function body or only late in the body.  Someone who
> doesn't yet understand how early binding of mutable defaults works is
> also somewhat likely to misunderstand "when needed" as a promise that
> resolves to an object the first time it is referenced, or as a thunk
> that gets run every time it is referenced, both of which are
> incorrect.

People will often have completely wrong understandings about things.
While it's possible to avoid some of those, we can't hold the language
back because *someone who doesn't understand* might misunderstand.
Mutable objects in general tend to be misunderstood.

Python has a strong policy of evaluating things immediately, or being
very clear about when they will be evaluated (eg generators when you
next() them). Resolving a promise to an object on first reference
would break that pattern completely, so I would expect most people to
assume that "each time it is needed" means "each time you omit the
argument".

And if they don't, they'll figure it out and go digging. Or not, as
the case may be; I've seen misunderstandings linger in people's brains
for a long time without ever being disproven.

(My own brain included.)

>  What you should write to be (more) accurate is
>
>     Write `arg=default` if you want the default to be evaluted when
>     the function is defined [and the value to be stored in the
>     function to be used when it is called], and `arg=late default` if
>     you want the default to be evaluated each time the function is
>     called.  If you are not sure which one you need, ask someone to
>     help you, because using the wrong one is a common source of bugs.
>
> The part in brackets is a gloss that might be helpful to the beginner,
> who might experience a WTF at "evaluated when defined"

And that's what happens when you need to be pedantically correct. Not
particularly useful to a novice, especially with the FUD at the end.

> To be honest, I was surprised you chose early binding for "when in
> doubt".  I would expect that "early binding when late is appropriate"
> is a much more common bug for beginners than "late binding when early
> is appropriate".  Of course I may be biased because it's the only bug
> now, but I would think that would continue to be true for beginners if
> late binding is made available.  Especially when they're testing code
> in the interactive interpreter.  There are probably many programs
> where the function is called with the argument missing only once, in
> which case it doesn't matter, until you invoke the function repeatedly
> in the same context.

There's a performance cost to late binding when the result will always
be the same. The compiler could optimize "=>constant" to "=constant"
at compilation time [1], but if it's not actually a compile-time
constant, only a human can know that that can be done.

But then the question becomes: should we recommend late-binding by
default, with early-binding as an easy optimization? I'm disinclined
to choose at this point, and will leave that up to educators and style
guide authors.

ChrisA
[1] Technically, there'd still be a difference, but only if you mess
with the function's dunders. So for safety, probably the compiler
should never optimize it.
_______________________________________________
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/K2UD46MJCCWDCYULAQJASXL2Y6JUOG2B/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to