One thing I have often seen and lamented is students
writing excessively complicated code with way too many
classes.  There is a huge difference between
  "A Robot knows its position and direction."
and
  "A Robot has-a Position and has-a Direction."
The first is the important one.  The second is
an over-commitment to too many classses.  For a
problem like this, you really really do not want
a Direction class, and you certainly have no use
for double dispatch.

A position can be represented by a pair of integers
x, y.  It could also be represented by a Point with
integer components.

A direction could be represented by a pair of integers
dx, dy such that |dx|+|dy| = 1.  It could also be
represented by a Point with integer components.

For movement, you need to be able to add the direction
to the location, which could be simply
x := x + dx.  y := y + dy.
or it could be
position := position + direction.
For turning, you need to be able to rotate a direction
vector by ninety degrees.  Now it so happens that
Point has methods #leftRotated and #rightRotated.

So we can do the following:
   a Robot has position (a Point) and direction (aPoint)
   position := 0 @ 0.
   direction := 0 @ 1.
To move forward without turning:
   position := position + direction.
To turn left without moving:
   direction := direction leftRotated.
To turn right without moving:
   direction := direction rightRotated.
To obey a sequence of characters, commands:
   commands do: [:each |
      each caseOf: {
         [$A] -> [--move forward--].
         [$L] -> [--turn left--].
         [$R] -> [--turn right--]
      }].


One of the key ideas in extreme programming is
"You Ain't Gonna Need It", abbreviated to YAGNI!
The idea is *DON'T* generalise beyond your immediate
needs.  In this case, for example, the likelihood of
*this* program needing to deal with more general
kinds of movement is ZERO.  And the only reason for
using Point here instead of just using a few simple
assignment statements is that Point already exists,
so costs nothing to write, and as a familiar class,
code using it should be easy to read.

If someone challenges you to do something counter-productive,
refuse the challenge.

On Mon, 8 Apr 2019 at 17:21, Roelof Wobben <r.wob...@home.nl> wrote:

> I can try to explain what I trying to solve.
>
> I have a Robot which can turn left,  turn right or moveForward.
>
> now I have a string like 'LAR'
>
> that means the robot needs to turn left (l) , move forward one place (A)
> and turn left.
> and I have to keep track to which direction the robot is facing and on
> which coordinate it stands.
>
> so to summarize with the above string
>
> lets say the robot is facing north on coordinate (0,0)
> then it has to turn left , so its facing east and still on coordinate
> (0,0)
> then it has to move forward, so its still  facing east but are on
> coordinate(0,1)
> then it has to turn right, so its facing north and on coordinate (0,1)
>
> and TimMacKinnon has challenged me to do this with double dispatch.
>
> So I think now I need a object Direction, a sub object North and a sub -
> sub object TurnLeft, turnRight and moveForward.
>
> So I can use double dispath first the direction North, East, South, West
> and then use double dispatch to find the right move.
>
> Roelof
>
>
>
>
>
> Op 8-4-2019 om 06:50 schreef Richard O'Keefe:
>
> It would really REALLY **REALLY** help if we knew what
> the heck you were trying to do.  There is an excellent
> chance that it is MUCH simpler than you think.  If you
> cannot show us the Smalltalk version of the problem,
> can you show us the version for some other language?
>
>
> On Sun, 7 Apr 2019 at 20:15, Roelof Wobben <r.wob...@home.nl> wrote:
>
>> Op 6-4-2019 om 15:15 schreef K K Subbu:
>> > On 06/04/19 4:49 PM, Roelof Wobben wrote:
>> >> Hello,
>> >>
>> >> I just learned double dispatch.
>> >> And now for the Robot challenge of exercism Tim has pointed me to
>> >> this
>> >> article(
>> https://blog.metaobject.com/2019/04/accessors-have-message-obsession.html)
>>
>> >>
>> >> but I fail to see how the move method looks like in that article.
>> >> I had a conversation with Tim in the exercism channel and the way he
>> >> explains it, it looks like double dispatch for me.
>> >>
>> >> Am I on the right track or do I oversee something here.
>> > unary methods like moveRight perform specific ops and are not
>> > parametric, so only a single dispatch, depending on the receiver, is
>> > needed.
>> >
>> > If you change it to move: aDistanceOrAngle, then performing requests
>> > like "move: 3 cms" or "move: 30 degrees" will depend not only on the
>> > receiver but also on the class of the argument. This would need double
>> > dispatch (aka multiple polymorphism). The first dispatch would be
>> > based on the receiver and the receiver's method would then dispatch it
>> > based on the class of the argument (i.e. Distance>>move or Angle>>move )
>> >
>> > HTH .. Subbu
>> >
>> >
>>
>>
>> hmm, still stuck
>>
>> I have now a class Direction with as instance variables north, south,
>> east, west
>> and made the accessors.
>>
>> then I thought I need a initialize like this :
>>
>> initialize
>>     north = Direction( 0, -1).
>>     east  = Direction( 1,  0).
>>     south = Direction( 0,  1).
>>     west  = Direction(-1,  0).
>>
>> but the Direction (0,-1)  is a problem . the compiler does not like the
>> (0,-1) part
>>
>> to give you the big picture. I have a Robot which can turnRight ,
>> turnLeft and moveForward and I try to understand how the page would work
>> in my case.
>>
>> So I have a object Direction as described above and a Object MoveForward
>> which is a subobject of Direction.
>> MoveForward has only 1 method :
>>
>> IsMove
>>     ^  'A'
>>
>> Roelof
>>
>>
>>
>

Reply via email to