expression form of one-to-many dict?
Bengt Richter
bokr at oz.net
Sun Dec 19 23:25:32 EST 2004
On Sun, 19 Dec 2004 21:29:27 +0100, "Fredrik Lundh" <fredrik at pythonware.com> wrote:
>Mike Meyer wrote:
>
>> Personally, I'd love a language feature that let you create a function
>> that didn't evaluate arguments until they were actually used - lazy
>> evaluation. That lets you write the C ?: operator as a function, for
>> a start.
>>
>> Hmmm. No, iterators can't be used to fake it. Oh well.
>
>if you can get some collaboration from the function itself, you can fake
>anything:
>
>def foo_default():
> while 1:
> print "MAKE A FOO"
> yield "foo"
>foo_default = foo_default()
>
>class mydict(dict):
> def setdefault(self, key, default=None):
> try:
> return self[key]
> except KeyError:
> if hasattr(default, "next"):
> default = default.next()
> self[key] = default
> return default
>
>d = mydict()
>d["spam"] = "bacon"
>
>print d.setdefault("spam", foo_default)
>print d.setdefault("egg", foo_default)
>
Just the same, it would be interesting to be able to create special-form style functions easily
by designating arbitrary arguments for deferred evaluation, to which eval could safely be applied
(or maybe a restricted unquote_arg function for better safety).
E.g., double back-tick is a syntax error now, so you could write
def ternary(c, ``t, ``f):
if c: return eval(t)
else: return eval(f)
(Of course, it's also interesting to speculate about what kind of first class object
would be returned by
def foo(``x): return x
and whether ``x should be a generally valid expression, not just specialized for arg list setup ;-)
(note that ``x is not quite the same as automated lambda:x -- nor lambda x=x:x -- wrapping,
since the latter would evaluate x for the lambda and the former accesses the last value set
in the closure cell:
>>> def foo():
... v = 'a'
... x = lambda:v
... v = 'b'
... y = lambda:v
... return x,y
...
>>> [foo()[i]() for i in (0,1)]
['b', 'b']
Anyway, with a suitable `` quoting operator your setdefault could be
def setdefault(self, key, ``default=None):
...
default = eval(default)
... etc
BTW, note that
def foo(``default=expr): ...
and
def foo(``default=``expr): ...
could mean different things, depending on preferred semantics and ``expr as
a generally valid expression.
Regards,
Bengt Richter
More information about the Python-list
mailing list