Hi All

SUMMARY
This is a longish post. It looks at the idea in general terms, and outlines
a way to get the desired semantics (by not syntax) with Python as it is
today. And this would be forward compatible with the new syntax, if
provided later.

PRESENT
I like the idea of allowing
    >>> d[1, 2, 3, a=4, b=5]
and will explore it further.

First, we can already write
    >>> f(1, 2, 3, a=4, b=5)
but that only works for the get operation. For set the present behaviour is
    >>> f(1, 2, 3, a=4, b=5) = None
    SyntaxError: can't assign to function call
and I see no good reason to change that.

Going further, I'd say that allowing both
    >>> d[something] = value
    >>> value = d[something]
is essential to the difference between f(something) and d[something]. Both
are expressions, but only one of them can be assigned to.

The proposal therefore is to retain this essential difference, and remove
what the proposer regards as an inessential difference. (And I also regard
this as an inessential difference.)

Now let's use this class
    class Dummy:
        def __getitem__(self, *argv, **kwargs):
            return argv, kwargs
to peek into how
    >>> value = d[something]
works.

Here goes:
    >>> d = Dummy()
    >>> d[1]
    ((1,), {})
    >>> d[1, 2]
    (((1, 2),), {})
    >>> d[:]
    ((slice(None, None, None),), {})
    >>> d['a':'b']
    ((slice('a', 'b', None),), {})

We see that the interpreter passes to __getitem__ a single positional
argument (which is usually called the key). This is another difference
between d[something] and f(something).

By the way, the slice syntax items[a:b:c] is so often convenient and
widespread, that it's been long enabled in Python. I see no good reason to
change that.

FUTURE
Let's proceed. We continue to use d = Dummy(). Given that
       >>> key = d[1, 2, 3, a=4, b=5]
is allowed, what should we be able to say about the key. Clearly it should
be an instance of a class, and there should be a way of creating such an
instance without going via d. Let's call the class K (for key).

It is natural to say that
       >>> key_1 = d[1, 2, 3, a=4, b=5]
       >>> key_2 = K(1, 2, 3, a=4, b=5)
should define two K objects, that are identical. Once we have designed and
implemented the class K, we can achieve many of the benefits of this
proposal within existing Python.

Here goes. First syntax.
    >>> value = d[K(1, 2, 3, a=4, b=5)]
    >>> d[K(1, 2, 3, a=4, b=5)] = value

Next, the implementation of such K-mappings. Here, K.set and K.get
decorators will help. Something like (not tested):
    class MyMap:
        @K.adjust_get
        def __getitem__(self, x1, x2, x3, a, b):
            pass
where K.adjust_get interfaces between the K-object and the definition of
__getitem__.

Aside. Here, not tested, is an implementation of K.adjust_get.
    class K:
        @staticmethod
        def adjust_get(fn):
            def __getitem__(self, k):
                return fn(self, *k.argv, **k.kwargs)
            return __getitem__

This introduction of K allows collections to be created, that can be used
today with the syntax
    >>> value = d[K(1, 2, 3, a=4, b=5)]
    >>> d[K(1, 2, 3, a=4, b=5)] = value

Further, if the K()-less syntax
    >>> value = d[1, 2, 3, a=4, b=5]
    >>> d[1, 2, 3, a=4, b=5] = value
is added to Python, the existing K-collections could continue to be used,
with only a change to the decorator K.adjust_get (and also of course
K.adjust_set).

I think that is enough for now. I hope it helps some of us, sometimes. And
does no harm elsewhere.
-- 
Jonathan
_______________________________________________
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/3LFNGTEYVCS4JOCSERYHS752YT6VQFDA/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to