[Python-ideas] Fwd: YAML (yet-another-multiline-lambda)

Antony Lee anntzer.lee at gmail.com
Fri Oct 25 08:28:21 CEST 2013


Sorry Stephen, forgot to reply-to-all the first time.
Antony

2013/10/24 Stephen J. Turnbull <stephen at xemacs.org>

> Antony Lee <anntzer.lee at gmail.com> writes:
> >>>>> 2013/10/24 Stephen J. Turnbull <stephen at xemacs.org>
>
>  > I think you've misunderstood the aim of my proposal.
>
> No, I misunderstood the language in your most recent post, not to
> mention the consistent mis-specification of the whole idea in *every*
> subject line.  Python doesn't currently have a notion of "binding"
> lambdas to objects, and you here don't specify how a lambda (object)
> is being "bound" to what (other kind of) object.  Python does have a
> notion of binding names to objects.  Confusion is natural.
>
> If you're *primarily* talking about defining functions in the "right
> place" in general, what's wrong with using the well-defined Python
> terms for those objects?
>

To me, in the context of Python, the words lambda and function have the
same meaning at the object representation level (an object of type
types.FunctionType (== types.LambdaType)), the only difference coming at
the syntactic level: a lambda is defined in an expression, a function is
defined in a statement.  Thus the name "multi-line lambda" (and it made a
nice acronym in the title, sure).  But if you prefer, you can replace
"multi-line lambda" by "function defined by multi-line expression"
everywhere.

>
>  > Specifically, I was asking his to clarify the relevance of such an
>  > issue as a locally defined lambda (etc.) already captures "self"
>  > without the need for a call to a JS-like bind (which is effectively
>  > spelled __get__ in Python).
>
> Sure.  So there is no "need" in the first place.  I don't understand
> what you're talking about.  IMO Nick's use case, described next, is
> compelling.  Why not just say "this syntax does the trick for that use
> case"?  Are you saying anything else?  That's what I can't figure out.
>

I am trying to answer the issue Andrew raised:

> I don't think this idea will fit well with Python's OO.
>
> Partly this is based on JS experience, where you have to write .bind(this)
> all over the place because your callback--or, worse, some callback later in
> the chain--needs access to this.
>

Like it or not, to discuss this argument, I need to discuss the need to
write ".bind(this)", or, in Python-speak, create bound(!) methods out of
"functions defined by multi-line expressions".  In fact, if I understood
you well, you seem to agree that it doesn't actually apply to this proposal.

>
>  > Just look at the other currently active thread on context manager
>  > semantics, where Nick Coghlan said
>
>  >> it *also* means that we *don't* currently have a clean syntax for
>  >> single use callbacks.
>
>  > Another example is when you want to provide a dictionary of
>  > callbacks (e.g.  to be triggered by various command line options),
>  > say at global scope, without putting the callbacks themselves in
>  > that scope).
>
> Eh, "there you go again."  That's the same example, isn't it?  It's a
> good one and stands repeating, but it's not different.  In both cases
> you have a callback and a desire to put the def in an appropriate
> "place" (namespace, and often lexical position in the source).  The
> dictionary of callbacks idiom is familiar (at least to those of us to
> have the misfortune to program with Xt), and I certainly understand
> the desire to define callbacks in an appropriate scope.  Again, do you
> have *more* to say than "I think my syntax does this nicely,
> concisely, and precisely"?
>

If I put my function definition in an expression, the point is of course to
use it "in the appropriate place", so this wording more or less covers
every use I can think of.  But perhaps you can consider the following use
case as "different enough".  If we had this feature, we could probably have
done without the "with" statement:

with open(name) as f:
    ...
===>
opening(name, (def func(f): ...)) # define a new "opening" function
or
open(name, do_and_close=(def func(f): ...)) # add a kwarg to "open"

with lock:
    ...
===>
lock.acquiring(def func(): ...) # define a new "acquiring" method

While I certainly consider the "with" statement to be extremely useful, and
nicer for such use cases, I simply doubt that new syntax would have been
added at all if this construct was available.  Of course one may consider
this as a non-argument as we have the "with" statement now and it's not
going away (which is a good thing).


> If you have other compelling use cases, that would be useful.  But I
> think the "defining callbacks in the right place" use case would be
> enough to get this proposal in Python 3.5 (if it stands up to issues
> like the LL constraint on the languages, and the objection to
> YAAP[1]).  Mixing this up with "lambda" and "binding" is unhelpful
> AFAICS.
>

I'm certainly no expert on parsing but this proposal was certainly designed
to be (relatively) simple to parse: instead of having just having one stack
of indentation levels, keep a stack of such stacks.  When encountering a
"def" token, check that the last token was a parenthesis (or perhaps
brackets and curly braces too... although I don't think using lambdas as
dict keys in a good idea at all :-)), and if so, start parsing the inline
def as if it was at toplevel, using a new stack of indent levels.

As for the abuse of parentheses [1], note that in the most common case (I
would guess) of passing a single inline function (or whatever you want to
call it) to another function, the function call itself already provides
these parentheses so there is no need of adding another level of
parentheses.

>
>  > I don't think abusing the class statement is particularly elegant
>  > either (and good luck if you want to preserve order... what, I have
>  > to provide a metaclass that overrides __prepare__ for doing this?),
>
> I doubt you need to use a metaclass (storing the callbacks in an
> OrderedDict and then defining an appropriate __index__ can probably be
> done with a decorator or two), but the alternatives are hardly
> prettier I guess.
>
>
> Footnotes:
> [1]  Yet Another Abuse of Parentheses, also spelled "YAAPMILL"
> ("... Making It Like LISP").
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131024/a2c06ac1/attachment.html>


More information about the Python-ideas mailing list