On Tue, Mar 4, 2014 at 7:49 PM, Cameron Simpson <cs@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.