On Sun, Oct 31, 2021 at 12:17 PM Brendan Barnwell <[email protected]> wrote:
>
> On 2021-10-30 16:12, Chris Angelico wrote:
> >> >         Increasingly it seems to me as if you are placing inordinate 
> >> > weight on
> >> >the idea that the benefit of default arguments is providing a "human
> >> >readable" description in the default help() and so on.  And, to be
> >> >frank, I just don't care about that.  We can already provide
> >> >human-readable descriptions in documentation and we should do that
> >> >instead of trying to create gimped human-readable descriptions that only
> >> >work in special cases.  Or, to put it even more bluntly, from my
> >> >perspective, having help() show something maybe sort of useful just in
> >> >the case where the person wrote very simple default-argument logic and
> >> >didn't take the time to write a real docstring is simply not a
> >> >worthwhile goal.
> > Interesting. Then why have default arguments at all? What's the point
> > of saying "if omitted, the default is zero" in a machine-readable way?
> > After all, you could just have it in the docstring. And there are
> > plenty of languages where that's the case.
>
>         The point of default arguments is to allow users of the function to
> omit arguments at the call site.  It doesn't have anything to do with
> docstrings.

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.

>         Or do you mean why not just have all omitted arguments set to some 
> kind
> of "undefined" value and then check each one in the body of the function
> and replace it with a default if you want to?  Well, for one thing it
> makes for cleaner error handling, since Python can tell at the time of
> the call that a required argument wasn't supplied and raise that error
> right away.

That's the JavaScript way - every parameter is optional. But it's
entirely possible to have some mandatory and some optional, while
still not having a concept of defaults.

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.)

>  It's sort of like a halfway type check, where you're not
> actually checking that the correct types of arguments were passed, but
> at least you know that the arguments that need to be passed were passed
> and not left out entirely.

Given that Python doesn't generally have any sort of argument type
checking, that's exactly what we'll get by default.

>         For another thing, it does mean that if you know the default at the
> time you're defining the function, you can specify it then.  What you
> can't do is specify the default if you don't know the default at
> function definition time, but only know "how you're going to decide what
> value to use" (which is a process, not a value).

Right. That's the current situation.

> > I'm of the opinion that having more information machine-readable is
> > always better. Are you saying that it isn't? Or alternatively, that
> > it's only useful when it fits in a strict subset of constant values
> > (values that don't depend on anything else, and can be calculated at
> > function definition time)?
>
>         Now wait a minute, before you said the goal was for it to be human
> readable, but now you're saying it's about being machine readable!  :-)

Truly machine readable is the best: any tool can know exactly what
will happen. That is fundamentally not possible when the default value
is calculated. Mostly machine readable means that the machine can
figure out what the default is, even if it doesn't know what that
means. My proposal (not in the reference implementation as yet) is to
have late-bound defaults contain a marker saying "the default will be
len(a)", even though the "len(a)" part would be just a text string.

>         What I am saying is that there is a qualitative difference between "I
> know now (at function definition time) what value to use for this
> argument if it's missing" and "I know now (at function definition time)
> *what I will do* if this argument is missing".  Specifying "what you
> will do" is naturally what you do inside the function.  It's a process
> to be done later, it's logic, it's code.  It is not the same as
> finalizing an actual VALUE at function definition time.  So yes, there
> is a qualitative difference between:
>
> # this
> if argument is undefined:
>         argument = some_constant_value
>
> # and this
> if argument is undefined:
>         # arbitrary code here
>
>         I mean, the difference is that in one case arbitrary code is allowed!
> That's a big difference.

Right. That is a very real difference, which is why there is a very
real difference between early-bound and late-bound defaults. But both
are argument defaults.

>         Based on some of your other posts, I'm guessing that what you mean
> about machine readability is that you appreciate certain kinds of
> labor-saving "self-documentation" techniques, whereby when we write the
> machine-readable code, the interpreter automatically derives some
> human-readable descriptions for stuff.  For instance when we write `def
> foo` we're just defining an arbitrary symbol to be used elsewhere in the
> code, but if we get an exception Python doesn't just tell us "exception
> in function number 1234" or the line number, but also tells us the
> function name.
>
>         And yeah, I agree that can be useful.  And I agree that it would be
> "nice" if we could write "len(a)" without quotes as machine-readable
> code, and then have that stored as some human-readable thing that could
> be shown when appropriate.  But if that's nice, why is it only nice in
> function arguments?  Why is it only nice to be able to associate the
> code `len(a)` with the human-readable string "len(a)" just when that
> string happens to occur in a function signature?

It would be very nice to have that feature for a number of places.
It's been requested for assertions, for instance. If that subfeature
becomes more generally available, the language will be the richer for
it.

>         So yes, it's true that adding convenience functions to derive
> human-readable forms from machine-readable code is handy, but it's not
> ALWAYS automatically good regardless of other considerations, and I
> don't see that it outweighs the costs here.  The benefit of
> autogenerating the string "len(a)" from the argument spec isn't quite
> zero but it's pretty tiny.

It's mainly about writing expressive code, which can then be
interpreted by humans AND machines. It's about writing function
defaults as function defaults, not working around a technical
limitation. It's about writing function headers such that they have
what function headers should have, allowing the function body to
contain only the function body.

We could just write every function with *args, **kwargs, and then do
all argument checking inside the function. We don't do this, because
it's the job of the function header to manage this. It's not the
function body's job to replace placeholders with actual values when
arguments are omitted.

ChrisA
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/I2GLNE47V5XXOFB5UNNLRXGFKQWDYT7F/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to