On Sat, Nov 27, 2021 at 08:50:37PM +0900, Stephen J. Turnbull wrote:

> The thing is, the reason such a module is needed at all is that Guido
> decided ages ago that mutating methods should return None, and in
> particular they don't return self.
> 
> I'm not sure why he did that, you'd have to ask him,

Or read the FAQs :-)

https://docs.python.org/3/faq/design.html#why-doesn-t-list-sort-return-the-sorted-list

> but we respect
> his intuition enough that to get it in, it would help to have answers
> to some of the following questions in advance:

And yet it is indisputable that chained methods are useful even for 
methods which modify the object they work on. Look at pandas:

https://towardsdatascience.com/the-unreasonable-effectiveness-of-method-chaining-in-pandas-15c2109e3c69?gi=b0f6424c99d1

If you format your code nicely, it even looks like a sequence of 
procedure calls:

https://tomaugspurger.github.io/method-chaining

so you have a choice whether to simulate Pascal or Java while still 
being 100% Pythonic :-)


https://duckduckgo.com/?q=pandas+fluent+interface


> 1.  Is dataflow/fluent programming distinguishable from whatever it
>     was that Guido didn't like about method chaining idioms?  If so,
>     how?

We already use method chaining on immutable strings. Its only when it 
comes to mutable objects that is it possible to confuse the two 
situations:

- the method modifies the object in place, and returns self;

- versus the method returns a new, modified, copy of the object.

Pandas uses the first style (I think; corrections welcome). Strings use 
the second, because they have no choice.


> 2.  Is the method chaining syntax preferable to an alternative
>     operator?

What do you mean, a different operator? Are you suggesting we should 
have two operators for method lookups?

That might even be workable, if we had a rule:

    obj.method

follows the regular descriptor protocol when doing attribute lookups, 
and (let's say...):

    obj::method

wraps the method object with a proxy, so that:

    proxy(args)

calls the original method, and then returns obj instead of whatever the 
method returned.



> 3.  Is there an obvious choice for the implementation?  Specifically,
>     there are at least three possibilities:
>     a.  Restrict it to mutable sequences, and do the transformations
>         in place.
>     b.  Construct nested iterators and listify the result only if
>         desired.
>     c.  Both.

a. is obviously impossible, since strings already support method 
chaining, as do any other method that returns something other than 
None. And even those that return None can chain methods, if you are 
careful about which methods you call!

    >>> mylist = []
    >>> mylist.sort().__bool__().as_integer_ratio()
    (0, 1)

So its not that we can't use chained methods on lists. Its just that we 
can't use them to do anything *useful*.

I don't understand your option b. What do nested iterators have to do 
with chaining methods? You can chain methods on any object or objects so 
long as the methods return something useful with methods that you want 
to call. They're not restricted to iterators.

Since most iterators don't have many methods, it's not clear to me that 
iterators are even a little bit relevant. Maybe I have missed something.

(It's been a looooong thread and I admit I have skimmed a few posts.)


-- 
Steve
_______________________________________________
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/CLPCGRBFH7SL4MUMMZCEI3WDDEQFVNKU/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to