On Sun, Oct 31, 2021 at 3:16 PM Steven D'Aprano <st...@pearwood.info> wrote:
>
> On Sun, Oct 31, 2021 at 12:29:18PM +1100, Chris Angelico wrote:
>
> > That's optional parameters. It's entirely possible to have optional
> > parameters with no concept of defaults; it means the function can be
> > called with or without those arguments, and the corresponding
> > parameters will either be set to some standard "undefined" value, or
> > in some other way marked as not given.
>
> That's certainly possible with languages like bash where there are
> typically (never?) no explicit parameters, the function is expected to
> pop arguments off the argument list and deal with them as it sees fit.
> Then a missing argument is literally missing from the argument list, and
> all the parameter binding logic that the Python interpreter handles for
> you has to be handled manually by the programmer. Bleh.
>
> We could emulate that in Python by having the interpreter flag "optional
> without a default" parameters in such a way that the parameter remains
> unbound when called without an argument, but why would we want such a
> thing? That's truly a YAGNI anti-feature.
>
> If you really want to emulate bash, we can just declare the function to
> take `*args` and manage it ourselves, like bash.
>
>
> > Python, so far, has completely conflated those two concepts: if a
> > parameter is optional, it always has a default argument value. (The
> > converse is implied - mandatory args can't have defaults.)
>
> If a mandatory parameter has a default argument, it would never be used,
> because the function is always called with an argument for that
> parameter. So we have a four-way table:
>
>
>                    Mandatory    Optional
>                    Parameters   Parameters
>     -------------  -----------  ------------
>     No default:    okay         YAGNI [1]
>     Default:       pointless    okay
>     -------------  -----------  ------------
>
>
> [1] And if you do need it, it is easy to emulate with a sentinel:
>
>     def func(arg=None):
>         if arg is None:
>             del arg
>         process(arg)  # May raise UnboundLocalError
>
>
>
> None of this is relevant to the question of when the default values
> should be evaluated.
>

Agreed on all points, but I think the YAGNIness of it is less strong
than you imply. Rather than a sentinel object, this would be a
sentinel lack-of-object. The point of avoiding sentinels is, like
everywhere else, that the sentinel isn't really a value - it's just a
marker saying "this arg wasn't passed". So I agree with you that this
isn't a feature of huge value, and it's not one that I'm pushing for,
but it is at least internally consistent and well-defined.

Usually, what ends up happening is that there's code somewhere saying
"if arg is _sentinel:" (or "if arg is None:"), which would have
exactly the same meaning without the sentinel, if we had a way to say
"if arg isn't set".

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

Reply via email to