On 2021-06-22 3:43 p.m., Brendan Barnwell wrote:
> On 2021-06-22 05:14, Chris Angelico wrote:
>> Fair point. However, I've worked with a good number of languages that
>> have some notion of object methods, and generally, an object has or
>> doesn't have a method based on what the object*is*, not on who's
>> asking.
>
>     I agree, and this is the aspect of the proposal that most confuses
> me. I still can't understand concretely what is being proposed,
> though, so I'm not sure I even understand it.  Can someone clarify? 
> Suppose I have this
>
> *****
> ### file1.py
> @extend(list)
> def len2(self):
>     return len(self)**2
>
> ### file2.py
> # or whatever I do to say "I want to use extensions to list defined in
> file1"
> from file1 extend list
>
> def coolness(some_list):
>     return some_list.len2() + 1
>
> my_list = [1, 2, 3]
> print("My list len2:", my_list.len2())
> print("My list coolness:", coolness(my_list))
>
> ### file3.py
> import file2
>
> other_list = [1, 2, 3, 4]
> print("Other list len2:", other_list.len2())
> print("other list coolness:", file2.coolness(other_list))
> print("My list len2 from outside:", file2.my_list.len2())
> print("My list coolness from outside:", file2.coolness(file2.my_list))
> *****
>
>     What exactly is supposed to happen here if I run file3?  file2
> declares use of file1's extensions.  file2 does not.  But file3 uses a
> function in file2 that makes use of such extensions.  Who sees the
> extension?
>

NameError, value, NameError, value, respectively.

>     The list object my_list in file2 is the same object accessed as
> file2.my_list in file3.  Likewise coolness and file2.coolness.  It is
> going to be super confusing if calling the same function object with
> the same list object argument gives different results depending on
> which file you're in.  Likewise it's going to be confusing if the same
> list object sometimes has a .len2 method and sometimes doesn't.

It isn't the list object that has the extension method.

>
>     But if it doesn't work that way, then it would seem to mean either
> every module sees the extensions (even if they didn't opt in), or else
> my_list in file2 is not the same object as file2.my_list in file3. 
> And that would be even worse.  (In this example it may seem okay
> because you can ask why I would call len2 from file3 if I didn't want
> to use it. But what if the extension is an override of an existing
> method?  Is that not allowed?)
>
>     In addition, if there is a difference between my_list and
> other_list, then that apparently means that the syntax for lists now
> does something different in the two files.  This is maybe the most
> reasonable approach, since it's at least remotely reminiscent of a
> __future__ import, which changes syntactic behavior.  But what exactly
> is the difference between the two objects here?  Are both objects
> lists?  If they are, then how can they have different methods?  If
> they're not, then what are they?
>
>     Most __future__ imports don't work like this.  Maybe the closest
> thing is the generator_stop one, but at least that places a flag on
> the code object to indicate the difference.  Would "extended lists"
> have some kind of magic attribute indicating which extensions they're
> using?  That may have been marginally acceptable in the case of PEP
> 479, which was essentially a bugfix, and set the attribute on code
> objects which are an obscure internal data structure.  But allowing
> this kind of thing for "user-facing" objects like lists would create a
> profusion of different list objects with different behavior depending
> on some combination of attributes indicating "what extends me" --- or,
> even worse, create different behavior without any such overt
> indication of which extensions are in use for a given object.
>
>     The idea that the file in which code is written would somehow
> determine this type of runtime behavior seems to me to break my
> assumption that by knowing an object's identity I should have all the
> information I need to know about how to use it.  Some of the posts
> earlier in this thread seem to suggest that somehow the module where
> something was defined (something --- not sure what --- maybe the
> object with the extended method?  maybe the extended method itself?)
> would somehow get a hook to override attribute access on some objects
> (again, not sure which objects).
>
>     That to me is the exact opposite of encapsulation.  Encapsulation
> means the object itself contains all its behavior.  If there is some
> getattr-like hook in some other module somewhere that is lying in wait
> to override attribute access on a given object "only sometimes" then
> that's not encapsulation at all.  It's almost as bad as the infamous
> COME FROM statement!
>
>     Existing mechanisms like __getattribute__ are not parallel at all.
> When you know an object's identity, you know its MRO, which tells you
> all you need to know about what __getattribute__ calls might happen.
> You don't need to know anything about where the object "came from" or
> what file you're using it in.  But it seems with this proposal you
> would need to know, and that's kind of creepy to me.
>

Think about it like this, extension methods give you the ability to make
imported functions that look like this:

foo(bar, baz)

look like this instead:

bar.foo(baz)

That's all there is to them. They're just a lie to change how you
read/write the code. Some languages have an whole operator that has a
similar function, where something like bar->foo(baz) is sugar for
foo(bar, baz). The OP doesn't specify any particular mechanism for
extension methods, so e.g. making the dot operator be implemented by a
local function in the module, which delegates to the current attribute
lookup mechanism by default, would be perfectly acceptable. It's like
deprecating the existing dot operator and introducing a completely
different one that has nothing to do with attribute lookup!
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/VWGTUNYXDQ3CYYRNL7Z3UCSVDM6IDAMJ/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to