PS: in this thread nobody has disagreed about what OO programming is. The disagreement was about *how to apply it*. There actually seems to be quite a lot of agreement that the answer depends on what your underlying goal is: - is this throw-away code for a specific problem? - is this code to be included in a useful program? - is this just for practice in an unfamiliar language where you already understand all the concepts? - is this for learning about radically new concepts? And everyone agrees that test cases are good for all of these.
You might find it useful to join another exercism thread and solve some of these problems in a language that you are comfortable with, then solve them in Smalltalk (or Ruby). This will help to separate "how do I solve this problem?" from "how do I express this solution in language X?" Another thing you might find useful, having solved a problem, is to try to solve it a different way. For example, in a functional language, you might solve a problem first in a C-like way using mutable objects freely. Then you might solve it again using immutable values. And then you might solve it again using higher-order functions. And then you might solve it again using point-free style as much as you can. For another example, in R, or Fortran 90, or Matlab, you might solve a problem first in an element-at-a-time way, and then you might try it again using vectorisation to eliminate as many loops as you can. And in *this* example, don't suppose that there is One Right Way To Do It. Get ONE solution going. ANY solution. I would suggest my approach, because (a) of course I would, and (b) it really is a struggle with exercism to find out what the problem actually is, and you want to get to SOME solution quickly. But it doesn't matter so much, because the point is to try it MORE ways than one. This is one way to learn design. Try more than one approach and discover which ones work out better. I started out using Point. Then I tried again just using bare coordinates. I started with position and velocity as instance variables. Then I tried again with them as method temporaries. I eliminated one thing after another until I was left with obviously correct code, and I felt no shame in using #caseOf: to classify characters, even though there are books that will tell you that using "if" and "case" is anti-OO. I could do it again eliminating #caseOf: in terms of "if" if I saw any value in doing so. In this particular exercise, you are simulating ONE instance (the robot) of ONE kind of thing (Robots). That strongly suggests that your solution might have ONE class: Robot, or perhaps TWO: Robot and RobotTest. That's the one active thing. This thing has properties: where it is and which way it is going. Now from the point of view of differential geometry, points and directions are different things and live in different abstract spaces, so I would have a lot of sympathy for having two classes: Place (x,y) and Direction (dx,dy) with #turnLeft and #turnRight as operations on Direction and place plus: distance in: direction as an operation on Place returning a new Place. But a good programmer is a lazy programmer, and looks for existing code to use. And the classic Point class in Smalltalk combines Place and Direction in one "two-dimensional vector" concept, originally designed for 2D computer graphics rather than geometry. It's good enough, and Smalltalk programmers can be expected to know that Point exists (just as Java programmers can be expected to know about Java's point classes), so I'd use it. So now, from one mind, we have designs with 1 Robot 2 Robot, RobotTest 3 Robot, RobotTest, Point 4 Robot, RobotTest, Place, Direction classes. ANY of them could be defended as a good design, depending on what the ultimate aim is.