Builtin dict should be callable, since a dict defines a function

Bengt Richter bokr at oz.net
Thu Dec 19 22:39:55 EST 2002


On 20 Dec 2002 02:59:41 GMT, bokr at oz.net (Bengt Richter) wrote:

>On Thu, 19 Dec 2002 18:17:03 -0800, Erik Max Francis <max at alcyone.com> wrote:
>
>>Bengt Richter wrote:
>>
>>> I posted the suggestion in a thread  Re: case-insensitive and
>>> internationalized sort,
>>> but it occurs to me that the principle is arguable from the abstract
>>> point of view.
>>> I.e., a dict implements a function key -> value, so why not let it
>>> accept a normal
>>> function arg list (i.e., the tuple) as the argument for its key ->
>>> value function?
>>> It should be a pretty simple change to provide __call__(self, *args):
>>> return self[args]
>>> under the hood, and let hashability chips fall where they will via [].
>>
>>But why would this be helpful?  A dictionary implements a mappable
>>interface; a function implements are callable interface.  They're
>>different interfaces; why would dovetailing them into the same interface
>>be beneficial?
>You can pass a reference to a dict to something that expects a function,
>e.g., a sort. You could pass it as a memoized-result proxy function in
>some context and catch KeyError to take care of LRU caching update, etc.
>I'm sure many uses would turn up once the obstacle was removed, and
>people thought of functions as mappings and vice versa ;-)
>>
>>It's a simple change, sure, but furthermore it's trivial enough for you
>>to implement it yourself in a subclass of dict.
>Yes (as I mentioned less specifically ;-) But not without the performance
Um, sorry 'bout that ;-/ I didn't mention it in this thread. I believe I did
in the other one. Anyway, obviously extra layers drag on speed.

But the main thing is that conceptually 

           +-----------+
   input-->| something |-->output
           +-----------+ 

is the same whether you spell it output=something(input) or
output=something[input], but when you pass the object something
somewhere, currently the somewhere has to do unnecessary work
before it can use it for input->|?|->output.

E.g., you can't apply(something, input) for both cases of

    something = {'x':'y'}
and
    def something(arg):
        if arg=='x': return 'y'
        raise KeyError

Why not? They both implement the same input->output function.
IMO it's an artificial limitation on orthogonality not to be
able to pass a dict to a place that expects a function.

>hit of an extra layer.
>
>I think a dict abstractly does define a function, so IMO it would be a good
>thing to allow access to it to be spelled that way. If you want to override
>__call__ in a subclass, fine, but let the base class provide a way to
>spell the natural default. A mapping is a function, and vv. ;-)
>

Regards,
Bengt Richter



More information about the Python-list mailing list