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