On Sun, Dec 5, 2021 at 6:16 AM Brendan Barnwell <brenb...@brenbarn.net> wrote:
>
> On 2021-12-04 03:50, Chris Angelico wrote:
> > On Sat, Dec 4, 2021 at 8:48 PM Steven D'Aprano <st...@pearwood.info> wrote:
> >> And third, when the interpreter fetches a default from
> >> func.__defaults__, if it is a LB function, it automatically calls that
> >> function with the parameters to the left of x (which in this case
> >> would be just b).
> >
> > Plausible. Okay.
> >
> > What this does mean, though, is that there are "magic objects" that
> > cannot be used like other objects. Consider:
>
>         Your proposal also has the same problem, since it involves "magic
> functions" that do not have usable values for their argument defaults,
> instead having some kind of Ellipsis two-step.  It's all a matter of
> what you consider magic.

My proposal allows any object to be used as a function default
argument. There's a minor technical difference that means that there's
a second lookup if you use Ellipsis, but you can still use Ellipsis
just fine.

>>> def f(x=...):
...     print(type(x), x)
...
>>> f()
<class 'ellipsis'> Ellipsis
>>> f(None)
<class 'NoneType'> None
>>> f("spam")
<class 'str'> spam

There are no objects that will behave differently if used in this way.
EVERY object can be a function default argument. Steve's proposal has
some objects (functions with the LB flag set) actually behave
differently - they *will not behave correctly* if used in this way.
This is a restriction placed on the rest of the language.

> > Great. So now we have some magnificently magical behaviour in the
> > language, which will have some nice sharp edge cases, but which nobody
> > will ever notice. Totally. I'm sure. Plus, we pay a performance price
> > in any function that makes use of argument references, not just for
> > the late-bound default, but in the rest of the code. We also need to
> > have these special functions that get stored as separate code objects.
> >
> > All to buy what, exactly? The ability to manually synthesize an
> > equivalent parameter value, as long as there's no assignment
> > expressions, no mutation, no other interactions, etc, etc, etc? That's
> > an awful lot of magic for not a lot of benefit.
>
>         I would consider most of what you say here an accurate description of
> your own proposal.  :-)

That's highly unfair. No, I won't let that pass. Please retract or
justify that statement. You are quoting the conclusion of a lengthy
post in which I show  significant magic in Steve's proposal,
contrasting it with mine which has much clearer behaviour, and you
then say that my proposal has the same magic. Frankly, that is not a
reasonable assertion, and I take offense.

>         Now we have magnificently magical behavior in the language, which will
> take expressions in the function signature and behind the scenes
> "inline" them into the function body.  We also need to have these
> special function arguments that do NOT get stored as separate objects,
> unlike ordinary function arguments.  All to buy what, exactly?  The
> ability to write something in the function signature that we can already
> write in the body, and that quite naturally belongs in the body, because
> it is executed when the function is called, not when it is defined.

You assert that it "belongs in the body", but only because Python
currently doesn't allow it to be anywhere else. Other languages have
this exact information in the function signature. This is a much
larger distinction than what Steve shows, which is the exact same
feature but with these magic callables.

> > I *really* don't like the idea that some types of object will be
> > executed instead of being used, just because they have a flag set.
> > That strikes me as the sort of thing that should be incredibly scary,
> > but since I can't think of any specific reasons, I just have to call
> > it "extremely off-putting".
>
>         I *really* don't like the idea that some types of argument will be
> inlined into the function body instead of being stored as first-class
> values like other `__defaults__`, just because there happens to be this
> one extra character next to the equals sign in the function signature.
> That strikes me as the sort of thing that should be incredibly scary.

You're still being highly offensive here. There's a HUGE difference
between these two assertions. Steve's proposal makes some objects
*behave differently when used in existing features*. It would be like
creating a new type of string which, when printed out, would eval
itself. That proposal wouldn't fly, and it's why f-strings are most
assuredly NOT first-class objects.

Why is it such a big deal for these function default expressions to
not be first-class objects? None of these are first-class either:

print(f"An f-string's {x+y} subexpressions")
print(x/y if y else "An if/else expression's sides")
assign(x.y[42], "An assignment target")

We don't have a problem with these being unable to be externally
referenced, manipulated, etc, as first-class objects. Why is it a
problem to be unable to refer to "new empty list" as some sort of
object when used like this?

def f(x=>[]): ...

Can you explain why it is necessary? And then, after that, explain why
you claim that Steve's proposal, which makes some objects *not even
work in early-bound defaults*, is just as magical?

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

Reply via email to