On 25.05.20 18:29, Chris Angelico wrote:

On Tue, May 26, 2020 at 2:24 AM Dominik Vilsmeier
<dominik.vilsme...@gmx.de> wrote:
On 25.05.20 17:29, Ricky Teachey wrote:


On Mon, May 25, 2020, 6:49 AM Rob Cliffe via Python-ideas 
<python-ideas@python.org> wrote:
  (Possibly heretical) Thought:
ISTM that when the decision was made that arg default values should be evaluated
         once, at function definition time,
rather than
         every time the function is called and the default needs to be supplied
that that was the *wrong* decision.
There may have been what seemed good reasons for it at the time (can anyone 
point me
to any relevant discussions, or is this too far back in the Python primeval 
soup?).
But it is a constant surprise to newbies (and sometimes not-so-newbies).
As is attested to by the number of web pages on this topic.  (Many of them 
defend
the status quo and explain that it's really quite logical - but why does the 
status quo
*need* to be defended quite so vigorously?)


First of all: supplying a default object one time and having it start fresh at 
every call would require copying the object. But it is not clear what kind of 
copying of these default values should be done. The language doesn't inherently 
know how to arbitrarily make copies of every object; decisions have to be made 
to define what copying the object would MEAN in different contexts.

It wouldn't copy the provided default, it would just reevaluate the expression. 
Python has already a way of deferring evaluation, generator expressions:

     >>> x = 1
     >>> g = (x for __ in range(2))
     >>> next(g)
     1
     >>> x = 2
     >>> next(g)
     2

It's like using a generator expression as the default value and then if the 
argument is not provided Python would use `next(gen)` instead of the `gen` 
object itself to fill the missing value. E.g.:

     def foo(x = ([] for __ in it.count())):  # if `x` is not provided use 
`next` on that generator
         pass

Doing this today would use the generator itself to fill a missing `x`, so this 
doesn't buy anything without changing the language.

Well.... if you want to define the semantics that way, there's a way
cleaner form. Just talk about a lambda function:

def foo(x = lambda: []):
     pass

and then the function would be called and its return value assigned to
x, if the parameter isn't given.
Indeed, the above example originated from the idea of treating generator
expressions as default values in a special way, namely such that if the
corresponding parameter receives no argument then `next(gen)` would be
used instead of the `gen` object itself to supply a value (it would be a
breaking change but how many functions use generator expressions as
defaults?). But then the construct `([] for __ in it.count())` is worse
than `if x is None:` so there's no point in doing that.
_______________________________________________
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/LTR754HLGKNXUX7LWH4DLW43QJE6Z75U/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to