[Python-ideas] Another way to avoid clumsy lambdas, while adding new functionality

David Mertz mertz at gnosis.cx
Wed Mar 5 07:54:30 CET 2014


On Tue, Mar 4, 2014 at 7:49 PM, Cameron Simpson <cs at zip.com.au> wrote:

> > >   b = eval(a) * 6
> > > This makes me unhappy. Eval parses a string and runs it, currently.
> > > I would _want_ to read that as "compute a, then eval() the result".
> >
> > > b = a() * 6
> >
> > I don't think I would want a thunk to be *exactly* a callable. That feels
> > wrong to me.
>
> Can you be more precise? It seems like exactly what's going on, semanticly.
> Except that there's no notion of parameters.
>

As *I* am thinking of it, a "thunk" is really just like a C macro.  Not
even really like a Lisp macro.  So it's not like a function in that it
doesn't define a scope, doesn't have a call stack, etc.  It's just "pretend
I typed these other literal symbols here." Maybe I should stop calling the
idea a thunk, and just call it a macro.

However, I'm pulled in several directions here.  On the one hand, if it
really is essentially the same thing as a code object, I'm not convinced we
actually need syntax for it.  That is, what's really the point of having

  a = $(expr)  # or `expr`, or `(expr), or c"expr"

If it's simply a slightly shorter way of spelling:

  a = compile(expr, "<string>", "eval")

One thing about a code object is that it is NOT callable.  Which is to say,
that it's not usable as a callback.  If this other thing (thunk, macro,
whatever) is callable, it's usable as a callback; albeit a callback with
zero arguments, which again is of limited purpose, and not really that much
shorter than lambda, e.g.:

  b = Button(text="click me", command=lambda: print("Clicked!"))

Under the callable-thunk spelling, we might have:

  b = Button(text="click me", command=$(print("Clicked!")))

All of this is moving me towards the -0, or even -0.5 on my own idea (even
though I like my spelling in principle, but I'm having trouble seeing why I
actually need it).

  a.eval()
> Don't make a new public function, give thunks a method.
>

Sure, that's a nice enough spelling, but what do we really get over code
objects there?

Actually, here's some short and trivial code in existing Python that seems
to already get *everything* we've discussed in this thread:

>>> class Thunk(object):
...     def __init__(self, s):
...         self.code = compile(s, "<thunk>", "eval")
...     def __call__(self, **kws):
...         return eval(self.code, globals(), kws)
...     eval = __call__
...
>>> a = Thunk("foo + bar")
>>> for foo, bar in enumerate(range(5,8)):
...     a()
...
5
7
9
>>> for foo, bar in enumerate(range(5,8)):
...     a.eval()
...
5
7
9
>>> a(foo=10, bar=20)
30

Other than using the '$' which I'm mixed about anyway, and saving two quote
symbols, my Thunk class seems to be exactly what I had proposed (with
Cameron's variations).

-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140304/8e680b50/attachment.html>


More information about the Python-ideas mailing list