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/