Python syntax in Lisp and Scheme

Bengt Richter bokr at oz.net
Sat Oct 4 15:38:58 EDT 2003


On Sat, 04 Oct 2003 17:02:41 GMT, Alex Martelli <aleax at aleax.it> wrote:
[...]
>
>def make_accumulator(initial_value):
>    accumulator = Bunch(value=initial_value)
>    def accumulate(addend):
>        accumulator.value += addend
>        return accumulator.value
>    return accumulate
>
>accumulate = make_accumulator(23)
>print accumulate(100)   # emits 123
>print accumulate(100)   # emits 223
>
>
>(using the popular Bunch class commonly defined as:
>    class Bunch(object):
>        def __init__(self, **kwds):
>            self.__dict__.update(kwds)
>).  There is, of course, a cultural gulf between this
>verbose 6-liner [using an auxiliary class strictly for
>reasons of better readability...!] and the terse Ruby 
>1-liner above, and no doubt most practitioners of both
>languages would in practice choose intermediate levels,
>such as un-densifying the Ruby function into:
>
I like the Bunch class, but the name suggests vegetables to me ;-)

Since the purpose (as I see it) is to create a unique object with
an attribute name space, I'd prefer a name that suggests that, e.g., NS,
or NSO or NameSpaceObject, so I am less likely to need a translation.


BTW, care to comment on a couple of close variants of Bunch with per-object class dicts? ...

    def mkNSC(**kwds): return type('NSC', (), kwds)()

or, stretching the one line a bit to use the instance dict,

    def mkNSO(**kwds): o=type('NSO', (), {})(); o.__dict__.update(kwds); return o

I'm wondering how much space is actually wasted with a throwaway class. Is there a
lazy copy-on-write kind of optimization for class and instance dicts that prevents
useless proliferation? I.e.,

 >>> type('',(),{}).__dict__
 <dictproxy object at 0x00901570>
 >>> type('',(),{}).__dict__.keys()
 ['__dict__', '__module__', '__weakref__', '__doc__']

seems like it could be synthesized by the proxy without a real dict
until one was actually needed to hold other state.

For qnd ns objects, I often do

    nso = type('',(),{})()
    nso.att = 'some_value'

and don't generally worry about the space issue anyway, since I don't make that many.

>
>def outer(a)
>  proc do |b|
>    a+b
>  end
>end
>
>or shortening/densifying the Python one into:
>
>def make_accumulator(a):
>    value = [a]
>    def accumulate(b):
>        value[0] += b
>        return value[0]
>    return accumulate
>
Or you could make a one-liner (for educational purposes only ;-)

 >>> def mkacc(a): return (lambda a,b: a.__setitem__(0,a[0]+b) or a[0]).__get__([a])
 ...
 >>> acc = mkacc(100)
 >>> acc(3)
 103
 >>> acc(5)
 108

Same with defining Bunch (or even instanciating via a throwaway). Of course I'm not
suggesting these as a models of spelling clarity, but it is sometimes interesting to see
alternate spellings of near-if-not-identical functionality.

 >>> Bunch = type('Bunch',(),{'__init__':lambda self,**kw:self.__dict__.update(kw)})
 >>> bunch=Bunch(value='initial_value')
 >>> bunch.value
 'initial_value'


>but I think the "purer" (more extreme) versions are
>interesting "tipizations" for the languages, anyway.
>
Oh goody, a new word (for me ;-). Would you define "tipization"?

Regards,
Bengt Richter




More information about the Python-list mailing list