Syntax for one-line "nonymous" functions in "declaration style"
Alexey Muranov
alexey.muranov at gmail.com
Tue Apr 2 12:54:17 EDT 2019
On mar., Apr 2, 2019 at 6:00 PM, python-list-request at python.org wrote:
> 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.
Sorry, i do not feel like continuing this discussion for much longer,
or we need to concentrate on some specific statement on which we
disagree.
I clarified what i meant by an assignment, and i believe it to be a
usual meaning.
1. `def` is not an assignment, there is no left-hand side or
right-hand side. I was talking about the normal assignment by which
anyone can bind any value to any variable.
2. If i execute an assignment statement
foo = ...
and instead of evaluating the right-hand side and assigning the
value to "foo" variable Python does something else, i consider the
assignment operation (<var> = <expr>) broken, as it does not do
assignment (and only assignment). I've said more on this in previous
messages.
3. About the examples with `372 is 372`, Python gives no garanties
about the id's of numerical objects, and about id's of many other types
of immutable objects. The user is not supposed to rely on their
equality or inequality.
Anytime Python's interpreter encounter two immutable objects that
it finds identical, it is free to allocate a single object for both,
this does not change the guaranteed semantics of the program.
The '__name__' attribute of an object, as well as most (or all)
other attributes, is a part of object's value/contents, no analogies
with the id's.
I am sorry, but except maybe for one or two more very specific
questions, I am probably not going to continue.
Alexey.
More information about the Python-list
mailing list