I’m still not clear if this is a disagreement about something more than
terminology, but as I understand it, other languages that have non-constant
defaults use late binding, and call them “defaults”.

It seems to be a well accepted term.

-CHB




On Thu, Dec 9, 2021 at 12:45 AM Brendan Barnwell <brenb...@brenbarn.net>
wrote:

> On 2021-12-08 23:22, Chris Angelico wrote:
> > On Thu, Dec 9, 2021 at 5:54 PM Brendan Barnwell <brenb...@brenbarn.net>
> wrote:
> >>
> >> On 2021-12-08 20:36, Chris Angelico wrote:
> >> > Remember, though: The comparison should be to a function that looks
> like this:
> >> >
> >> > def f(a=[], b=_SENTINEL1, c=_SENTINEL2, d=_SENTINEL3):
> >> >      if b is _SENTINEL1: b = {}
> >> >      if c is _SENTINEL2: c = some_function(a, b)
> >> >      if d is _SENTINEL3: d = other_function(a, b, c)
> >> >
> >> > If you find the long-hand form more readable, use the long-hand form!
> >> > It's not going away. But the introspectability is no better or worse
> >> > for these two. The late-bound defaults "{}", "some_function(a, b)",
> >> > and "other_function(a, b, c)" do not exist as objects here. Using PEP
> >> > 671's syntax, they would at least exist as string constants, allowing
> >> > you to visually see what would happen (and, for instance, see that in
> >> > help() and inspect.signature).
> >>
> >>         I don't want to get bogged down in terminology but I am becoming
> >> increasingly frustrated by you using the term "default" both for things
> >> that are values and things that are not, as if there is no difference
> >> between them.
> >
> > That's absolutely correct: I am using the term "default" for anything
> > that provides a default for an optional argument that was omitted. In
> > some cases, they are default values. In other cases, they are default
> > expressions. If your docstring says "omitting d will use the length of
> > a", then the default for d is len(a).
>
>         Your definition is somewhat circular, because you say that a
> default is
> "anything that provides a default".  But that says "default" again.  So
> what is a default?
>
>         By your definition, any arbitrary code inside a function body that
> eventually assigns something to an argument name is a default.  (It is
> not clear to me whether you would consider some code a default if it may
> or may not assign a value to an argument, depending on some conditions.)
>   So I don't agree with that definition.  That can be default BEHAVIOR,
> but it is function behavior; it is not an argument default.
>
> >>  There are no late-bound defaults here, in the sense that
> >> I mean, which as I said before has to do with default VALUES.  There is
> >> just code in the function body that does stuff.  I am fine with code in
> >> a function body doing stuff, but that is the purview of the function and
> >> not the argument.  An individual ARGUMENT having a default VALUE is not
> >> the same as the FUNCTION defining BEHAVIOR to deal with a missing value
> >> for an argument.
> >
> > In a technical sense, the default value for b is _SENTINEL1, but would
> > you describe that in the docstring, or would you say that omitting b
> > would use a new empty dictionary? You're getting bogged down, not in
> > terminology, but in mechanics. At an abstract level, the default for
> > that argument is whatever would be used if the argument is omitted.
>
>         I don't agree.  At an abstract level, there is no clear dividing
> line
> between what you call an argument default and just "arbitrary behavior
> of the function".  What if "what would be used" depends on random
> numbers or data from some external source?
>
>         Or, again, what you are describing is not an argument default (in
> my
> conception).  It may be the BEHAVIOR of the function to do a certain
> thing (like use a certain value in place of an omitted argument) but
> unless that behavior is segmented and associated with the argument
> itself (not merely part of the function's code flow) I don't consider it
> an argument default.
>
>         As for the docstring, yes, I might well mention _SENTINEL1 in the
> docstring.  I certainly wouldn't see anything wrong with that.  That's
> what the default is.  Again, the function may USE that value in some
> way, but that doesn't mean that's not what the default is; it just means
> the function conditions its behavior on its argument value, as any
> function may do on any argument value, omitted or not.  I get the
> impression you think that in a case like that the default "really is"
> something else defined in the body of the function, but again I
> disagree.  The default really is _SENTINEL1.  Conceptually we may
> understand that the function will use that value in a special way, but
> that is not really any different than understanding that passing "r" to
> open() will open the file for reading while passing "w" will open it for
> writing.  It's just that to know how to use a function you need to know
> more than the default values of the arguments; you need to know what
> they MEAN, and (at least with current technology :-) we have no way of
> deriving that from the source code.
>
>         You're quite right that "at an abstract level" it may be the case
> that
> the default behavior is to do a certain thing, but I guess one way to
> state my position would be that I think that is TOO abstract of a level
> to worry about representing in code.  At an abstract level I may say
> "this function computes the number of paths of length N between the
> given nodes in the given graph", but I don't expect that to be mentioned
> in the signature or automatically provided in the docstring.  I would
> certainly WRITE it in the docstring, but I don't expect Python to deduce
> that "abstract" level of meaning from code annotations and write that
> docstring for me.
>
>         In other words, I think mechanics is the right level to be at
> here.  We
> cannot hope to capture the abstract level that you're describing, and I
> think doing so will just muddle matters.  At an abstract level we say
> ""this function computes the number of paths of length N between the
> given nodes in the given graph" but what we write is `def n_paths(graph,
> node1, node2)`.  I don't see any reason we need to be able to write
> `len(x)` in the function signature just because at that abstract level
> we think of it as something that may be computed later.  This is
> especially so because, as I mentioned above, there is no clear line
> separating "code that we can write in a function to assign a default
> value to an argument" and "code we can write in a function for other
> purposes" --- and thus there is no way to distinguish behavior that is
> "tied" to a particular argument from just code that uses any old
> combination of values it wants.
>
>         We write code in terms of instrumental units which necessarily are
> at a
> slightly more concrete level than the purely abstract or conceptual
> realm of "what this function does".  For instance, objects (which, until
> now, every function argument, default or not, is).  I don't see any
> reason why late-bound defaults should be represented in code in a way
> that attempts to capture this abstract level when other aspects of
> functions are not and cannot be.
>
> > To justify this, please explain WHY it is so important for defaults to
> > all be objects. Not just "that's how they are now", but why that is an
> > important feature.
>
>         Because I'm used to reasoning about Python code in terms of
> operations
> on objects, and so are a lot of other people.  Everything I or anyone
> else currently needs to know about how functions and their arguments
> work in Python can be thought of in terms of objects.  Why add a new
> complication?  I mean, okay, maybe that is really just saying "that's
> how they are now", although it's more like "right now defaults are part
> of the big set of things that are objects and this change would peel
> them off and create a new type of thing".
>
>         But apart from that, I think part of what makes Python a nice
> language
> is the way that many language functions are represented in terms of
> objects, for instance the iterator and descriptor protocols.  The idea
> of the object as a locus of functionality --- that the way you "do
> something" (like loop or access an attribute) is represented as "get an
> object representing the functionality and call certain methods on it"
> --- gives unity to many Python features.  It's true that's a pretty
> abstract reason, but I think it's a legit one.
>
>         Also, let's remember that burden of evidence is really the other
> way
> around here.  Can you really explain WHY it is so important for
> late-bound defaults to be represented with special syntax of the type
> you propose?  Not only can you not rely on "that's how they are now"
> (because they're not), but in fact you must overcome the reverse
> argument, namely that people have been doing pretty well with just
> early-bound defaults for decades now.  In other words, even if it is not
> particularly important for defaults to be objects, it may still be more
> important than being able to write a "late-bound default" (aka "behavior
> in the function body") in the signature.
>
> --
> Brendan Barnwell
> "Do not follow where the path may lead.  Go, instead, where there is no
> path, and leave a trail."
>     --author unknown
> _______________________________________________
> 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/EXDGAZCHULMFAIP4ARLILRQF76GIILWF/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
_______________________________________________
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/P22UIWHOYOJC7QESKLYNX5LF4RIL6Q3T/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to