Syntax for one-line "nonymous" functions in "declaration style"
Ian Kelly
ian.g.kelly at gmail.com
Tue Apr 2 11:27:41 EDT 2019
On Tue, Apr 2, 2019 at 1:43 AM Alexey Muranov <alexey.muranov at gmail.com>
wrote:
>
> > On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov <alexey.muranov at
> > gmail.com>
> > wrote:
> > >
> > > I only see a superficial analogy with `super()`, but perhaps it is
> > > because you did not give much details of you suggestion.
> >
> > No, it's because the analogy was not meant to be anything more than
> > superficial. Both are constructs of syntactic magic that aid
> > readability at
> > a high level but potentially obscure the details of execution (in
> > relatively unimportant ways) when examined at a low level.
>
> Since i understand that the "super() magic" is just evaluation in a
> predefined environment, it does not look so very magic.
It's the reason why this doesn't work:
superduper = super
class A:
def f(self):
return 42
class B(A):
def f(self):
return superduper().f()
>>> B().f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
RuntimeError: super(): __class__ cell not found
But this does:
class C(A):
def f(self):
return superduper().f()
not super
>>> C().f()
42
I don't know, seems magical to me.
> Moreover, without this "magic", `super()` would have just produced an
> error. So this magic did not change behaviour of something that worked
> before, it made "magically" work something that did not work before
> (but i am still not excited about it).
I'm curious how you feel about this example then (from the CPython 3.7.2
REPL; results from different Python implementations or from scripts that
comprise a single compilation unit may vary)?
>>> 372 is 372
True
>>> b = 372; b is 372
True
>>> b = 372
>>> b is 372
False
> > Maybe it was from my talk of implementing this by replacing the
> > assignment
> > with an equivalent def statement in the AST. Bear in mind that the def
> > statement is already just a particular kind of assignment: it creates
> > a
> > function and assigns it to a name. The only difference between the
> > original
> > assignment and the def statement that replaces it is in the __name__
> > attribute of the function object that gets created. The proposal just
> > makes
> > the direct lambda assignment and the def "assignment" to be fully
> > equivalent.
>
> `def` is not an assignment, it is more than that.
def is an assignment where the target is constrained to a single variable
and the expression is constrained to a newly created function object
(optionally "decorated" first with one or more composed function calls).
The only ways in which:
@decorate
def foo(blah):
return stuff
is more than:
foo = decorate(lambda blah: stuff)
are: 1) the former syntactically allows statements inside the function
body, not just expressions; 2) the former syntactically allows annotations
on the function; and 3) the former syntactically sets a function name and
the latter doesn't. In other words, all of the differences ultimately boil
down to syntax.
More information about the Python-list
mailing list