On Tue, Mar 4, 2014 at 7:49 PM, Cameron Simpson firstname.lastname@example.org 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).
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:
... 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
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).