Re: LangWart: Method congestion from mutate multiplicty
On Monday, February 11, 2013 11:28:57 PM UTC-6, zipher wrote: > [...] > Yeah, this is where one has to consider the idea of a unified data > model (a sort of OOPv2). Right now, it's all confused because people > are using their own internal, subconscious ideas of data. Indeed! The current paradigms lack concrete structures which will prevent these ever-long bickering over minutiae. Our current paradigms are actually self-defeating because they allow too much "interpretation" of what is correct, and what is incorrect. It's like the early pioneer days, cowboys everywhere. We need Wyatt Earp! > There are > natural ways of working with data that ***actually map onto the world > we all share*** and there are other ways which are purely abstract and > not-pragmatic however "pure". (Apart from this, there is the > ultra-concrete data model, like C, which only maps onto the machine > architecture). This is where pretty much every computer language is > today. > > What I'm suggesting I think is somewhat novel. The first version of > OOP was too concrete in the sense that it was actually trying to make > real-world objects in the machine (class Chevy(Car):). This is > ridiculous. There needs to be a refactor of the OOP paradigm. In > practice OOP never was used to represent real-world objects. It came > to model virtual world objects, a very different world with different > relationships. It became the evolution of the data type itself. > The > unified object model needs to do for OOP what arithmetic did for > number: defined a very basic and general set of operations on the > concept of "quantificiation". But here were trying to do that not for > quantification but for structures. Most people in the this group would probably consider this to be a fantastical idea. But aren't ALL great ideas fantastical? >From as long as man has existed he has wanted to fly like a bird -- whether >his wish was based on logistical expeditiously or simply a primitive >egotistical rebelliousness to overcome the limits of his own physiology. It's no surprise that the initial attempts were naive at best and resulted in total embarrassment. When he attempted to borrow some "flight attributes" of his feathered friends by "taring-and-feathering" himself, he did /look/ like a bird, however, when he executed the "perfect 10" swan-dive from his second story cave dwelling, only to bounce his face off the granite welcome mat, he was reminded by his audience of the one bird-like feature he already had... his brain! You see, early man wanted to fly, and knew /somehow/ it was possible, however, his folly was to attempt flight by borrowing attributes of the bird /directly/. In reality, even if could borrow /every/ flight specific attribute of the bird: light weight frame from hollow bones, large lung capacity, aerodynamic body shape and wing structure, features, etc. He would then be /himself/ a bird, and NOT a /human/ flying. Besides, a human changing into a bird is impossible... or is it?[3] [Warning: Slight tangent curve ahead!] I think a lot of the failure of achieving flight "hinged" around the superfluous complexity of articulated wings-- of which is something that we have trouble replicating even today with our advancements in mechanical, hydraulic, and computing technology. But articulating wings are another fine example of how "intelligent design" will always beat the pants off "evolution". The simple technology of combining "fixed wings" with "brute force propulsion" can overcome the complex design of articulating wings and gain maintainability in the process. It seems the bird should have developed a squid-like air propulsion emanating from his anus instead of articulating wings and large breast muscles; But i digress! RR: "A billion years worth of "dice rolling" is no replacement one human imagination! Evolution, you have created your replacement; prepare for your deprecation!" [Back to the beaten path!] What early man failed to realize is that he should create a model of the bird, and then hitch a ride on the model! This is an example if utilizing an /indirect/ approach to solving the problem of "human flight". However, it is still possible to solve the problem directly. Although this direct approach involves man manipulating atomic structures (using nano-technology) and then transforming cognitive state from one entity into another entity (or in-place if we're really good![1]); AKA: "Shapeshifting" But some rules require too much time to hack, so while the brute algorthim is chewing away for the next 100 years, we need to follow these steps: 0. Start the brute force algorithm (study nano-tech, computing) 1. in the short term use the indirect approach (aeroplane) 2. until the direct approach becomes attainable (shapeshifting) > My suggestion is to create the "fractal graph" data type to end (and > represent) all data types. (Keep all the special, high-speed matrix
Re: LangWart: Method congestion from mutate multiplicty
On Mon, Feb 11, 2013 at 8:52 PM, Jean-Michel Pichavant wrote: > >> Yeah, this is, pardon the french, just batshit crazy. > > huh ? :) You're French, ergo you are pardoned. Makes good sense to me! :) ChrisA Cheshire was right, we're all mad here... -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
> Yeah, this is, pardon the french, just batshit crazy. huh ? :) JM -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Mon, Feb 11, 2013 at 8:55 PM, Rick Johnson wrote: > On Monday, February 11, 2013 7:27:30 AM UTC-6, Chris Angelico wrote: > >> So... >> flatten([None, 23, [1, 2, 3], (2, 3), ["spam", "ham"]]) >> >> would return >> >> [None, 23, 1, 2, 3, (2, 3), "spam", "ham"] >> >> I think that's even more unexpected. > > Why? Are you over-analyzing? Show me a result that /does/ make you happy. > > Do you remember when i was talking about how i attempt to intuit interfaces > before reading any docs? Well i have news for you Chris, what you are doing > is NOT "intuiting" how flatten will work, what you are doing is "projecting" > how flatten will work; these are two completely different concepts Chris. > > You can't procrastinate over this method forever because NEWSFLASH you will > /never/ find a perfect flatten algorithm that will please /everyone/, so just > pick the most logical and consistent, and MOVE ON! Yeah, this is where one has to consider the idea of a unified data model (a sort of OOPv2). Right now, it's all confused because people are using their own internal, subconscious ideas of data. There are natural ways of working with data that ***actually map onto the world we all share*** and there are other ways which are purely abstract and not-pragmatic however "pure". (Apart from this, there is the ultra-concrete data model, like C, which only maps onto the machine architecture). This is where pretty much every computer language is today. What I'm suggesting I think is somewhat novel. The first version of OOP was too concrete in the sense that it was actually trying to make real-world objects in the machine (class Chevy(Car):). This is ridiculous. There needs to be a refactor of the OOP paradigm. In practice OOP never was used to represent real-world objects. It came to model virtual world objects, a very different world with different relationships. It became the evolution of the data type itself. The unified object model needs to do for OOP what arithmetic did for number: defined a very basic and general set of operations on the concept of "quantificiation". But here were trying to do that not for quantification but for structures. My suggestion is to create the "fractal graph" data type to end (and represent) all data types. (Keep all the special, high-speed matrix ideas in SciPi/VPython.) But generally, re-arrange the data model around the fractal graph for efficiency and start watching the magic happen. markj pangaia.sf.net -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Monday, February 11, 2013 7:27:30 AM UTC-6, Chris Angelico wrote: > So... > flatten([None, 23, [1, 2, 3], (2, 3), ["spam", "ham"]]) > > would return > > [None, 23, 1, 2, 3, (2, 3), "spam", "ham"] > > I think that's even more unexpected. Why? Are you over-analyzing? Show me a result that /does/ make you happy. Do you remember when i was talking about how i attempt to intuit interfaces before reading any docs? Well i have news for you Chris, what you are doing is NOT "intuiting" how flatten will work, what you are doing is "projecting" how flatten will work; these are two completely different concepts Chris. The word "flatten" is too ambiguous to intuit the /exact/ "result". The only intuit-able attribute of flatten is that calling list.flatten() will result in a list that probably looks different than the current list. Intuition is your friend; not your own personal "clairvoyant side-kick"! To learn the interface you need to initially "intuit", but then you need to test. Run a few example sequences and see what results you get, compare those results to what you /expected/ to get. If it works the way you expect, move on to the next topic, if not, dig deeper. You can't procrastinate over this method forever because NEWSFLASH you will /never/ find a perfect flatten algorithm that will please /everyone/, so just pick the most logical and consistent, and MOVE ON! Infinite recursion anyone? while obj.repeat is True: obj.lather() obj.rinse() obj.repeat = True -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On 11.02.13 09:24, Chris Angelico wrote: Can I get a ringside seat at the debate between Rick and jmf on which kind of string theory was the wronger decision? I want to see it. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Mon, Feb 11, 2013 at 11:53 PM, Rick Johnson wrote: > Which primitive(s) should NOT have been expanded in your opinion? The "Point" > object? I agree, that's why MY implementation would call seq.flatten() on all > sub-sequences THEREBY allowing each subtype to define it's own flatten > behavior. Of course the default behavior of the SequenceBase#flatten would be > to flatten everything. > > However, ImmutableSequence Types would not flatten. In your example ["spam", > "ham"] would not be expanded to ['s', 'p', 'a', 'm', 'h', 'a', 'm']. psst: > strings and tuples are immutable! So... flatten([None, 23, [1, 2, 3], (2, 3), ["spam", "ham"]]) would return [None, 23, 1, 2, 3, (2, 3), "spam", "ham"] ? I think that's even more unexpected. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sunday, February 10, 2013 6:36:20 PM UTC-6, Steven D'Aprano wrote: > Rick Johnson wrote: > > On Sunday, February 10, 2013 5:29:54 AM UTC-6, Steven D'Aprano wrote: > >> Rick wrote: > > [...] > > Steven, the definition of flatten (as relates to sequences) is very, VERY > > simple: > > > > Return a new sequence that is the result of reducing > > a nested sequence of sequences into a single depth > > sequence. > > Very, VERY simple until you actually implement this function, and discover > that it does too much e.g. I would implement it as a method of sequence types, but i digress! > flatten([None, 23, [1, 2, 3], Point(x=2, y=3), ["spam", "ham"]]) > => [None, 23, 1, 2, 3, 2, 3, 's', 'p', 'a', 'm', 'h', 'a', 'm'] > > So people who have *actually programmed*, instead of just talking about > programming, have discovered that in practice you need to treat some > sequences as primitives that don't get expanded. Which primitive(s) should NOT have been expanded in your opinion? The "Point" object? I agree, that's why MY implementation would call seq.flatten() on all sub-sequences THEREBY allowing each subtype to define it's own flatten behavior. Of course the default behavior of the SequenceBase#flatten would be to flatten everything. However, ImmutableSequence Types would not flatten. In your example ["spam", "ham"] would not be expanded to ['s', 'p', 'a', 'm', 'h', 'a', 'm']. psst: strings and tuples are immutable! I'm not convinced that flattening immutable types is a good idea anyway, because heck, they're designed to be immutable! I suppose if we are not flattening "in-place" it really would not matter though. Creating a new immutable object that is the result of reordering an existing immutable object's values is not mutation. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Mon, 11 Feb 2013 18:24:05 +1100 Chris Angelico wrote: > Is that Unicode string theory or ASCII string theory? +1 QOTW :-) -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On 11/02/2013 07:24, Chris Angelico wrote: On Mon, Feb 11, 2013 at 6:19 PM, Mark Lawrence wrote: On 11/02/2013 02:05, alex23 wrote: I highly recommend not reading up on any modern physics as there'll be plenty there that just makes you angry. Spoil sport. Fancy not wanting rr's views on string theory :) Is that Unicode string theory or ASCII string theory? Can I get a ringside seat at the debate between Rick and jmf on which kind of string theory was the wronger decision? I guess that the black market would put the price beyond the pocket of the average Python programmer. ChrisA (And on whether "wronger" is permitted on this forum. Have at it,trolls!) And I'll allow wronger as you're the righter. -- Cheers. Mark Lawrence -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Mon, Feb 11, 2013 at 6:19 PM, Mark Lawrence wrote: > On 11/02/2013 02:05, alex23 wrote: >> >> >> I highly recommend not reading up on any >> modern physics as there'll be plenty there that just makes you angry. >> > > Spoil sport. Fancy not wanting rr's views on string theory :) Is that Unicode string theory or ASCII string theory? Can I get a ringside seat at the debate between Rick and jmf on which kind of string theory was the wronger decision? ChrisA (And on whether "wronger" is permitted on this forum. Have at it,trolls!) -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On 11/02/2013 02:05, alex23 wrote: I highly recommend not reading up on any modern physics as there'll be plenty there that just makes you angry. Spoil sport. Fancy not wanting rr's views on string theory :) -- Cheers. Mark Lawrence -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Feb 11, 9:59 am, Rick Johnson wrote: > We don't add features because of logic, or because of consistency, > or even because of good sense, we simply add them to appease the masses. When "logic" or "good sense" are writing programs, maybe then we'll listen more to what they want in a language. "Good sense" would dictate that someone actually read documentation when dealing with a new programming language. "Logic" would indicate that expecting things outside of your control to confirm with your intuition is a fool's game; I highly recommend not reading up on any modern physics as there'll be plenty there that just makes you angry. PS pragmatism is a perfectly valid philosophical approach too. Far more practical than more "pure" approaches, and something something foolish consistency blah blah small minds. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On 2013-02-11 00:36, Steven D'Aprano wrote: Rick Johnson wrote: On Sunday, February 10, 2013 5:29:54 AM UTC-6, Steven D'Aprano wrote: Rick wrote: And you have missed my point, which is that reversed(), and sorted(), were not added to the language on a whim, but because they were requested, over and over and over again. Well, well, this explains everything! We don't add features because of logic, or because of consistency, or even because of good sense, we simply add them to appease the masses. I remember a time when he was saying that the developers of the language were ignoring the silent majority. Now he's saying that we shouldn't simply add things to appease the masses. They were requested because people kept re-inventing them. They kept re-inventing them because they are useful functions that make good sense to have. Exactly. Practicality beats purity, and all that. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Feb 9, 2:51 pm, Chris Angelico wrote: >> Rick Johnson wrote: >> I really don't like to read docs when learning a language, >> especially a "so-called" high level language. I prefer to learn >> the language by interactive sessions and object introspection. Then, >> when i have exhausted all abilities to intuit the solution, i will >> roll my eyes, maybe blubber an expletive, and then reluctantly crack >> open a user manual. > > What Rick means: "I want to claim that I've learned a new language, > but I want it to work exactly like the imaginary language in my mind, > and if it doesn't, I'm going to complain about it, rather than, > yaknow, actually learn a new language." Yeah, this is, pardon the french, just batshit crazy. How does one _ever_ learn _anything_ new if they expect everything to conform with their pre-established intuitions? As can be seen by his posts, the outcome is one just _doesn't_ learn. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sunday, February 10, 2013 6:12:57 PM UTC-6, Tim Chase wrote: > What should you get if you flatten > > [[[1,2],[3,4]],[[5,6],[7,8]]] > > Should the result be > > [[1,2],[3,4],[5,6],[7,8]] > > or > > [1,2,3,4,5,6,7,8] > > I've needed both cases, depending on the situation. Well providing /every/ possible solution for /every/ possible answer to /every/ problem is not going to be possible unless you are willing to endure an endless amount of complexity. My opinion is that flatten should should call seq.flatten() on all sub-sequences. That seems like the only /reasonable/ resolution to allow. At least sub-types could define how they get flattened. However, that does not solve your problem: where you wish to flatten a sequence down to a prescribed sub-depth; in your example: flatten(subdepth=1). class Sequence(): """Hypothetical sequence object.""" def flatten(self, depth=INFINITY): # ... py> seq = [[[1,2],[3,4]],0,[[5,6],[7,8]]] py> seq.flatten() [1,2,3,4,0,5,6,7,8] py> seq.flatten(depth=1) [[1,2,3,4],0,[5,6,7,8]] py> seq.flatten(depth=2) [1,2,3,4,0,5,6,7,8] py> seq.flatten(depth=3) # Throw error or just quietly return flat list??? I don't feel very good about this API though. But i admit it might be beneficial to some folks. Should this example be the built-in behavior of Sequence#flatten, probably not. But hey, here at pydev we add features that appease the masses because we want to be loved. So folks, get your votes in! :-) -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sun, Feb 10, 2013 at 4:10 PM, Steven D'Aprano wrote: > Mark Janssen wrote: > >> A unified data model as I define it, specifies a canonical atomic unit >> (like the unit integer) and an abstract grouping construct in which >> these atomic units can be arranged. By themselves, these two can >> construct arbitrary levels of data structure complexity. Add the >> ability to apply names to these levels, and you have a complete data >> model for a happy programming environment. My work, to give you some >> context, involves the invention of a "fractal graph" which is where >> the name "unified object model" came from, because a fractal graph, I >> argue can represent every part of the physical world at every scale. > > How can you breathe *way* up there in space? > > http://www.joelonsoftware.com/articles/fog18.html Haha, point taken, but I actually have an application for such a high-level abstraction -- a 3-d web. A unified information model could take the internet to the next level (much like the Internet itself did to all the disparate communications networks before). Instead of the current hypertext and cumbersome attempt at coding semantic meaning in RDF tags, (re)present the internet content in a 3-d space and let the visual cortex, along with the crowd, make the relationships. (See pangaia.sourceforge.net) > P.S. not all phenomena are fractal. The elbow joint, for instance, is just a > hinge, and not made of smaller elbow joints made of tinier elbow joints > made of even tinier elbow joints made of ... Oh, no doubt about that. Perhaps instead of fractal graph, I should call it a recursive graph -- there must be a "base case" which ends the infinite regress. For the model I've been working on, that base case is the unit integer (or the machine word with only the least-significant-bit set to "1"). Cheers, mark > > > -- > Steven > > -- > http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson wrote: > On Sunday, February 10, 2013 7:30:00 AM UTC-6, Oscar Benjamin wrote: >> On 10 February 2013 04:53, Mark Janssen wrote: >> > [...] >> > I have to agree with Rick, I think requiring the user to explicitly >> > create a new object, which is already a good and widely-used practice, >> > should be the Only One Way to Do It. >> >> Why should I copy a potentially large data structure just to iterate >> over it in reverse order? > > That's a good question, and the answer is: "Only a fool would make a copy > of ANY data structure only to simply iterate over it; be it forwards or > backwards or sideways". Aren't you the fool who wants to remove reversed() and have people write: [quote] reversed = list(seq).reverse() Oh yes, you are the fool. And me the bigger fool for listening to you. Time for another six months in my killfile, methinks. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson wrote: > On Sunday, February 10, 2013 5:29:54 AM UTC-6, Steven D'Aprano wrote: >> Rick wrote: >> And you have missed my point, which is that reversed(), and sorted(), >> were not added to the language on a whim, but because they were >> requested, over and over and over again. > > Well, well, this explains everything! > > We don't add features because of logic, or because of consistency, or even > because of good sense, we simply add them to appease the masses. They were requested because people kept re-inventing them. They kept re-inventing them because they are useful functions that make good sense to have. >> "appended" is called list addition. >> >> newlist = oldlist + [item_to_append] > > But where is the consistency? Strings use + for concatenation. Tuples use + for concatenation. Lists use + for concatenation. Seems pretty consistent to me. Are you sure you've used Python before? > Yes the syntactic sugar of the "plus sign" is concise, however, the "+" > operator does not "pair" intuitively with the "append" method. Adding "ed" to a word does not pair intuitively with the method name. You have to learn it, which in the case of most English speakers you probably did between the ages of 2 and 6. Using + to represent concatenation is no less intuitive. > Even IF you > transformed the "+" operator into a named method like "add" (or call the > magic method "__add__") it still fails to mesh properly with "append", and > the two words utterly fail to intuitively establish an "in-place" versus > "copy-mutate" relationship. So what? >> > flatten, flattened >> >> flatten is another often requested, hard to implement correctly, >> function. The only reason that Python doesn't have a flatten is that >> nobody can agree on precisely what it should do. > > Steven, the definition of flatten (as relates to sequences) is very, VERY > simple: > > Return a new sequence that is the result of reducing > a nested sequence of sequences into a single depth > sequence. Very, VERY simple until you actually implement this function, and discover that it does too much e.g. flatten([None, 23, [1, 2, 3], Point(x=2, y=3), ["spam", "ham"]]) => [None, 23, 1, 2, 3, 2, 3, 's', 'p', 'a', 'm', 'h', 'a', 'm'] So people who have *actually programmed*, instead of just talking about programming, have discovered that in practice you need to treat some sequences as primitives that don't get expanded. >> Like map, filter, reduce, etc. flatten is not sensibly implemented as a >> mutator method, but as a function. > > Only because you, along with a few other high ranking members of this > community (including the BDFL himself!) have this /aversion/ to true OOP > paradigm. > > Can you provide an example of how flatten "as a method" is incorrect > versus flatten "as a function" is correct, or will this challenge be > silently swept under the rug as so many before? Simple efficiency. The most efficient, and sensible, way to flatten a list is to create a new list. Trying to flatten a list in place is a dumb idea -- it is O(n**2), or possibly even worse. Since only an idiot would write flatten as an in-place method, any mutator version of flatten would have to use a non-mutator version, then use slicing to over-write itself: def flatten(self): new_list = flatten(self) self[:] = new_list which is fine if you absolutely have to have an in-place version, but why bother? The caller can do it themselves: mylist = flatten(mylist) [snip] >> > map, mapped >> > filter, filtered >> > reduce, reduced >> >> Those are nonsense. None of those are in-place mutator methods. > > Well not in the current implementation of Python; but they could be if we > wanted them to be. Now you're smoking crack. How can *reduce* be an in-place mutator method? py> mylist = [1, 2, 3, 4, 5] py> from operator import mul py> reduce(mul, mylist) 120 I would really like to see your implementation of a reduce method that turns a list into an int *in-place*. > Applying mutations both "in-place" and "to a copy" are > very helpful. Exactly. [snip] >> > My point was this: All mutate methods should mutate "in-place", >> >> Well duh. All mutator methods do mutate in-place, otherwise they wouldn't >> be mutator methods. > > So "reversed()" and "sorted()" mutate in-place? No. They are not mutator methods, because they do not mutate in place. >> > if the >> > programmer wishes to create a mutated copy of the object, then the >> > programmer should /explicitly/ create a copy of the object and then >> > apply the correct mutator method to the copy. >> >> Been there, done that, it sucks. That's about a dozen steps backwards to >> a worse time in Python development. > > Why? Because you have to type this > > reversed = list(seq).reverse() Are you sure you've programmed in Python before? That gives reversed = None. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sunday, February 10, 2013 7:30:00 AM UTC-6, Oscar Benjamin wrote: > On 10 February 2013 04:53, Mark Janssen wrote: > > [...] > > I have to agree with Rick, I think requiring the user to explicitly > > create a new object, which is already a good and widely-used practice, > > should be the Only One Way to Do It. > > Why should I copy a potentially large data structure just to iterate > over it in reverse order? That's a good question, and the answer is: "Only a fool would make a copy of ANY data structure only to simply iterate over it; be it forwards or backwards or sideways". > And why on earth would you want to remove > the more efficient ways of doing this? Well these "ways"(sic) might be more efficient, at this time, because the Python developers have defined them to be. This could be changed if they would drop the aversion to true OOP paradigm. To make this work properly you would need to optimize the constructor of the sequence object. If the user presents the seq object (say for example a list) with variable that points to an already existing list like: py> a = [1,2,3] py> for x in list(a).reverse(): ... do_something Python will not actually create a copy of the list because that would be foolish! Python would instead ITERATE over the existing object transparently. It's called OPTIMIZING CODE! By doing this we gain many things: * We don't have these foolish "mutate"<->"copy mutate" method "pairs" like: "seq.reverse()" and "seq.reversed()" * We are writing maintainable code by explicitly calling "Sequence(seq).mutate()". The intent becomes obvious even though Python may "optimize" our intentions "behind the scenes". > > Guessing method names is far suboptimal to this simple, easy idiom. > > There is no guessing. If the object has a __reverse__ method then it > specifically advertises that it knows how to create an iterator that > gives its values in reverse order. Otherwise __len__ and __getitem__ > are used. Really. And you know that simply from intuiting a seemingly unrelated method? Wow, i'd bet the detectives of many municipalities would love to rent some of your powers. What sort of esoteric rule book are you reading from my friend? -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson wrote: > we can get the iterator for free. If however you want to control the > iteration /without/ being locked into a loop, you can explicitly call: > > py> iter(seq) > Or, if python employed /true/ OOP paradigm: > > py> Iterator(seq) Today I learned that the difference between "true" OOP and everything else is the presence of an initial capital letter. Thank you Rick for your deep insight. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Dennis Lee Bieber wrote: > On Mon, 11 Feb 2013 01:29:30 +1100, Steven D'Aprano > declaimed the following in > gmane.comp.python.general: > >> >> Oh dear. Chris was being sarcastic. I thought that, even if the sarcasm >> wasn't obvious, his "Ook. Ook!" at the end should have given it away: >> >> http://www.dangermouse.net/esoteric/ook.html >> > > Ah... and here I thought it might have been a subtle reference to > the Librarian of the Unseen University... > http://en.wikipedia.org/wiki/Unseen_University#Librarian Not so subtle. The creator of Ook obviously is a fan. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Mark Janssen wrote: > A unified data model as I define it, specifies a canonical atomic unit > (like the unit integer) and an abstract grouping construct in which > these atomic units can be arranged. By themselves, these two can > construct arbitrary levels of data structure complexity. Add the > ability to apply names to these levels, and you have a complete data > model for a happy programming environment. My work, to give you some > context, involves the invention of a "fractal graph" which is where > the name "unified object model" came from, because a fractal graph, I > argue can represent every part of the physical world at every scale. How can you breathe *way* up there in space? http://www.joelonsoftware.com/articles/fog18.html P.S. not all phenomena are fractal. The elbow joint, for instance, is just a hinge, and not made of smaller elbow joints made of tinier elbow joints made of even tinier elbow joints made of ... -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
> > > flatten, flattened > > > > flatten is another often requested, hard to implement correctly, > > function. The only reason that Python doesn't have a flatten is > > that nobody can agree on precisely what it should do. > > Steven, the definition of flatten (as relates to sequences) is > very, VERY simple: > > Return a new sequence that is the result of reducing > a nested sequence of sequences into a single depth > sequence. What should you get if you flatten [[[1,2],[3,4]],[[5,6],[7,8]]] Should the result be [[1,2],[3,4],[5,6],[7,8]] or [1,2,3,4,5,6,7,8] I've needed both cases, depending on the situation. -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sunday, February 10, 2013 5:29:54 AM UTC-6, Steven D'Aprano wrote: > Rick wrote: > And you have missed my point, which is that reversed(), and sorted(), were > not added to the language on a whim, but because they were requested, over > and over and over again. Well, well, this explains everything! We don't add features because of logic, or because of consistency, or even because of good sense, we simply add them to appease the masses. psst: Steven, maybe if the C and Java heads moan long enough we can get braced scoping, or, if the ruby guys pester us enough we can adopt the dollar sign to denote globals, the "@@" for class variables, and the "@" for instance variables! Oh yes! Because being loved is SO much more important than sticking to our philosophy of the Python Zen. > "appended" is called list addition. > > newlist = oldlist + [item_to_append] But where is the consistency? Yes the syntactic sugar of the "plus sign" is concise, however, the "+" operator does not "pair" intuitively with the "append" method. Even IF you transformed the "+" operator into a named method like "add" (or call the magic method "__add__") it still fails to mesh properly with "append", and the two words utterly fail to intuitively establish an "in-place" versus "copy-mutate" relationship. Consider the English definitions of "add" and "append" when applied to sequence objects: DEFINE "add" Expand a sequence of "somethings" to include additional "somethings" -- which may be another sequence of N somethings. However the exact location of the new "somethings" is not clearly intuit-able from the word "add" alone! DEFINE "append" Expand a sequence of "somethings" to include an additional "something". Here the exact location is can be intuited as: "at the end". > > flatten, flattened > > flatten is another often requested, hard to implement correctly, function. > The only reason that Python doesn't have a flatten is that nobody can agree > on precisely what it should do. Steven, the definition of flatten (as relates to sequences) is very, VERY simple: Return a new sequence that is the result of reducing a nested sequence of sequences into a single depth sequence. > Like map, filter, reduce, etc. flatten is not sensibly implemented as a > mutator method, but as a function. Only because you, along with a few other high ranking members of this community (including the BDFL himself!) have this /aversion/ to true OOP paradigm. Can you provide an example of how flatten "as a method" is incorrect versus flatten "as a function" is correct, or will this challenge be silently swept under the rug as so many before? > > insert, inserted > > "inserted" is called addition, together with list slicing when needed. > newlist = [item_to_insert] + oldlist > newlist = oldlist[0:5] + [item_to_insert] + oldlist[5: "inserted" is called "addition" by who? If are implying that "seq.__add__()" employs the semantics of the English word "addition" and seq.insert(arg) is a thin wrapper around "oldlist[0:5]+[item]+oldlist[5:]", then fine. But how will someone intuit those two methods as have a "mutating pairs relationship" from the names alone? Not to mention that calling magic methods is anti-pythonic! > > map, mapped > > filter, filtered > > reduce, reduced > > Those are nonsense. None of those are in-place mutator methods. Well not in the current implementation of Python; but they could be if we wanted them to be. Applying mutations both "in-place" and "to a copy" are very helpful. For example, Ruby supplies both forms for many commonly used operations on arrays: (However i am not a fan of these "mutator pairs") slice, slice! sort, sort! flatten, flatten! collect, collect! map, map! uniq, uniq! reject, reject! reverse, reverse! compact, compact! Steven, just because you have yet to encounter such usage does not mean the usage is "non-sense" seq.map(func) new = seq.mapped(func) seq.filter(lambda x: x<2) new = seq.filtered(lambda x: x<2) > Especially reduce, which reduces a list to a single item. Nice to see you are paying attention! I am sure you already know this, although your wording was clumsy and suggests otherwise, but reduce does NOTHING to the list itself: py> from operator import add py> a = [1,2,3] py> reduce(add, a) 6 py> a [1, 2, 3] reduce simply returns the result of the reduction; which is an Integer. However it is my strong belief that the sum function should not exist when a reduce function does. Why? Because "sum([1,2,3])" is the equivalent of "reduce(operator.add, [1,2,3])"; the latter being significantly explicit and the former being a potential linguistical interpretation nightmare. Now some might complain about this proposed removal of "sum" because the reduce function requires two arguments whereas the sum only needs one, and I say you're correct, however, this nega
Re: LangWart: Method congestion from mutate multiplicty
On Sun, Feb 10, 2013 at 1:51 PM, Chris Angelico wrote: > On Mon, Feb 11, 2013 at 8:28 AM, Mark Janssen > wrote: >> Yes, I was aware of his sarcasm. But I was actually wanting to agree >> with the fundamental idea: that one could reduce all data types to 1 >> atomic unit and 1 grouping construct, and like set theory in >> mathematics, derive everything else. > > There are many things that work fine in theory, but aren't practical. > You could theoretically rewrite any Python program in Ook (or its > non-G-rated cousin), but that doesn't mean that Ook's data model is > worth working with. Ah, but you're conflating a *data model* (which is already composed of simple theoretical elements (like 1/0)) and a *programming language*, which is composed of either an implicit or explicit data model (usually the former) AND a set of transforms that operate on it. IOW, I'm wanting to take something that is usually just inherited and historical (and thereby taken for granted), and make it something to look at. Traditional Data Structures in CompSci goes somewhat towards this end, but doesn't quite take the idea to its ultimate, and that's what I'm proposing with a unified data model. mark -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson: Really? Yes. >> a = [1,2] => [1, 2] >> a.push(3) => [1, 2, 3] >> a => [1, 2, 3] This could be called "mutation without exclamation". >> require 'WEBrick' => true >> vowels = "[aeiou]+" => "[aeiou]+" >> vowels.object_id => 2234951380 >> WEBrick::HTTPUtils._make_regex!(vowels) => /([^\[aeiou\]\+])/n >> vowels => "[aeiou]+" >> vowels.object_id => 2234951380 The counterpart, exclamation without mutation. Neil -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Mon, Feb 11, 2013 at 8:28 AM, Mark Janssen wrote: > Yes, I was aware of his sarcasm. But I was actually wanting to agree > with the fundamental idea: that one could reduce all data types to 1 > atomic unit and 1 grouping construct, and like set theory in > mathematics, derive everything else. There are many things that work fine in theory, but aren't practical. You could theoretically rewrite any Python program in Ook (or its non-G-rated cousin), but that doesn't mean that Ook's data model is worth working with. You could write a Python-to-Ook compiler, perhaps, for what that's worth. Proving these things possible may be of curiosity value, but I wouldn't want to actually _work with_ such a system. A while ago I put together a language concep[1]t that, similarly, started with nothing and let the programmer build from there. It quickly proved to have one massive fundamental flaw: that two programs, ostensibly written in the same language, could be utterly and completely different. It'd be like treating Python and bash scripts as the same language, given that the shebang at the top makes them both execute just fine. If you reduce everything to nothing, you (1) force the programmer to do a lot of unnecessary work, and (2) allow two different programmers to do that work subtly differently and thus create incompatible programs. (Python already has a little of this, in that Py2 and Py3 files aren't guaranteed compatible; but imagine if every source file were different.) [1] Posted here if you care. http://rosuav.com/1/?id=683 ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On 2/10/2013 1:45 PM, Rick Johnson wrote: On Sunday, February 10, 2013 2:39:21 AM UTC-6, Terry Reedy wrote: While it is true that sorted(iterable) is essentially def sorted(iterable): tem = list(iterable) tem.sort return tem the body is not an expression and cannot be substituted in an expression. Yes but the body can be compressed to this single line: "list(iterable).sort()" That single line now evaluates to None, so that does not work. Even if list mutation methods returned the list, which they do not and for good reason, I am not proposing that in-place modification return the object. It seems to me that you are, as that is the only way for 'list(iterable).sort()' to replace 'sorted(iterable)', as you proposed both originally and above. The reason sorted(iterable) was added is 'list(iterable).sort()', which newbies would try, *does not work*. Sorted was added so people would not have to write tem = list(iterable) tem.sort() del tem as they did previously, and instead could write Reversed was added not only for the same reason, but also to avoid the temporary list altogether when not actually needed, which it often or usually is not. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sun, Feb 10, 2013 at 6:29 AM, Steven D'Aprano wrote: > Mark Janssen wrote: >> I have to agree with Rick, I think requiring the user to explicitly >> create a new object, which is already a good and widely-used practice, > > Perhaps so, but consider how you creates new objects in Python. Very rarely > do you do so with an explicit call to the constructor. For example: > > n = 5 # Yes. > # or > n = int("5") # No. Good, alright, this is the point where the concept of a unified object model comes into play. (Actually, I'm going to say "unified data model" (or UDM) from now on so as to avoid the confusion that you point out below that Python seems to already have a "unified object model" because everything derives from "Object". The point is actually rather subtle.) A unified data model as I define it, specifies a canonical atomic unit (like the unit integer) and an abstract grouping construct in which these atomic units can be arranged. By themselves, these two can construct arbitrary levels of data structure complexity. Add the ability to apply names to these levels, and you have a complete data model for a happy programming environment. My work, to give you some context, involves the invention of a "fractal graph" which is where the name "unified object model" came from, because a fractal graph, I argue can represent every part of the physical world at every scale. (Note that everything in a computer is series of these "atomic" bits organized by the machine into "words" (merely for sake of the efficiency that such parallelization affords), yet we have these human-language constructs such as lists and sets (or records, files, arrays, etc) where *no such things exist in the computer*. Hence, the usefulness of considering a unified data model as part of the computer *science*.) In your example above, you can verify, for example, that the identity of 5 and int("5") is the same -- even though you're using a constructor syntax, you're not *constructing* anything at all, which you may know already (somewhere in the Python docs, Guido points out that Python pre-constructs the first 100 or so integers as I recall.) There is, in addition, an implicit constructor for integers, such that saying 656565 in python will actually construct the integer as if you said "int("656565")". In any case, one never operates or concerns oneself with copies of atomic elements because they are all the same. It's a subtle meta-philosophical(?) point, not that different that that which occurs in the science of physics regarding electrons and protons ("Is there only one electron?": http://en.wikipedia.org/wiki/One-electron_universe). > py> import this > [...] > There should be one-- and preferably only one --obvious way to do it. Yes, that is the reference. >> Guessing method names is far >> suboptimal to this simple, easy idiom. As for the point Chris was >> making as to making all types one, I actually agree there too, > > Oh dear. Chris was being sarcastic. I thought that, even if the sarcasm > wasn't obvious, his "Ook. Ook!" at the end should have given it away: Yes, I was aware of his sarcasm. But I was actually wanting to agree with the fundamental idea: that one could reduce all data types to 1 atomic unit and 1 grouping construct, and like set theory in mathematics, derive everything else. >> it's >> just that in order to do that, python would need a unified object >> model and it doesn't have one yet. > > I'm not sure what you mean by "unified object model", but I'm pretty sure > that Python has one. Everything is an object, with a single[1] hierarchy of > classes. Hopefully the elucidation above clears up some of that confusion. Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sunday, February 10, 2013 3:53:57 AM UTC-6, Neil Hodgson wrote: > Ruby does not use '!' to indicate in-place modification: Really? rb> a = [1,2,3] [1, 2, 3] rb> a.reverse [3, 2, 1] rb> a [1, 2, 3] rb> a.reverse! [3, 2, 1] rb> a [3, 2, 1] And now we will verify that a.reverse! has not assigned 'a' to a new object rb> a = [1,2,3] [1, 2, 3] rb> aID = a.object_id 78906770 rb> a.reverse! [3, 2, 1] rb> a [3, 2, 1] rb> a.object_id 78906770 I'd love to hear an explanation for that. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sunday, February 10, 2013 2:39:21 AM UTC-6, Terry Reedy wrote: > While it is true that sorted(iterable) is essentially > > def sorted(iterable): >tem = list(iterable) >tem.sort >return tem > > the body is not an expression and cannot be substituted in an > expression. Yes but the body can be compressed to this single line: "list(iterable).sort()" > Reversed(iterable) is more complicated because it returns an iterator, > not a list, and looks for a class-specific __reversed__ method. > [...] Well if you're taking the position that iterators are difficult to create i say you are exaggerating a bit. Using the for loop: py> for LOCALVAR in SEQUENCE: ... do_something we can get the iterator for free. If however you want to control the iteration /without/ being locked into a loop, you can explicitly call: py> iter(seq) Or, if you prefer methods over global functions: py> seq.__iter__() Or, if python employed /true/ OOP paradigm: py> Iterator(seq) > Even if list mutation methods returned the list, which they do not and > for good reason, I am not proposing that in-place modification return the object. > reversed(it) is not the same as list(it).reverse(). So > that part of the premise of this thread is wrong. Well, it's not the same /now/, because of how Python handles this operation. The status quo is to encourage the implicit idiom over the explicit, however, this behavior could be optimized to cleanly handle /explicit/ syntax only. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sun, Feb 10, 2013 at 5:30 AM, Oscar Benjamin wrote: > On 10 February 2013 04:53, Mark Janssen wrote: >> I have to agree with Rick, I think requiring the user to explicitly >> create a new object, which is already a good and widely-used practice, >> should be the Only One Way to Do It. > > Why should I copy a potentially large data structure just to iterate > over it in reverse order? And why on earth would you want to remove > the more efficient ways of doing this? You're right. I responded too fast. I think reversed() and sorted() might be the only legit methods in this regard and I thank Steve D'Aprano for pointing that out. But Rick still has a valid point: it should not be taken as a general practice. The point, as I see it, is that there's no clear, documented standard on the "right way" for people to think about the issue. The existence of sorted() and reversed() actually *misinform* programmers as if this is the best practice. It isn't, it just that these are very special cases (one for a real machine efficiency and one for a very common "user efficiency") and there should probably be documentation to make that clear, so programmers don't start going that direction. I don't think there are other cases where such an idiom would be recommended. Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Steven D'Aprano於 2013年2月9日星期六UTC+8上午11時36分52秒寫道: > Rick Johnson wrote: > > > > > The solution is simple. Do not offer the "copy-mutate" methods and force > > > all mutation to happen in-place: > > > > > > py> l = [1,2,3] > > > py> l.reverse > > > py> l > > > [3,2,1] > > > > > > If the user wants a "mutated copy" he should explicitly create a new > > > object and then apply the correct mutator method: > > > > > > py> a1 = [1,2,3] > > > py> a2 = list(a1).reverse() > > > > > > Oh wow, Rick has re-discovered programming in Python during the mid to late > > 1990s! > > > > I was there, and I remember what it was like. For about a month, you try > > hard to follow Rick's prescription. Then you realise that with a small > > helper function, you can halve the amount of code it takes to do a common > > operation: > > > > def reversed(sequence): > > seq = list(sequence) > > seq.reverse() > > return seq > > > > > > Soon you've copied this reversed() function into all your projects. And of > > course, they start to diverge... in project A, you only care about lists. > > In project B, you realise that you also need to support tuples and strings: > > > > > > def reversed(sequence): > > seq = sequence[:] > > try: > > seq.reverse() > > except AttributeError: > > seq = seq[::-1] > > return seq > > Will a temprary new list be formed here? If it is not necessary, I'll prefer a reverse generator for all lists to save the heap space and the GC burden. > > which in project C you realise can be shortened: > > > > def reversed(sequence): > > return sequence[::-1] > > > > > > until you get to project D when you realise that you also want this to work > > on dicts: > > > > def reversed(sequence): > > everything = list(sequence) > > return everything[::-1] > > > > > > and then in project E you wonder why reversed(string) returns a list: > > > > def reversed(sequence): > > everything = list(sequence)[::-1] > > if isinstance(sequence, tuple): > > return tuple(everything) > > elif isinstance(sequence, str): > > return ''.join(everything) > > return everything > > > > > > and then finally you learn about iterators and generators and become more > > comfortable with a flow-based programming paradigm and generators: > > > > def reversed(sequence): > > for item in list(sequence)[::-1]: > > yield item > > > > at which point you realise that, hell, this is so useful that pretty much > > everyone has implemented it a dozen times or more in their own projects, > > and you start to agitate for it to be added to the builtins so that there > > is *one* implementation, done *right*, that everyone can use. > > > > And then you get told that Guido's time machine has struck again, because > > Python has already had this since Python 2.4. > > > > > > > > -- > > Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Mark Janssen wrote: > On Sat, Feb 9, 2013 at 8:20 PM, Chris Angelico wrote: >> On Sun, Feb 10, 2013 at 2:54 PM, Rick Johnson >> wrote: >>> My point was this: All mutate methods should mutate "in-place", if the >>> programmer wishes to create a mutated copy of the object, then the >>> programmer should /explicitly/ create a copy of the object and then >>> apply the correct mutator method to the copy. >> >> I agree. And we can go further and declare that there is only one data >> [sarcasm] > > I have to agree with Rick, I think requiring the user to explicitly > create a new object, which is already a good and widely-used practice, Perhaps so, but consider how you creates new objects in Python. Very rarely do you do so with an explicit call to the constructor. For example: n = 5 # Yes. # or n = int("5") # No. alist = some_list[1:] # Yes. # or alist = list() alist.extend(some_list[1:]) # No. items = sorted(other_things + [1]) # Yes. # or items = other_things[:] items.append(1) items.sort() # Hell no. There are many functions or methods that create new objects, apart from the constructor. A call like: blist = sorted(alist) is no less explicitly creating a new list than: blist = list(alist) > should be the Only One Way to Do It. Pardon me, but you've been listening to too many Perl developers. "Only One Way To Do It" is not, and never has been, the motto of Python. You may be thinking of the line from the Zen of Python: py> import this [...] There should be one-- and preferably only one --obvious way to do it. The emphasis is on the *obvious*, not the "only". There is an enormous difference between prohibiting a second way to solve problems ("Only One Way") and recommending that there should be an Obvious Way. > Guessing method names is far > suboptimal to this simple, easy idiom. As for the point Chris was > making as to making all types one, I actually agree there too, Oh dear. Chris was being sarcastic. I thought that, even if the sarcasm wasn't obvious, his "Ook. Ook!" at the end should have given it away: http://www.dangermouse.net/esoteric/ook.html > it's > just that in order to do that, python would need a unified object > model and it doesn't have one yet. I'm not sure what you mean by "unified object model", but I'm pretty sure that Python has one. Everything is an object, with a single[1] hierarchy of classes. [1] Python 3 only. In Python 2, you have types, and you have old-style classes, and they are separate. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Chris Angelico wrote: > On Sun, Feb 10, 2013 at 10:29 PM, Steven D'Aprano > wrote: >> "inserted" is called addition, together with list slicing when needed. >> >> newlist = [item_to_insert] + oldlist >> newlist = oldlist[0:5] + [item_to_insert] + oldlist[5:] > > Really? Wouldn't it be easier to use slice assignment on a copy? > > newlist = oldlist[:]; newlist[pos:pos] = [item_to_insert] I don't know about "easier", but it's two statements rather than a single expression, which means you cannot easily include it as part of a larger expression. > Actually, come to think of it, that scores about the same on > readability. Six of one, half dozen of the other. Pretty much. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sun, 10 Feb 2013 22:29:54 +1100, Steven D'Aprano wrote: > Rick Johnson wrote: > > map, mapped > > filter, filtered > > reduce, reduced > > Those are nonsense. None of those are in-place mutator methods. > Especially reduce, which reduces a list to a single item. You might > as well have suggested "len, "lened". And, if you want those in-place, indexing trivially comes to the rescue again: lst[:] = map(transform_fn, lst) lst[:] = filter(check_fn, lst) or, as I prefer: lst[:] = [transform_fn(x) for x in lst] lst[:] = [x for x in lst if check_fn(x)] as they can be combined simply. -tkc -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On 10 February 2013 04:53, Mark Janssen wrote: > On Sat, Feb 9, 2013 at 8:20 PM, Chris Angelico wrote: >> On Sun, Feb 10, 2013 at 2:54 PM, Rick Johnson >> wrote: >>> My point was this: All mutate methods should mutate "in-place", if the >>> programmer wishes to create a mutated copy of the object, then the >>> programmer should /explicitly/ create a copy of the object and then apply >>> the correct mutator method to the copy. >> >> I agree. And we can go further and declare that there is only one data >> [sarcasm] > > I have to agree with Rick, I think requiring the user to explicitly > create a new object, which is already a good and widely-used practice, > should be the Only One Way to Do It. Why should I copy a potentially large data structure just to iterate over it in reverse order? And why on earth would you want to remove the more efficient ways of doing this? > Guessing method names is far suboptimal to this simple, easy idiom. There is no guessing. If the object has a __reverse__ method then it specifically advertises that it knows how to create an iterator that gives its values in reverse order. Otherwise __len__ and __getitem__ are used. Oscar -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sun, Feb 10, 2013 at 10:29 PM, Steven D'Aprano wrote: > "inserted" is called addition, together with list slicing when needed. > > newlist = [item_to_insert] + oldlist > newlist = oldlist[0:5] + [item_to_insert] + oldlist[5:] Really? Wouldn't it be easier to use slice assignment on a copy? newlist = oldlist[:]; newlist[pos:pos] = [item_to_insert] Actually, come to think of it, that scores about the same on readability. Six of one, half dozen of the other. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson wrote: > On Friday, February 8, 2013 9:36:52 PM UTC-6, Steven D'Aprano wrote: >> Rick Johnson wrote: >> >> > The solution is simple. Do not offer the "copy-mutate" methods and >> > force all mutation to happen in-place: >> > >> > py> l = [1,2,3] >> > py> l.reverse >> > py> l >> > [3,2,1] >> > >> > If the user wants a "mutated copy" he should explicitly create a new >> > object and then apply the correct mutator method: >> > >> > py> a1 = [1,2,3] >> > py> a2 = list(a1).reverse() >> >> Oh wow, Rick has re-discovered programming in Python during the mid to >> late 1990s! >> >> [...snip: long-winded, rambling, and sarcastic response simply to convey >> that Python lists have had a "reversed" method for some time...] > > Steven, i am quite aware of the Python list method "reversed" --which > returns a copy of the current list object in reversed order--, And you have missed my point, which is that reversed(), and sorted(), were not added to the language on a whim, but because they were requested, over and over and over again. People who actually programmed using Python before reversed() and sorted() were added missed them, and consequently kept reimplementing them. You want to go back to the Bad Old Days when everyone was reimplementing the same few functions over and over again. I say, boo sucks to that. > my point is > that these types of "copy-mutate" methods superfluously pollute the object > namespace. Do you really want "method pairs" like these: > > sort, sorted > reverse, reversed Yes. > Hell, why stop there: > > append, appended "appended" is called list addition. newlist = oldlist + [item_to_append] > flatten, flattened flatten is another often requested, hard to implement correctly, function. The only reason that Python doesn't have a flatten is that nobody can agree on precisely what it should do. Like map, filter, reduce, etc. flatten is not sensibly implemented as a mutator method, but as a function. > insert, inserted "inserted" is called addition, together with list slicing when needed. newlist = [item_to_insert] + oldlist newlist = oldlist[0:5] + [item_to_insert] + oldlist[5:] > map, mapped > filter, filtered > reduce, reduced Those are nonsense. None of those are in-place mutator methods. Especially reduce, which reduces a list to a single item. You might as well have suggested "len, "lened". > extend, extended Again, "extended" is spelled list addition. Are you sure you've actually programmed in Python before? You seem awfully ignorant of language features. [...] > My point was this: All mutate methods should mutate "in-place", Well duh. All mutator methods do mutate in-place, otherwise they wouldn't be mutator methods. > if the > programmer wishes to create a mutated copy of the object, then the > programmer should /explicitly/ create a copy of the object and then apply > the correct mutator method to the copy. Been there, done that, it sucks. That's about a dozen steps backwards to a worse time in Python development. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Neil Hodgson wrote: > Rick Johnson: > >> The Ruby language attempted to save the programmer from the scourge of >> obtaining a four year degree in linguistics just to create intuitive >> identifiers "on-the-fly", and they tried to remove this ambiguity by >> employing "post-fix-punctuation" of the exclamation mark as a visual cue >> for in-place modification of the object: > > Ruby does not use '!' to indicate in-place modification: > http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist Why am I not surprised that Rick's knowledge of Ruby is no deeper than his knowledge of Python? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson: The Ruby language attempted to save the programmer from the scourge of obtaining a four year degree in linguistics just to create intuitive identifiers "on-the-fly", and they tried to remove this ambiguity by employing "post-fix-punctuation" of the exclamation mark as a visual cue for in-place modification of the object: Ruby does not use '!' to indicate in-place modification: http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist Neil -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
While it is true that sorted(iterable) is essentially def sorted(iterable): tem = list(iterable) tem.sort return tem the body is not an expression and cannot be substituted in an expression. The need for the short form was thought common enough to be worth, *on balance*, a new builtin name. It is not surprising that not all agree. Reversed(iterable) is more complicated because it returns an iterator, not a list, and looks for a class-specific __reversed__ method. I think it is more or less equivalent to the following: def _rev_iter(seq, n): for i in range(n-1, -1, -1): # many people have trouble getting the range right yield seq[i] def reversed(iterable): try: return iterable.__reversed__() except AttributeError: try: itlen = iterable.__len__ iterable.__getitem__ return _rev_iter(iterable, itlen) except AttributeError: raise TypeError("argument to reversed() must be a sequence") Even if list mutation methods returned the list, which they do not and for good reason, reversed(it) is not the same as list(it).reverse(). So that part of the premise of this thread is wrong. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sat, Feb 9, 2013 at 8:20 PM, Chris Angelico wrote: > On Sun, Feb 10, 2013 at 2:54 PM, Rick Johnson > wrote: >> My point was this: All mutate methods should mutate "in-place", if the >> programmer wishes to create a mutated copy of the object, then the >> programmer should /explicitly/ create a copy of the object and then apply >> the correct mutator method to the copy. > > I agree. And we can go further and declare that there is only one data > [sarcasm] I have to agree with Rick, I think requiring the user to explicitly create a new object, which is already a good and widely-used practice, should be the Only One Way to Do It. Guessing method names is far suboptimal to this simple, easy idiom. As for the point Chris was making as to making all types one, I actually agree there too, it's just that in order to do that, python would need a unified object model and it doesn't have one yet. Mark -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sun, Feb 10, 2013 at 2:54 PM, Rick Johnson wrote: > My point was this: All mutate methods should mutate "in-place", if the > programmer wishes to create a mutated copy of the object, then the programmer > should /explicitly/ create a copy of the object and then apply the correct > mutator method to the copy. I agree. And we can go further and declare that there is only one data type, the simple integer; you have an infinite number of them, and all you can do is mutate them in place. You don't need variable names either; just have one single array that represents your whole namespace, and work with positions in that array. And don't bother with actual positions, even - with a single pointer, you could manage everything. Forget this silly mess of data types, methods, global functions, and so on. Let's simplify things massively! Ook. Ook! ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Friday, February 8, 2013 9:36:52 PM UTC-6, Steven D'Aprano wrote: > Rick Johnson wrote: > > > The solution is simple. Do not offer the "copy-mutate" methods and force > > all mutation to happen in-place: > > > > py> l = [1,2,3] > > py> l.reverse > > py> l > > [3,2,1] > > > > If the user wants a "mutated copy" he should explicitly create a new > > object and then apply the correct mutator method: > > > > py> a1 = [1,2,3] > > py> a2 = list(a1).reverse() > > Oh wow, Rick has re-discovered programming in Python during the mid to late > 1990s! > > [...snip: long-winded, rambling, and sarcastic response simply to convey > that Python lists have had a "reversed" method for some time...] Steven, i am quite aware of the Python list method "reversed" --which returns a copy of the current list object in reversed order--, my point is that these types of "copy-mutate" methods superfluously pollute the object namespace. Do you really want "method pairs" like these: sort, sorted reverse, reversed Hell, why stop there: append, appended flatten, flattened insert, inserted map, mapped filter, filtered reduce, reduced extend, extended freeze, frozen set, sat|setted unique, uniqued Is this really what you prefer? Where does the madness end Steven? At what point do you say enough is enough? And what happens if you fail to catch the infection early enough? Steven, this is a /real/ problem which has the potential to go viral! My point was this: All mutate methods should mutate "in-place", if the programmer wishes to create a mutated copy of the object, then the programmer should /explicitly/ create a copy of the object and then apply the correct mutator method to the copy. NO: reversed = lst.reversed() # Python YES: reversed = list(lst).reverse() # Python NO: reversed = a.reverse() # Ruby YES: reversed = Array.new(a).reverse!() # Ruby This is about consistency and keeping the number of methods from spiraling out of control because we feel the need to automate /every/ task for the programmer, when in actuality, we are doing more harm than good. -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
On Sat, Feb 9, 2013 at 12:50 PM, Rick Johnson wrote: > I really don't like to read docs when learning a language, especially a > "so-called" high level language. I prefer to learn the language by > interactive sessions and object introspection. Then, when i have exhausted > all abilities to intuit the solution, i will roll my eyes, maybe blubber an > expletive, and then reluctantly crack open a user manual. What Rick means: "I want to claim that I've learned a new language, but I want it to work exactly like the imaginary language in my mind, and if it doesn't, I'm going to complain about it, rather than, yaknow, actually learn a new language." I have learned *many* languages in the past couple of decades. Some of them are excellent and I keep using them (Pike). Others are excellent and I keep talking about them (Python). Some are mediocre or poor, but I keep using them anyway (bash). Some are not particularly enjoyable to me and I use them only in the one application that embeds them (Lua, Scheme, DML). And some, I'm just not going to touch any more (Q-BASIC). But there is not a single language that hasn't taught me something new. I'm a better C++ programmer for having learned Python; a better Python programmer for having grokked Scheme and Lua; and, believe it or not, a better Scheme programmer for having mastered DML. And that's a language so obscure it doesn't even have a Wikipedia page... just a redlink here[1]. Learning a language requires accepting something from it into your brain, not forcing something from your brain onto the language. ChrisA [1] http://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Extension_languages -- http://mail.python.org/mailman/listinfo/python-list
Re: LangWart: Method congestion from mutate multiplicty
Rick Johnson wrote: > The solution is simple. Do not offer the "copy-mutate" methods and force > all mutation to happen in-place: > > py> l = [1,2,3] > py> l.reverse > py> l > [3,2,1] > > If the user wants a "mutated copy" he should explicitly create a new > object and then apply the correct mutator method: > > py> a1 = [1,2,3] > py> a2 = list(a1).reverse() Oh wow, Rick has re-discovered programming in Python during the mid to late 1990s! I was there, and I remember what it was like. For about a month, you try hard to follow Rick's prescription. Then you realise that with a small helper function, you can halve the amount of code it takes to do a common operation: def reversed(sequence): seq = list(sequence) seq.reverse() return seq Soon you've copied this reversed() function into all your projects. And of course, they start to diverge... in project A, you only care about lists. In project B, you realise that you also need to support tuples and strings: def reversed(sequence): seq = sequence[:] try: seq.reverse() except AttributeError: seq = seq[::-1] return seq which in project C you realise can be shortened: def reversed(sequence): return sequence[::-1] until you get to project D when you realise that you also want this to work on dicts: def reversed(sequence): everything = list(sequence) return everything[::-1] and then in project E you wonder why reversed(string) returns a list: def reversed(sequence): everything = list(sequence)[::-1] if isinstance(sequence, tuple): return tuple(everything) elif isinstance(sequence, str): return ''.join(everything) return everything and then finally you learn about iterators and generators and become more comfortable with a flow-based programming paradigm and generators: def reversed(sequence): for item in list(sequence)[::-1]: yield item at which point you realise that, hell, this is so useful that pretty much everyone has implemented it a dozen times or more in their own projects, and you start to agitate for it to be added to the builtins so that there is *one* implementation, done *right*, that everyone can use. And then you get told that Guido's time machine has struck again, because Python has already had this since Python 2.4. -- Steven -- http://mail.python.org/mailman/listinfo/python-list