On Wed, Dec 8, 2021 at 11:28 PM Chris Angelico <ros...@gmail.com> wrote:

> On Thu, Dec 9, 2021 at 3:15 PM Jonathan Goble <jcgob...@gmail.com> wrote:
> > My preferences to resolve this are, in order:
> >
> > 1. Introduce `from __future__ import late_default`. When present,
> argument defaults in that file are late bound instead of early bound. After
> a suitable deprecation period, make the future statement the default
> behavior. Then Python will comply with best practices demonstrated by
> Steven's language review. I have not done any analysis, but I believe based
> on intuition that any breakage in libraries and scripts stemming from this
> would be relatively easy to fix, and most existing code should just work
> (in particular, the common existing usage of a sentinel as a default with
> an `is None` or `is sentinel` check in the body would not break and could
> be migrated to the new behavior at leisure). If true, it would result in
> minimal fuss for maximum benefit.
> >
>
> IMO this is strictly worse than supporting both alternatives with
> syntactic differences. The language still needs to support both,
> programmers still need to comprehend both, but instead of being able
> to distinguish "def f(x=[]):" from "def f(x=>[]):", you have to go
> look at the top of the file to see which way around it is. To the
> extent that the distinction needs to be visible, it needs to be
> visible at the function's definition, not at the top of the file.
>

Is it really worse? Yes, it's a burden during the transition period, but
the burden (both of managing both behaviors, and of grokking early-bound
mutable defaults) eventually goes away after a couple versions and adoption
time. After that, only one needs to be taught and understood. In contrast,
adding a syntax for late binding while keeping early binding means you have
to teach and comprehend both behaviors forever. I'd much, much rather have
a temporary burden than a permanent burden.


> > 2. If a future statement and behavior change is deemed too disruptive,
> then keep early binding, do not introduce late binding, and introduce a new
> use for the keyword `pass` to represent an absent argument. Under this
> idea, `pass` would be accepted as an expression in the following three
> contexts, and exactly nowhere else: a) as a complete argument to a call, b)
> as a complete "value" for an argument default, and c) in the expressions `x
> is pass` and `x is not pass`, but only when both `x` is a parameter to the
> immediately enclosing function and the default value of that parameter is
> `pass`. This way, `pass` acts as a sentinel that isn't a valid value in any
> other context, which would solve the issue of when `None` is a valid value.
> >
>
> This is a good idea that desperately needs good syntax. I don't like
> "pass" used in this way. It's perfectly implementable but only if
> someone can figure out how to write it.
>
> (I'd define it as "the default is for the variable to be unbound" and
> "if the variable is unbound". That makes very good sense and would
> work within the language.)
>
> Unfortunately this still has several of the problems that argument
> defaults are supposed to solve. It means that you can mark a parameter
> as optional, but you get no information about what it would be if
> omitted. That's just as bad as the current sentinel option, with the
> only advantage being that there's no sentinel.
>
> Option 2 might actually make a good extension beyond PEP 671, but it's
> not a replacement for it.
>

I never said it was a replacement. On the contrary, I explicitly said in
the first sentence of Option 2 to "do not introduce late binding". Period.
I am firmly against having both behaviors baked into the language forever.
If we cannot change the default behavior to late binding via a future
statement and a deprecation period, then we should not introduce late
binding at all. Python should have one permanent behavior, and should not
support both at once unless as part of a temporary transition to a new
default behavior.

In other words, the status quo with all of its warts is highly preferable
to me over PEP 671, however it's spelled.

I stand as follows:

My Option 1 (future statement, deprecation of early binding, and permanent
switch to late binding): +1
My Option 2 (syntax for an unbound argument): +0.4
Status quo (no changes at all): +0.3
PEP 671 or any other proposal to introduce a different spelling for late
binding (thereby supporting both at once forever): -1
_______________________________________________
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/R354OZSTCBYFLA3XKOQI22SNPNDGECIX/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to