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

Cameron Simpson cs at zip.com.au
Wed Mar 5 04:49:45 CET 2014


On 04Mar2014 18:36, David Mertz <mertz at gnosis.cx> wrote:
> On Tue, Mar 4, 2014 at 5:46 PM, Cameron Simpson <cs at zip.com.au> wrote:
> > >   foo = 1
> > >   a = $(foo + 1)
> > Definitely nicer. Still irrationally uncomfortable about the "$" though.
> > A thought, though it could break existing code (and nested tuples, alas):
> >
> >     a = (( foo + 1 ))
> 
> That looks like unresolvable ambiguity to me.

Me too.

> I confess that I am more
> comfortable with '$(...)' because I'm one of those folks who actually likes
> bash, and uses that spelling often over there (where the meaning isn't the
> *same* as this, but is enough similar for the meaning to carry over)

I write a lot of shell scripts too.

> > Still, what does this mean?
> >     a = 3 + (( foo + 1 ))
> > I think that would need to be a syntax error, because I can't see it being
> > anything except nonsense otherwise.
> 
> In my example I made it a TypeError on the grounds that a thunk and and int
> aren't things that can be added together.  That makes more sense to me than
> a SyntaxError, since a thunk is a perfectly good expression (or would be if
> the feature is added).
> 
> Besides, you really need to allow thunks in expressions, since sometimes
> they make sense as values to operate on, e.g. (as I wrote before):
> 
>   print(foo, 'foo', $(foo))  # Using my bash-like syntax
>   # 1 foo <thunk object ...>
> 
> You could also, for example, have a type of object that knew how to operate
> on a thunk with operators:
> 
>   class Thunker(object):
>       def __radd__(self, other):
>           if isinstance(other, thunk):
>               ... return something sensible ...
> 
>   thunker = Thunker()
>   a = thunker + $(foo + bar)

Hmm, yes. Ok. We should get TypeErrors for free except where some
operator has been designed.

> >   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.

> But I can see that overloading the meaning of eval() to
> operate on either a string or a thunk might feel odd. *Except* that eval()
> is *already* overloaded in a similar manner:
> 
>   >>> exp = compile("1+2", "<string>", "eval")
>   >>> exp, eval(exp)
>   (<code object <module> at 0x100730ae0, file "<string>", line 1>, 3)

Hmm. The lack of params makes eval a better match then.

> However, what if it was spelled differently from eval(), e.g.:
> 
>   b = unthunk(a) * 6
> 
> OK, I don't actually like that name, but you see what I mean that other
> names are perfectly possible.

How about:

  a.eval()

Don't make a new public function, give thunks a method.

Are we still intending thunks to be effectively a calling-scope
closure? That seems subject to being fragile: you can define a thunk
far from where it is called/evaled and therefore keeping it in sync
with the user's scope is less solid.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au>

Steve is going for the pink ball - and for those of you who are
watching in black and white, the pink is next to the green.
- Snooker commentator 'Whispering' Ted Lowe


More information about the Python-ideas mailing list