On Sun, Aug 16, 2020 at 5:45 AM Steven D'Aprano <st...@pearwood.info> wrote:

> On Mon, Aug 17, 2020 at 12:32:08AM +1200, Greg Ewing wrote:
> > On 16/08/20 11:49 am, Guido van Rossum wrote:
> > >    SEMANTICS OF NO ARGUMENTS
> > >    I can see two basic ways of allowing no arguments. One is for the
> > >    interpreter to construct an object that is the argument passed to
> > >    __getitem__ and so forth. The other is to not pass an argument at
> > >    all. I see this as a secondary question.
> >
> > If d[] were to be allowed, I would expect it to pass an empty
> > tuple as the index, since it's the limiting case of reducing the
> > number of positional indices.
>
> So you would expect `obj[]` and `obj[()]` to be the same?
>

That's not terrible, since these are also the same:
```
obj[x] === obj[(x)]
obj[x, y] === obj[(x, y)]
```
(Even though `obj[x]` is still an exception because it's the only form that
isn't tuplified.)

On the other hand, it's *also* the limiting case of reducing the number of
keyword arguments, so whatever is passed here should also be passed as the
positional part of the key when only keyword arguments are present, and I'm
not sure what I think of using `()` for that.


> Personally, I think that unless there is an overwhelmingly good use-case
> for an empty subscript, we should continue to treat empty subscripts
> (no positional or keyword arguments) as a syntax error.
>

That's where I am too right now. But I think there may be at least a
_decent_ use case: the `Tuple` type in type annotations. (And since PEP 585
also the `tuple` type.)

We have `Tuple[int, int]` as a tuple of two integers. And we have
`Tuple[int]` as a tuple of one integer. And occasionally we need to spell a
tuple of *no* values, since that's the type of `()`. But we currently are
forced to write that as `Tuple[()]`. If we allowed `Tuple[]` that odd edge
case would be removed.

So I probably would be okay with allowing `obj[]` syntactically, as long as
the dict type could be made to reject it.

Alas, I thought I had a solution, but it doesn't work for `__setitem__`: we
can easily state that `obj[]` calls `obj.__getitem__()` and whether that's
accepted or not depends on whether `obj.__getitem__` has a default value
for its `key` positional argument. But what to do for `obj[] = x`? We can't
call `obj.__setitem__(x)` -- well, we could, but it would be super ugly to
write such a `__getitem__` method properly -- similar to supporting
`range(n)`.

So my intuition is failing me. It looks like `d[] = x` will need to come up
with *some* key, and the only two values that sound at all reasonable are
`()` (for the reason Greg mentioned) and `None` (because it's the universal
"nothing here" value). But either way it's not reasonable for `dict` to
reject those keys -- they are legitimate keys when passed explicitly. Using
`()` is slightly better because it helps debugging: if you have a dict with
an unexpected `None` key you should look for a key computation that
unexpectedly returned `None`, and we can now add that if you have a dict
with an unexpected `()` key, you should look for an assignment of the form
`d[] = x`.

But it would be better if `d[] = x` could be simply rejected -- either at
runtime (perhaps with a TypeError, like for calling a function with
insufficient arguments), or syntactically. (That is, if you believe, like
me, that `d[key, kwd=val]` should be rejected.) Hence, `Tuple[]` qualifies
as a decent use case, but not as an overwhelmingly good one.

I can think of another way to deal with this -- we could define a new
sentinel object (e.g. `Nope` :-), `d[]` could be equivalent to `d[Nope]`,
and the dict class could reject `Nope` as a key value. But that's quite
ugly, and it's arbitrary, too.



PS. All this reminds me of a complaint I heard 4-5 decades ago from an
experienced programmer when I was just learning the ropes, and which
somehow stuck in my mind ever since: "... and yet again, the empty
[sequence] is treated rather shabbily." (It sounded better in Dutch --
"stiefmoederlijk", meaning "stepmotherly".)

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
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/3AXKZGJCRBQOZDMR3FBG5YBKRKWR3U7D/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to