I take Sean's point. However, while I agree that practising using polymorphism instead of 'if' is a good idea, I don't think that *this* exercise is a good one for getting such practice. Roelof is going through the Pharo track of Exercism. This particular one is called 'flatten-array'. The one concession to "hey, this is Pharo!" in the description of the exercise is a veiled warning against using Pharo's #flattened/#flattenOn:, which (a) does not add anything to Object or UndefinedObject (just Collection>>flattened and Collection>>flattenOn:) (b) does not make a special case of nil (c) DOES make a special case of strings, treating them as atomic. Possibly the most challenging part for me in this exercise was trying to figure out "what does <list> mean for Smalltalk here?" In Pharo's existing #flattened, why does a String count as atomic but a Semphore is just another collection?
This is a Lisp programming exercise from the early 1960s. It had unpleasant ambiguities back then and it has not got better since. If this were rewritten as "Make a Composite implementation of binary search trees with a class for empty trees, a class for non-empty ones, and perhaps a class for singleton ones. Implement #do:, traversing the elements in increasing order. Use this to implement #asOrderedCollection." then that *would* be a good exercise for using polymorphism instead of conditionals. BST () asOrderedCollection ^OrderedCollection new in: [:coll | self do: [:each | coll addLast: each]. coll] EmptyBST () do: aBlock "Nothing to do." NonemptyBST (less key greater) do: aBlock less do: aBlock. aBlock value: key. greater do: aBlock. On Tue, 15 Sep 2020 at 18:33, Sean P. DeNigris <s...@clipperadams.com> wrote: > Richard O'Keefe wrote > > Whatever else it is, OOP is a means to an end, not an end in itself. > > It's not a religion. > > Richard makes an important point here. > > As I mentioned on Discord (slightly edited to fit this thread), it’s a > judgment call with trade-offs, but for the purposes of an OOP exercise, I > would say absolutely put the methods in object and wherever else you may > need them - if only to get practice with that particular idiom. I needed to > do a lot of that sort of thing - probably way *too* much, just to break my > procedural thinking habits. Once I got it "in my bones" I became more > pragmatic. While in theory, this may always be the “most“ OOP way, in > practice it can be confusing due to the limitations of our system > organization and the fact that people will have to scroll through more > methods on kernel objects (not to mention the extra dependencies Richard > noted). That is the dogma, and I think is a fine answer for an OOP > exercise, > but IMHO in practice there are justifiable exceptions. The two major axes > are understandability and adaptability. If in your domain there are only > two > choices and there can not logically be more, it may be easier to understand > one method with a conditional that documents that domain fact, than it > would > be to dive down a polymorphism rabbit hole spread across the system. Of > course, tooling is a big factor in understandability. In GT it may be > trivial because you can open implementors in a plane right next to the code > browser. Different toolsets themselves mean different trade offs. There are > no one size fits all answers for all time. There are principles that have > to > be negotiated with your current environment, use case, experience level, > team size... > > > > ----- > Cheers, > Sean > -- > Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html >