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