I've just updated PEP 671 https://www.python.org/dev/peps/pep-0671/
with some additional information about the reference implementation,
and some clarifications elsewhere.
*PEP 671: Syntax for late-bound function argument defaults*
Questions, for you all:
1) If this feature existed in Python 3.11 exactly as described, would
you use it?
2) Independently: Is the syntactic distinction between "=" and "=>" a
cognitive burden?
(It's absolutely valid to say "yes" and "yes", and feel free to say
which of those pulls is the stronger one.)
3) If "yes" to question 1, would you use it for any/all of (a) mutable
defaults, (b) referencing things that might have changed, (c)
referencing other arguments, (d) something else?
4) If "no" to question 1, is there some other spelling or other small
change that WOULD mean you would use it? (Some examples in the PEP.)
5) Do you know how to compile CPython from source, and would you be
willing to try this out? Please? :)
I'd love to hear, also, from anyone's friends/family who know a bit of
Python but haven't been involved in this discussion. If late-bound
defaults "just make sense" to people, that would be highly
informative.
Any and all comments welcomed. I mean, this is python-ideas after
all... bikeshedding is what we do best!
and if you're depending on that behaviour, it's
been locked in as the function's API, which causes problems if None
ever becomes a meaningful non-default value.
None-aware operators are solving a different problem. They allow you
to accept None, but then simplify the replacement of it with some
other value. This proposal allows you to leave None out of the
equation altogether. And it only works if None isn't a valid value.
> * The function code becomes unreadable if the parameter-setting code is long. Having a long piece of code inside the function after "if parameter is None" is just fine. Having none-aware operators would make such code more succinct.
>
Again, that only works if None is not a valid parameter value, and PEP
505 doesn't generalize to other sentinels at all.
If the code is too long, don't put it into the parameter default. But
"if x is None: x = []" can easily be replaced with "x=>[]" and the
parameters will actually become shorter.
ANY feature can be used badly. You can daisy-chain everything into a
gigantic expression with horrendous abuses of lambda functions, but
that doesn't mean you should. It also doesn't mean that lambda
functions are bad :)
> * People nearly always avoid writing code in the parameter defaults themselves, and this new practice adds a lot of cognitive load. E.g., people rarely write:
> def f(x: int = 1+g()) -> None: ...
> Parameter lists are already busy enough with parameter names, annotations, and defaults. We don't need to encourage this practice.
>
They don't become any more noisy by being able to use defaults that
aren't constant. The main goal is to put the function header in the
function header, and the function body in the function body, instead
of having the function body doing part of the work of the header :)
> In short, I think this is a creative idea, a great exploration. While optional parameters are common, and some of them have defaults that are calculated inside the function, my feeling is that people will continue to set their values inside the function.
>
In some cases, they certainly will. And that's not a problem. But for
the cases where it's better to put it in the header, it's better to
have that option than to restrict it for an arbitrary technical
limitation.
Some languages don't have ANY function defaults. They simply have
"optional arguments", where an omitted optional argument will always
and only have a specific null value. Python allows you to show what
the default REALLY is, and that's an improvement. I want to be able to
show what the default is, even if that is defined in a non-constant
way.
ChrisA
_______________________________________________
Python-ideas mailing list -- python...@python.org
To unsubscribe send an email to python-id...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python...@python.org/message/23E62MLZH3ZMRYWTYPXDKG2LWT6X3G2V/
Code of Conduct: http://python.org/psf/codeofconduct/
--
---
You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/cz3I79-jyp0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python-ideas/CAPTjJmpcUxSOCGfxyDFPU8G-NXHq_59dXAA_t2-YeFbtw7dxyw%40mail.gmail.com.
I've just updated PEP 671 https://www.python.org/dev/peps/pep-0671/
with some additional information about the reference implementation,
and some clarifications elsewhere.
*PEP 671: Syntax for late-bound function argument defaults*
Questions, for you all:
1) If this feature existed in Python 3.11 exactly as described, would
you use it?
2) Independently: Is the syntactic distinction between "=" and "=>" a
cognitive burden?
4) If "no" to question 1, is there some other spelling or other small
change that WOULD mean you would use it? (Some examples in the PEP.)
5) Do you know how to compile CPython from source, and would you be
willing to try this out? Please? :)
1) If this feature existed in Python 3.11 exactly as described, would
you use it?
2) Independently: Is the syntactic distinction between "=" and "=>" a
cognitive burden?
3) If "yes" to question 1, would you use it for any/all of (a) mutable
defaults, (b) referencing things that might have changed, (c)
referencing other arguments, (d) something else?
4) If "no" to question 1, is there some other spelling or other small
change that WOULD mean you would use it? (Some examples in the PEP.)
1) If this feature existed in Python 3.11 exactly as described, would
you use it?
2) Independently: Is the syntactic distinction between "=" and "=>" a
cognitive burden?
3) If "yes" to question 1, would you use it for any/all of (a) mutable
defaults, (b) referencing things that might have changed, (c)
referencing other arguments, (d) something else?
4) If "no" to question 1, is there some other spelling or other small
change that WOULD mean you would use it? (Some examples in the PEP.)
5) Do you know how to compile CPython from source, and would you be
willing to try this out? Please? :)
On Wed, Dec 1, 2021 at 10:30 PM André Roberge <andre....@gmail.com> wrote:
>> 2) Independently: Is the syntactic distinction between "=" and "=>" a
>> cognitive burden?
>
> Yes.
> I really think that using a keyword like defer, or from_calling_scope ;-), would significantly reduce the cognitive burden.
Also fair. I'm not a fan of keywords for this sort of thing, since it
implies that you could do this:
def f(x=defer []): ...
dflt = defer []
def f(x=dflt): ...
which is a completely different proposal (eg it would be evaluated
only when you "touch" that, rather than being guaranteed to be
evaluated before the first line of the function body). That's why I
want to adorn the equals sign and nothing else.
>> 4) If "no" to question 1, is there some other spelling or other small
>> change that WOULD mean you would use it? (Some examples in the PEP.)
>
>
> *Perhaps* if a keyword would be used instead of symbols, I might reconsider.
>
> I find the emphasis of trying to cram too much information in single lines of code to be really a burden. Many years ago, I argued very unsuccessfully for using a 'where:' code block for annotations. (To this day, I still believe it would make the code much more readable, at the cost of a slight duplication.) Using what is at first glance a cryptic operator like => for late binding is not helping readability, especially when type annotations are thrown in the mix.
>
> Aside: at the same time, I can see how using => instead of lambda as a potential win in readability, including for beginners.
It's interesting how different people's views go on that sort of
thing. It depends a lot on how much people expect to use something.
Features you use a lot want to have short notations, features you
seldom use are allowed to have longer words.
I think that the only
thing I might use it for is to make it easier to annotate defaults (as
f(a: list[int] => []) rather than as f(a: list[int] | None = None).
On Thu, Dec 2, 2021 at 12:42 AM David Mertz, Ph.D.
<david...@gmail.com> wrote:
>> 4) If "no" to question 1, is there some other spelling or other small
>> change that WOULD mean you would use it? (Some examples in the PEP.)
>
> Yes, the delay/later/defer keyword approach is not confusing, and does not preempt a later feature that would actually be worth having.
Do you mean changing the spelling of the existing proposal, or a
completely different proposal for deferred objects that are actually
objects? Because that is NOT what I mean by a "small change". :)
def fun(things: list[int] = defer []) -> int:# ... some implementation
result = defer really_expensive_calculation()if predicate:doubled = result * 2
On 1 Dec 2021, at 06:16, Chris Angelico <ros...@gmail.com> wrote:
I've just updated PEP 671 https://www.python.org/dev/peps/pep-0671/
with some additional information about the reference implementation,
and some clarifications elsewhere.
*PEP 671: Syntax for late-bound function argument defaults*
Questions, for you all:
1) If this feature existed in Python 3.11 exactly as described, would
you use it?
2) Independently: Is the syntactic distinction between "=" and "=>" a
cognitive burden?
(It's absolutely valid to say "yes" and "yes", and feel free to say
which of those pulls is the stronger one.)
3) If "yes" to question 1, would you use it for any/all of (a) mutable
defaults, (b) referencing things that might have changed, (c)
referencing other arguments, (d) something else?
4) If "no" to question 1, is there some other spelling or other small
change that WOULD mean you would use it? (Some examples in the PEP.)
5) Do you know how to compile CPython from source, and would you be
willing to try this out? Please? :)
I'd love to hear, also, from anyone's friends/family who know a bit of
Python but haven't been involved in this discussion. If late-bound
defaults "just make sense" to people, that would be highly
informative.
Any and all comments welcomed. I mean, this is python-ideas after
all... bikeshedding is what we do best!
The reference implementation currently has some test failures, which
I'm looking into. I'm probably going to make this my personal default
Python interpreter for a while, to see how things go.
ChrisA
_______________________________________________
Python-ideas mailing list -- python...@python.org
To unsubscribe send an email to python-id...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
"If param is missing **or None**, the default if blah..."
I reject Chris' characterisation of this as a hack. There are function parameters where None will *never* in any conceivable circumstances become a valid argument value, and it is safe to use it as a sentinel.
Hm. A word is "vastly less confusing". OK. Should Python have been designed with
However, even if I assume the mythical future PEP never happens, in terms of readability, a WORD is vastly less confusing than a combination of punctuation that has no obvious or natural interpretation like '=>'. Or rather, I think that spelling is kinda-sorta obvious for the lambda meaning, and the use you want is kinda-sorta similar to a lambda. So I *do* understand how you get there... but it still seems like much too much line noise for a very minimal need.
> But it IS stored! There is no way for it to be evaluated without it
> being stored!
>
I'm not sure I understand you here. How is the late-bound default
"stored" when one side of a ternary is "not stored"?
>>> def foo(a):... b = a + 1... print(b)...>>> foo.__code__<code object foo at 0x7f167e539710, file "<ipython-input-7-3c44060a0872>", line 1>
How is a late-bound default different from half of a conditional expression?
def f(lst=>[], n=>len(lst)):
def f(*args):
lst = args[0] if len(args) > 0 else []
n = args[1] if len(args) > 1 else len(lst)
On Wednesday, December 1, 2021 at 1:18:33 AM UTC-5 Chris Angelico wrote:I've just updated PEP 671 https://www.python.org/dev/peps/pep-0671/
with some additional information about the reference implementation,
and some clarifications elsewhere.
*PEP 671: Syntax for late-bound function argument defaults*
Questions, for you all:
1) If this feature existed in Python 3.11 exactly as described, would
you use it?
No, I would avoid for the sake of readers. Anyway, it can't be used in any public projects until thy drop support for 3.10, which is many years off.Also, I think this question is quite the biased sample on python-ideas. Please consider asking this to less advanced python users, e.g., reddit.com/r/python or learnpython.
2) Independently: Is the syntactic distinction between "=" and "=>" a
cognitive burden?
(It's absolutely valid to say "yes" and "yes", and feel free to say
which of those pulls is the stronger one.)
Yes.
3) If "yes" to question 1, would you use it for any/all of (a) mutable
defaults, (b) referencing things that might have changed, (c)
referencing other arguments, (d) something else?
4) If "no" to question 1, is there some other spelling or other small
change that WOULD mean you would use it? (Some examples in the PEP.)
No.5) Do you know how to compile CPython from source, and would you be
willing to try this out? Please? :)
I'd love to hear, also, from anyone's friends/family who know a bit of
Python but haven't been involved in this discussion. If late-bound
defaults "just make sense" to people, that would be highly
informative.
Any and all comments welcomed. I mean, this is python-ideas after
all... bikeshedding is what we do best!
This PEP has a lot of interesting ideas. I still think that none-aware operators (PEP 505) are an easier, more readable general solution to binding calculated default values to arguments succinctly. I think the problems with this idea include:* The caller cannot explicitly ask for default behaviour except by omitting the parameter. This can be very annoying to set up when the parameter values are provided from other places, e.g.,if need_x:# do lots of stuffx = whateverelse:# do morex = Nonef(x=x, ...) # easy, but with this PEP, you would have to find a way to remove x from the parameter list. Typically, removing a parameter from a dynamically-created parameter list is hard.* The function code becomes unreadable if the parameter-setting code is long. Having a long piece of code inside the function after "if parameter is None" is just fine. Having none-aware operators would make such code more succinct.* People nearly always avoid writing code in the parameter defaults themselves, and this new practice adds a lot of cognitive load. E.g., people rarely write:def f(x: int = 1+g()) -> None: ...Parameter lists are already busy enough with parameter names, annotations, and defaults. We don't need to encourage this practice.In short, I think this is a creative idea, a great exploration. While optional parameters are common, and some of them have defaults that are calculated inside the function, my feeling is that people will continue to set their values inside the function.Best,Neil
If the coder's intent is to have an optional parameter default to an empty list, the most EXPLICIT way to encode that intent would be to have the optional parameter default to an empty list. It's categorically LESS EXPLICIT to bind the parameter to None and add boilerplate code to the body of the function to correct that.
I think it's a nearly philosophical distinction but right now there is no such thing as “an optional parameter defaulting to an empty list”. Or rather there is, but it's not what you really want “a different empty list for every call of the function”.
To me, it's not absurd that “creating a new object and binding the parameter to it” is sufficiently complex that we don't cram it into the function signature. It's fine to just have code in the function body...
especially since there does not seem to be an overwhelming consensus for either the concept or the proposed syntaxes.
(Also maybe not calling what we have been happily (at least for some of us) doing for years "a hack" would be a good way to have a more civil discussion)
Nicholas Cole"There is nothing that this proposal makes possible that is not already
possible with more explicit code."
There's nothing any of Python's syntax makes possible that is not already possible with Brainfuck or any other language that's Turing complete. The current hacks used to get around the lack of late-bound optional parameters aren't more explicit. They just require more code. If the coder's intent is to have an optional parameter default to an empty list, the most EXPLICIT way to encode that intent would be to have the optional parameter default to an empty list. It's categorically LESS EXPLICIT to bind the parameter to None and add boilerplate code to the body of the function to correct that.
I think it's a nearly philosophical distinction but right now there is no such thing as “an optional parameter defaulting to an empty list”. Or rather there is, but it's not what you really want “a different empty list for every call of the function”. To me, it's not absurd that “creating a new object and binding the parameter to it” is sufficiently complex that we don't cram it into the function signature. It's fine to just have code in the function body, especially since there does not seem to be an overwhelming consensus for either the concept or the proposed syntaxes.(Also maybe not calling what we have been happily (at least for some of us) doing for years "a hack" would be a good way to have a more civil discussion)BestE
_______________________________________________
Python-ideas mailing list -- python...@python.org
To unsubscribe send an email to python-id...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python...@python.org/message/O5GDCBMNUEPTSYS2AVZOFY4IUZAWMXFH/