On Sun, Oct 24, 2021 at 9:52 PM Serhiy Storchaka <storch...@gmail.com> wrote:
>
> 23.10.21 19:07, Chris Angelico пише:
> > _missing = object()
> > def spaminate(thing, count=_missing):
> >     if count is _missing: count = thing.getdefault()
> >
> > Proposal: Proper syntax and support for late-bound argument defaults.
> >
> > def spaminate(thing, count=:thing.getdefault()):
> >     ...
>
> Few years ago I proposed a syntax for optional arguments without default
> value:
>
> def spaminate(thing, count=?):
>     try:
>         count
>     except UnboundLocalError:
>         count = thing.getdefault()
>     ...

Ah yes, I'd forgotten about this proposal.

> It would help in cases in which we now use None or special singleton
> value. It is more general than late-bound arguments, because it can be
> used in cases in which the default argument cannot be expressed, like in
> getattr() and dict.pop().

True, but in the example you give here, I would definitely prefer
"count=>thing.getdefault()".

> The code for initialization of the default value is something
> complicated, but we can introduce special syntax for it:
>
>     if unset count:
>         count = thing.getdefault()
>
> or even
>
>     count ?= thing.getdefault()

This is the perfect way to stir the pot on the None-coalescing
discussion, because now you're looking at a very real concept of null
value :)

(Although there's no way to return this null value from a function or
pass it to another, so the state of being unbound should be local to a
single code unit.)

> > 1) Inspecting the function would reveal the source code for the late-bound 
> > value
> > 2) There is no value which can be passed as an argument to achieve the
> > same effect
>
> This is the largest problem of both ideas. The inspect module has no way
> to represent optional arguments without default value, and any solution
> will break user code which is not ready for this feature.

There kinda sorta is a way to do it, at least for keyword arguments:

def func_left(x, y=>len(x)): ...

def func_right(x, y=?):
    if unset y: y = {}
    else y = {"y": y}
    return func_left(-x, **y)

But if there were a value that could be passed as an argument to
indicate "no value", then we'd come across the same problem of using
None as a default: sometimes, literally any value could be valid, and
we still need to signal the absence of a value.

ChrisA
_______________________________________________
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/KGBKQFBJA66T2XR5DM4EWW74GNAJ56AH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to