Alan, Your thoughts were helpful and gave me a hint.
Just an idea. What if you sub-classed an object type like list with a name like chainable_list? For most things it would be left alone. But if you isolated specific named methods like sort() and reverse() you could over-ride them with the same name or a new name. If you override the function, you need to call list.sort() with whatever arguments you had passed and then return this. If you choose a new name, call this.sort() and then return this. I tried it and it seems to work fine when I use a new name: """Module to create a version of list that is more chainable""" class chainable_list(list): """Same as list but sort() can now be chained""" def chainsort(this, *args, **kwargs): this.sort(*args, **kwargs) return this Here it is on a list of ints: >>> testink = chainable_list([3,5,1,7]) >>> testink [3, 5, 1, 7] >>> testink.chainsort() [1, 3, 5, 7] >>> testink.chainsort(reverse=True) [7, 5, 3, 1] Here it is on a list of strings that sort differently unless coerced back into an int to show keyword arguments are passed: >>> testink = chainable_list(["3","15","1","7"]) >>> testink.chainsort() ['1', '15', '3', '7'] >>> testink.chainsort(reverse=True) ['7', '3', '15', '1'] >>> testink.chainsort(key=int,reverse=True) ['15', '7', '3', '1'] I then tested the second method using the same name but asking the original list sort to do things: """Module to create a version of list that is more chainable""" class chainable_list(list): """Same as list but sort() can now be chained""" def sort(this, *args, **kwargs): list.sort(this, *args, **kwargs) return this >>> testink = chainable_list(["3","15","1","7"]) >>> testink.sort() ['1', '15', '3', '7'] >>> testink.sort().sort(reverse=true) Traceback (most recent call last): File "<pyshell#18>", line 1, in <module> testink.sort().sort(reverse=true) NameError: name 'true' is not defined >>> testink.sort().sort(reverse=True) ['7', '3', '15', '1'] >>> testink.sort().sort(reverse=True).sort(key=int) ['1', '3', '7', '15'] Again, it works fine. So if someone did something similar to many of the methods that now return None, you could use the new class when needed. This seems too simple so it must have been done. Obviously not in the standard distribution but perhaps elsewhere. And, no, I do not expect a method like pop() to suddenly return the list with a member dropped but it would be nice to fix some like this one: >>> testink.remove('7') >>> testink ['1', '3', '15'] Meanwhile, I hear Beethoven is decomp..., well never mind! It was probably Liszt! -----Original Message----- From: Tutor <tutor-bounces+avigross=verizon....@python.org> On Behalf Of Alan Gauld via Tutor Sent: Tuesday, December 25, 2018 8:06 PM To: tutor@python.org Subject: Re: [Tutor] decomposing a problem On 26/12/2018 00:00, Avi Gross wrote: > great. Many things in python can be made to fit and some need work. > Dumb example is that sorting something internally returns None and not > the object itself. This is one of my few complaints about Python. In Smalltalk the default return value from any method is self. In Python it is None. self allows chaining of methods, None does not. Introducing features like reversed() and sorted() partially addresses the issue but leads to inconsistent and ugly syntax. Smalltalk uses this technique so much it has its own code layout idiom (Pythonised as follows): object .method1() .method2() .method3() .... .lastone() We can do this with some methods but not all. And of course methods that return a different type of value require careful handling (eg. an index() call in the middle of a set of list operations means the subsequent methods are being called on an int not a list - which if handled correctly can be confusing and if not handled correctly produces errors! (The idiomatic way says don't chain with methods not returning self!) In practice I (and the Smalltalk community) don't find that an issue in real world usage, but it may have been why Guido chose not to do it that way. But I still curse the decision every time I hit it! But as I said, it's about the only thing in Python I dislike... a small price to pay. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor