On Sun, 2020-08-16 at 12:07 -0700, Guido van Rossum wrote: > 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`.
For what its worth, NumPy uses `None` to indicate inserting a new axis/dimensions (we have an `np.newaxis` alias as well): arr = np.array(5) arr.ndim == 0 arr[None].ndim == arr[None,].ndim == 1 So that would be problematic. There are two (subtly different [1]) acceptable choices for `ndarray[]`: arr[] is arr[()] or: arr[] is arr[...] In either case, though, I guess the arguments above against `None` apply likely similarly for `Ellipsis`. And since there are two different choices refusing to choose is fair for NumPy itself (for some other array-objects the result of those two choices may be identical). - Sebastian [1] The difference is that `arr[()]` extracts a scalar, while `arr[...]` returns the array (container) unchanged. This difference only matters for zero dimensional arrays. There may be reasons to prefer one over the other, but I can't think of any right now. > > 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".) > > _______________________________________________ > 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/
signature.asc
Description: This is a digitally signed message part
_______________________________________________ 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/AC3NNTLGAA53M5MADTKMKKVICFDFQEOP/ Code of Conduct: http://python.org/psf/codeofconduct/