Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Roelof Wobben

  
  
Thanks, 
  
  for the discusson and lessons. 
  
  I will think about it and also think if smalltalk is for me. 
  I did the pharo Mooc and still have a lot of problems making the
  smalltalk way click in my head so I can solve little problems like
  this.
  
  Out of coriousy what dialect do you use?
  
  
  Op 8-4-2019 om 17:11 schreef Richard O'Keefe:


  
  

  You are expected to
use my code fragments for *ideas*,
  not to incorporate
them *literally* in your code.  As
  I explained,
*without seeing the specification*, I have
  no way to tell
whether the specification uses a left-handed
  or right-handed
coordinate system.
  
  
  For what it's worth,
here's a complete program in my
  Smalltalk dialect. 
It doesn't plug into the exercism
  testing framework
because I can do not know what it
  looks like.  But if
it makes the code more complicated
  that this, it's
doing it wrong.
  
  
  require: 'geometry.st' 
"Point"
require: 'print.st'
"OutputStream>>print:"
    
Object subclass: #Robot
  instanceVariableNames: 'position direction'
  poolDirectionaries:    'FileStream'

  methods for: 'initialising'
    pvtPostNew
  position  := 0@0.
  direction := 1@0.

  methods for: 'accessing'
    direction
  ^direction copy

    location
  ^location copy

    obey: commands
  commands do: [:each |
    each caseOf: {
  [$A] -> [position  := position  + direction].
  [$L] -> [direction := direction leftRotated].
  [$R] -> [direction := direction rightRotated]
    }].

  class methods for: 'main'
    start
  [StdIn atEnd] whileFalse: [
 |robot|
 robot := Robot new.
 Robot obey: StdIn nextLine.
 StdOut print: Robot location; cr].
  

  
  
  
On Tue, 9 Apr 2019 at 02:58,
  Roelof Wobben  wrote:


  
yes, 
  this is a real  tests from the pharo track on exercism.io
  
  I understand what you mean but maybe I overthinking
  things. 
  But if we have a robot facing north and the robot turns to
  the left  , im my oponion it faces now to the east. 
  
  like this test is saying : 
  
test04_RotatesTheRobotsDirection90DegreesClockwiseChangesTheDirectionFromEastToSouth
      | result |
      result := robotSimulatorCalculator
          moveDirection: 'east'
          position:
              (Dictionary new
                  add: 'x' -> 0;
                  add: 'y' -> 0;
                  yourself)
          instructions: 'R'.
      self
          assert: result
          equals:
              (Dictionary new
                  add: 'direction' -> 'south';
                  add:
                      'position'
                          ->
                              (Dictionary new
                                  add: 'x' -> 0;
                                  add: 'y' -> 0;
                                  yourself);
                  yourself)
  
  
  but I cannot come to the same outcome with this code : 
  
  
  pointToName:
aPoint
    ^aPoint x
isZero
   ifTrue: 
[aPoint y > 0 ifTrue: [#north] ifFalse: [#south]]
   ifFalse:
[aPoint x > 0 ifTrue: [#west ] ifFalse: [#east ]]


maybe exercism.io is not a good
way to practice and learn smalltalk but I found not a
better one. or smalltalk is not for me. 

Roelof






  
  
  
  
  
  
  Op 8-4-2019 om 16:44 schreef 

Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Richard O'Keefe
You are expected to use my code fragments for *ideas*,
not to incorporate them *literally* in your code.  As
I explained, *without seeing the specification*, I have
no way to tell whether the specification uses a left-handed
or right-handed coordinate system.

For what it's worth, here's a complete program in my
Smalltalk dialect.  It doesn't plug into the exercism
testing framework because I can do not know what it
looks like.  But if it makes the code more complicated
that this, it's doing it wrong.

require: 'geometry.st'  "Point"
require: 'print.st' "OutputStream>>print:"

Object subclass: #Robot
  instanceVariableNames: 'position direction'
  poolDirectionaries:'FileStream'

  methods for: 'initialising'
pvtPostNew
  position  := 0@0.
  direction := 1@0.

  methods for: 'accessing'
direction
  ^direction copy

location
  ^location copy

obey: commands
  commands do: [:each |
each caseOf: {
  [$A] -> [position  := position  + direction].
  [$L] -> [direction := direction leftRotated].
  [$R] -> [direction := direction rightRotated]
}].

  class methods for: 'main'
start
  [StdIn atEnd] whileFalse: [
 |robot|
 robot := Robot new.
 Robot obey: StdIn nextLine.
 StdOut print: Robot location; cr].

On Tue, 9 Apr 2019 at 02:58, Roelof Wobben  wrote:

> yes,  this is a real  tests from the pharo track on exercism.io
>
> I understand what you mean but maybe I overthinking things.
> But if we have a robot facing north and the robot turns to the left  , im
> my oponion it faces now to the east.
>
> like this test is saying :
>
>
> test04_RotatesTheRobotsDirection90DegreesClockwiseChangesTheDirectionFromEastToSouth
> | result |
> result := robotSimulatorCalculator
> moveDirection: 'east'
> position:
> (Dictionary new
> add: 'x' -> 0;
> add: 'y' -> 0;
> yourself)
> instructions: 'R'.
> self
> assert: result
> equals:
> (Dictionary new
> add: 'direction' -> 'south';
> add:
> 'position'
> ->
> (Dictionary new
> add: 'x' -> 0;
> add: 'y' -> 0;
> yourself);
> yourself)
>
>
> but I cannot come to the same outcome with this code :
>
>
> pointToName: aPoint
>   ^aPoint x isZero
>  ifTrue:  [aPoint y > 0 ifTrue: [#north] ifFalse: [#south]]
>  ifFalse: [aPoint x > 0 ifTrue: [#west ] ifFalse: [#east ]]
>
>
> maybe exercism.io is not a good way to practice and learn smalltalk but I
> found not a better one. or smalltalk is not for me.
>
> Roelof
>
>
>
>
>
>
>
>
>
>
>
> Op 8-4-2019 om 16:44 schreef Richard O'Keefe:
>
> The basic issue here is abstraction.
> An instance of "Robot" in your program is not a
> physical object.  How could it possibly point North,
> South, or Nor-nor-west?  It cannot.
> Its location and direction are abstract values
> *metaphorically* related to real world notions
> like position vectors and velocity vectors.
> "North" in this program is not a real thing,
> it is an *idea* which could be represented by
> 'North', 'north', #North, #north, $N, $n,
> 'Raki',  'raki',  #Raki,  #raki,  $R, $r,
> 137, (0@ -1), a picture of the star Polaris,
> the colour red (the conventional colour for
> that end of a compass needle which points north),
> a sound recording of a lecture by Alfred North
> Whitehead, or anything you please, as long as,
> inside the program, it *acts* the way *you* want
> "north" to act (which is not necessarily the way
> the physical direction North acts, and in fact in
> this case it most certainly is not).
>
> Locations and movements in a 2D space are, in Smalltalk,
> commonly represented by Points.  "Represented by."
>
> As for this method:
>
>
> test11_MovesTheRobotForward1SpaceInTheDirectionItIsPointingIncreasesTheYCoordinateOneWhenFacingNorth
> | result |
> result := robotSimulatorCalculator
> moveDirection: 'north'
> position:
> (Dictionary new
> add: 'x' -> 0;
> add: 'y' -> 0;
> yourself)
> instructions: 'A'.
> self
> assert: result
> equals:
> (Dictionary new
> add: 'direction' -> 'north';
> add:
> 'position'
> ->
> (Dictionary new
> add: 'x' -> 0;
> add: 'y' -> 1;
> yourself);
> yourself)
>
> PLEASE tell me that is not what they are actually using.
> Let's start with
>   (Dictionary new)
>  add: k1 -> v1;
>  ...
>  add: kn -> vn;
>  yourself
> Did you know that 

Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Roelof Wobben

  
  
yes,  this is a real  tests from the
  pharo track on exercism.io
  
  I understand what you mean but maybe I overthinking things. 
  But if we have a robot facing north and the robot turns to the
  left  , im my oponion it faces now to the east. 
  
  like this test is saying : 
  
test04_RotatesTheRobotsDirection90DegreesClockwiseChangesTheDirectionFromEastToSouth
      | result |
      result := robotSimulatorCalculator
          moveDirection: 'east'
          position:
              (Dictionary new
                  add: 'x' -> 0;
                  add: 'y' -> 0;
                  yourself)
          instructions: 'R'.
      self
          assert: result
          equals:
              (Dictionary new
                  add: 'direction' -> 'south';
                  add:
                      'position'
                          ->
                              (Dictionary new
                                  add: 'x' -> 0;
                                  add: 'y' -> 0;
                                  yourself);
                  yourself)
  
  
  but I cannot come to the same outcome with this code : 
  
  
  pointToName:
aPoint
   
^aPoint x isZero
  
ifTrue:  [aPoint y > 0 ifTrue: [#north] ifFalse: [#south]]
  
ifFalse: [aPoint x > 0 ifTrue: [#west ] ifFalse: [#east ]]


maybe exercism.io is not a good way to practice and learn
smalltalk but I found not a better one. or smalltalk is not for
me. 

Roelof






  
  
  
  
  
  
  Op 8-4-2019 om 16:44 schreef Richard O'Keefe:


  
  
The basic issue here
  is abstraction.
An instance of "Robot"
  in your program is not a
physical object.  How
  could it possibly point North,
South, or
  Nor-nor-west?  It cannot.
Its location and
  direction are abstract values
*metaphorically*
  related to real world notions
like position vectors
  and velocity vectors.
"North" in this
  program is not a real thing,
it is an *idea* which
  could be represented by
'North', 'north',
  #North, #north, $N, $n,
'Raki',  'raki', 
  #Raki,  #raki,  $R, $r,
137, (0@ -1), a
  picture of the star Polaris,
the colour red (the
  conventional colour for
that end of a compass
  needle which points north),
a sound recording of a
  lecture by Alfred North
Whitehead, or anything
  you please, as long as,
inside the program, it
  *acts* the way *you* want
"north" to act (which
  is not necessarily the way
the physical direction
  North acts, and in fact in
this case it most
  certainly is not).


Locations and
  movements in a 2D space are, in Smalltalk,
commonly represented
  by Points.  "Represented by."


As for this method:


test11_MovesTheRobotForward1SpaceInTheDirectionItIsPointingIncreasesTheYCoordinateOneWhenFacingNorth
      | result |
      result := robotSimulatorCalculator
          moveDirection: 'north'
          position:
              (Dictionary new
                  add: 'x' -> 0;
                  add: 'y' -> 0;
                  yourself)
          instructions: 'A'.
      self
          assert: result
          equals:
              (Dictionary new
                  add: 'direction' -> 'north';
                  add:
                      'position'
                          ->
                              (Dictionary new
                                  add: 'x' -> 0;
                                  add: 'y' -> 1;
                                  yourself);
                  yourself)


PLEASE tell me that is
  not what they are actually using.
Let's start with
  (Dictionary new)
 add: k1 -> v1;
 ...
 add: kn -> vn;
 yourself
Did you know that
  sending #add: to a dictionary is not
portable?  Storing
  actual Association objects inside
Dictionaries was
  originally an encapsulation error and
remains a performance
  error, so there are Smalltalks
that do not make that
  mistake.  The *portable* way to
make a Dictionary is
    

Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Richard O'Keefe
The basic issue here is abstraction.
An instance of "Robot" in your program is not a
physical object.  How could it possibly point North,
South, or Nor-nor-west?  It cannot.
Its location and direction are abstract values
*metaphorically* related to real world notions
like position vectors and velocity vectors.
"North" in this program is not a real thing,
it is an *idea* which could be represented by
'North', 'north', #North, #north, $N, $n,
'Raki',  'raki',  #Raki,  #raki,  $R, $r,
137, (0@ -1), a picture of the star Polaris,
the colour red (the conventional colour for
that end of a compass needle which points north),
a sound recording of a lecture by Alfred North
Whitehead, or anything you please, as long as,
inside the program, it *acts* the way *you* want
"north" to act (which is not necessarily the way
the physical direction North acts, and in fact in
this case it most certainly is not).

Locations and movements in a 2D space are, in Smalltalk,
commonly represented by Points.  "Represented by."

As for this method:

test11_MovesTheRobotForward1SpaceInTheDirectionItIsPointingIncreasesTheYCoordinateOneWhenFacingNorth
| result |
result := robotSimulatorCalculator
moveDirection: 'north'
position:
(Dictionary new
add: 'x' -> 0;
add: 'y' -> 0;
yourself)
instructions: 'A'.
self
assert: result
equals:
(Dictionary new
add: 'direction' -> 'north';
add:
'position'
->
(Dictionary new
add: 'x' -> 0;
add: 'y' -> 1;
yourself);
yourself)

PLEASE tell me that is not what they are actually using.
Let's start with
  (Dictionary new)
 add: k1 -> v1;
 ...
 add: kn -> vn;
 yourself
Did you know that sending #add: to a dictionary is not
portable?  Storing actual Association objects inside
Dictionaries was originally an encapsulation error and
remains a performance error, so there are Smalltalks
that do not make that mistake.  The *portable* way to
make a Dictionary is
(Dictionary new)
   at: k1 put: v1;
   ...
   at: kn put: vn;
   yourself.

And why in the name of sanity are the keys *strings*
instead of *symbols*?  This is not Smalltalk.  It is
Javascript in drag.

Now exercism.io has a habit of insisting on particular
implementations.  For example, I completed the SML track,
and found that the test code ONLY worked with Poly and
not with any of the three SML implementations I already
had on my machine.  Since you are doing this in Pharo,
I take it that exercism.io will insist on the Smalltalk
track being done in Pharo, and in that case it is
*nauseating* to use a Dictionary when you could use a
Point.  Old-fashioned Smalltalk style would have been
to return something like
   #(  )
e.g. #(north 1 0), and I still prefer that.

In fact *good* Smalltalk style for something like this
would be
test11_MovesTheRobotForward1SpaceInTheDirectionItIsPointingIncreasesTheYCoordinateOneWhenFacingNorth
  robotSimulatorCalculator
moveTo: 0@0;
head: #north;
obey: 'A'.
  self assert: robotSimulatorCalculator heading equals: #north.
  self assert: robotSimulatorCalculator location equals: 0@1.

-- We're starting to get the idea that identifiers like
robotSimulatorCalculator are not a very good idea when
simulatedRobot would do the job as well or better.

(This is also pointing us towards Betrand Meyer's
Command/Query Separation principle, but we shan't
go there today.)

This is important feedback to give to the exercism.io
people.  The test code should use a SMALLTALK interface,
not a warmed-over JAVASCRIPT interface.

Now, how do we map between direction *names* and
direction *points*?  Well, we have to start by
laying down clearly what we *mean* by the directions.

To move North one step is to add 1 to y and 0 to x.
(We know that from the appalling test case above.)
To move South one step is to add -1 to y and 0 to x.
(South is the opposite of North.)
To move East one step, oh we have a problem.
THIS NEEDS SPELLING OUT.  And one of the things the
exercism.io exercises are HORRIBLY BAD AT is specifying
the problem.  Nearly every single exercise I have tried,
I have been unable to tell what the problem is without
examining the test cases, and that is not the way
exercises are supposed to work.  (Yeah, that's why I'm
screaming about it.  I've taught a class using exercises
like this that were not of my writing and vague specifications
really upset the students.  People who had taken the class
under someone else several years before were still angry
about it.)

The geometric classes in Smalltalk were written to support
graphic user interfaces.  And in user interfaces, the y
coordinate increases DOWN.  So if we take the compass rose
and rotate it so that North is 

Re: [Pharo-users] How to catch and handle multiple exceptions

2019-04-08 Thread Esteban Maringolo
Maybe the abstraction needed wraps everything within a single handler,
but internally does a switch like statement dispatching to a
particular error handler block.

handledBlock
  exceptionDispatcher
on: NotFoundError do: [:ex | ...];
on: MessageNotUnderstood do: [:ex | .. ].

BlockClosure>>exceptionDispatcher

| exceptionDispatcher|
exceptionDispatcher:= ExceptionDispatcher new.
self on: Exception do: [:ex | dispatcher handle: ex ].
^exceptionDispatcher


ExceptionDispatcher>>on: exceptionClass do: aBlock
  self handlers add: exceptionClass -> aBlock

The #exceptionDispatcher method would return this special object that
deals with the resolution of each exception class (how to sort them
would't be trivial unless done naively). But any resignalling would be
only one level deep.

Disclaimer: I just wrote the code as I replied this email, not
guaranteed to work :)


Esteban A. Maringolo

El lun., 8 abr. 2019 a las 10:09, jtuc...@objektfabrik.de
() escribió:
>
> Am 08.04.19 um 14:39 schrieb Richard O'Keefe:
>
>
>> >
>> > It's easy enough to add your own methods like
>> > on: exn1 do: act1 on: exn2 do: act2
>> > "An imperfect emulation of VAST's #when:do:when:do:"
>> > ^[self on: exn1 do: act1] on: exn2 do: act2
>> >
>> > on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
>> > "An imperfect emulation of VAST's #when:do:when:do:when:do:"
>> > ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
>> > to BlockClosure.  It won't be fast, but your code might be
>> > clearer.
>
> well, an unwanted side effect might be that the handling of exn1 is also 
> guarded by the outer on:do: .
>
> Not that this has to be a problem but it introduces new things to think about 
> when you want to #resignalAs: and such.
>
>
> --
> ---
> Objektfabrik Joachim Tuchel  mailto:jtuc...@objektfabrik.de
> Fliederweg 1 http://www.objektfabrik.de
> D-71640 Ludwigsburg  http://joachimtuchel.wordpress.com
> Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1
>
>



Re: [Pharo-users] How to catch and handle multiple exceptions

2019-04-08 Thread jtuc...@objektfabrik.de

Am 08.04.19 um 14:39 schrieb Richard O'Keefe:


>
> It's easy enough to add your own methods like
> on: exn1 do: act1 on: exn2 do: act2
>     "An imperfect emulation of VAST's #when:do:when:do:"
>     ^[self on: exn1 do: act1] on: exn2 do: act2
>
> on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
>     "An imperfect emulation of VAST's #when:do:when:do:when:do:"
>     ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> to BlockClosure.  It won't be fast, but your code might be
> clearer.

well, an unwanted side effect might be that the handling of exn1 is also 
guarded by the outer on:do: .


Not that this has to be a problem but it introduces new things to think 
about when you want to #resignalAs: and such.



--
---
Objektfabrik Joachim Tuchel  mailto:jtuc...@objektfabrik.de
Fliederweg 1 http://www.objektfabrik.de
D-71640 Ludwigsburg  http://joachimtuchel.wordpress.com
Telefon: +49 7141 56 10 86 0 Fax: +49 7141 56 10 86 1




Re: [Pharo-users] How to catch and handle multiple exceptions

2019-04-08 Thread Tim Mackinnon
Thanks Richard - indeed it was that VisualAge Smalltalk pattern that I was 
remembering and looking for in Pharo, and was a bit surprised it wasn’t there - 
and hence thought there’re was possibly a different way.

 I might propose we add this, if no-one else comes up with a better 
alternative. Handling both application and http exceptions is quite a common 
pattern - and you don’t always want to do the same blanket thing.

Tim


Sent from my iPhone

> On 8 Apr 2019, at 04:48, Richard O'Keefe  wrote:
> 
> VisualAge Smalltalk has, in addition to the standard #on:do:,
> #when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
> with the last four mapping to #whenOneOf:doMatching:, taking
> two arrays.
> 
> It's easy enough to add your own methods like
> on: exn1 do: act1 on: exn2 do: act2
> "An imperfect emulation of VAST's #when:do:when:do:"
> ^[self on: exn1 do: act1] on: exn2 do: act2
> 
> on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
> "An imperfect emulation of VAST's #when:do:when:do:when:do:"
> ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> to BlockClosure.  It won't be fast, but your code might be
> clearer.
> 
> 
>> On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon  wrote:
>> 
>> Thanks, I guess that makes sense, although it somehow looks a bit ugly with 
>> the nested brackets.. but nothing else springs to mind so maybe I’ll get 
>> used to it (and In my case I think it’s likely 2 or 3 different exceptions)
>> 
>> Tim
>> 
>> Sent from my iPhone
>> 
>> > On 7 Apr 2019, at 20:43, Richard Sargent 
>> >  wrote:
>> > 
>> > 
>> > This last one.
>> > 
>> > [[self run]
>> > on: TestFailure
>> > do: [:testEx | ...]]
>> > on: Error
>> > do: [:error | ...]


Re: [Pharo-users] How to catch and handle multiple exceptions

2019-04-08 Thread Richard O'Keefe
It won't be fast because it creates multiple blocks,
whereas a "native" version would not.
To be honest I have not implemented exceptions in my
Smalltalk yet, but I want to inline []on:do: constructions.
The VAST system I have is 8.6.3, and it supports ANSI
Exceptions.

On Tue, 9 Apr 2019 at 00:31, Esteban Maringolo  wrote:

> Richard,
>
> I was going to comment the #when:do:[when:do:] approach of VAST [1].
>
> Why do you say it won't be fast? Because of the multiple exception
> handlers in the call stack?
>
> I think that some construct might be used to obtain the same as the
> #when:do:when:do: but using a chained approach instead.
>
> Regards,
>
> [1] AFAIR when I used VAST (+a decade ago) it didn't have "ANSI"
> exceptions.
>
> Esteban A. Maringolo
>
> El lun., 8 abr. 2019 a las 0:49, Richard O'Keefe ()
> escribió:
> >
> > VisualAge Smalltalk has, in addition to the standard #on:do:,
> > #when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
> > with the last four mapping to #whenOneOf:doMatching:, taking
> > two arrays.
> >
> > It's easy enough to add your own methods like
> > on: exn1 do: act1 on: exn2 do: act2
> > "An imperfect emulation of VAST's #when:do:when:do:"
> > ^[self on: exn1 do: act1] on: exn2 do: act2
> >
> > on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
> > "An imperfect emulation of VAST's #when:do:when:do:when:do:"
> > ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> > to BlockClosure.  It won't be fast, but your code might be
> > clearer.
> >
> >
> > On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon  wrote:
> >>
> >>
> >> Thanks, I guess that makes sense, although it somehow looks a bit ugly
> with the nested brackets.. but nothing else springs to mind so maybe I’ll
> get used to it (and In my case I think it’s likely 2 or 3 different
> exceptions)
> >>
> >> Tim
> >>
> >> Sent from my iPhone
> >>
> >> > On 7 Apr 2019, at 20:43, Richard Sargent <
> richard.sarg...@gemtalksystems.com> wrote:
> >> >
> >> >
> >> > This last one.
> >> >
> >> > [[self run]
> >> > on: TestFailure
> >> > do: [:testEx | ...]]
> >> > on: Error
> >> > do: [:error | ...]
> >>
> >>
>
>


Re: [Pharo-users] How to catch and handle multiple exceptions

2019-04-08 Thread Esteban Maringolo
Richard,

I was going to comment the #when:do:[when:do:] approach of VAST [1].

Why do you say it won't be fast? Because of the multiple exception
handlers in the call stack?

I think that some construct might be used to obtain the same as the
#when:do:when:do: but using a chained approach instead.

Regards,

[1] AFAIR when I used VAST (+a decade ago) it didn't have "ANSI" exceptions.

Esteban A. Maringolo

El lun., 8 abr. 2019 a las 0:49, Richard O'Keefe () escribió:
>
> VisualAge Smalltalk has, in addition to the standard #on:do:,
> #when:do:, ..., #when:do:#when:do:#when:do:#when:do:#when:do:,
> with the last four mapping to #whenOneOf:doMatching:, taking
> two arrays.
>
> It's easy enough to add your own methods like
> on: exn1 do: act1 on: exn2 do: act2
> "An imperfect emulation of VAST's #when:do:when:do:"
> ^[self on: exn1 do: act1] on: exn2 do: act2
>
> on: exn1 do: act1 on: exn2 do: act2 on: exn3 do: act3
> "An imperfect emulation of VAST's #when:do:when:do:when:do:"
> ^[[self on: exn1 do: act1] on: exn2 do: act2] on: exn3 do: act3
> to BlockClosure.  It won't be fast, but your code might be
> clearer.
>
>
> On Mon, 8 Apr 2019 at 10:21, Tim Mackinnon  wrote:
>>
>>
>> Thanks, I guess that makes sense, although it somehow looks a bit ugly with 
>> the nested brackets.. but nothing else springs to mind so maybe I’ll get 
>> used to it (and In my case I think it’s likely 2 or 3 different exceptions)
>>
>> Tim
>>
>> Sent from my iPhone
>>
>> > On 7 Apr 2019, at 20:43, Richard Sargent 
>> >  wrote:
>> >
>> >
>> > This last one.
>> >
>> > [[self run]
>> > on: TestFailure
>> > do: [:testEx | ...]]
>> > on: Error
>> > do: [:error | ...]
>>
>>



Re: [Pharo-users] Iceberg for files other than code?

2019-04-08 Thread Konrad Hinsen
Hi Tim,

> Hi Konrad - I think you can do what you describe - I think the
> ICeRepository entry for your project will have the path you want.

Indeed. Here's how to get the repository for class MyClass:

  repo := IceRepository registeredRepositoryIncludingPackage: MyClass
package.

And then the path ist just

  repo location.

> And yes, its the committing back non source files where iceberg
> doesn’t try to do anything (and so needs help from elsewhere).

>From what I saw so far it looks possible to change a file and do a
commit from Pharo code, bypassing the Iceberg UI. For some uses that
may be OK.

Konrad.



Re: [Pharo-users] can I do something like this with Double Dispatch

2019-04-08 Thread Roelof Wobben

  
  
it is almost the same. 
  
  here exercism challenge looks like this : 
  
  Scoring Bowling
  The game consists of 10 frames. A frame is composed of one or
two ball
throws with 10 pins standing at frame initialization. There are
three
cases for the tabulation of a frame.
  

  An open frame is where a score of less than 10 is recorded
for the
frame. In this case the score for the frame is the number of
pins
knocked down.


  A spare is where all ten pins are knocked down by the
second
throw. The total value of a spare is 10 plus the number of
pins
knocked down in their next throw.


  A strike is where all ten pins are knocked down by the
first
throw. The total value of a strike is 10 plus the number of
pins
knocked down in the next two throws. If a strike is
immediately
followed by a second strike, then the value of the first
strike
cannot be determined until the ball is thrown one more time.

  
  Here is a three frame example:
  

  
Frame 1
Frame 2
Frame 3
  


  
X (strike)
5/ (spare)
9 0 (open frame)
  

  
  Frame 1 is (10 + 5 + 5) = 20
  Frame 2 is (5 + 5 + 9) = 19
  Frame 3 is (9 + 0) = 9
  This means the current running total is 48.
  The tenth frame in the game is a special case. If someone
throws a
strike or a spare then they get a fill ball. Fill balls exist to
calculate the total of the 10th frame. Scoring a strike or spare
on
the fill ball does not give the player more fill balls. The
total
value of the 10th frame is the total number of pins knocked
down.
  For a tenth frame of X1/ (strike and a spare), the total value
is 20.
  For a tenth frame of XXX (three strikes), the total value is
30.
  Requirements
  Write code to keep track of the score of a game of bowling. It
should
support two operations:
  

  roll(pins : int) is called each time the player
  rolls a ball. The
  argument is the number of pins knocked down.

  score() : int is called only at the very end of
  the game. It
  returns the total score for that game.
  
  
  and the input is like this :  
  
  test05_ConsecutiveSparesEachGetAOneRollBonus
      | result |
      result := bowlingCalculator
          scoreAfterRolling: #(5 5 3 7 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  0).
      self assert: result equals: 31
  
  Roelof
  
  
  
  
  Op 8-4-2019 om 11:43 schreef Richard O'Keefe:


  
  

  Remember, we cannot
see the Smalltalk exercises in exercism.
  We cannot help you
without knowing what problem you are
  trying to solve.  Is
this problem basically the same as
  https://www.reddit.com/r/dailyprogrammer/comments/3ntsni/20151007_challenge_235_intermediate_scoring_a/?ref=share_source=link
  or is it different?
  
  
  
  Double dispatch is a
programming technique,
  not an end in
itself.
  
  
  A weird thing about
the exercism site is that you can
  see *solutions* to
problems for a language even if you
  cannot see the
*problems* themselves.  So I have seen
  *solutions* to
Bowling in several languages; some with
  no objects at all,
and some using single dispatch only.
  This is a 'medium'
problem, meaning the solution is
  maybe 2 or 3 pages.
  
  
  KEEP IT SIMPLE.
  Not every *concept*
needs to be a *class*.
  
  

  
  
  
On Sat, 6 Apr 2019 at 21:53,
  Roelof Wobben  wrote:

Hello,
  
  Just thinking how to solve the bowling challenge from
  exercism.
  
  but I wonder if I can do something like this in the method
  that checks 
  if I have the right object
  
  I was thinking about this :
  
  Result
  -- Strike
  -- Spare
  -- allOther
  
  then In  Strike something like this
  
  checkForBonus: number1 score2: number2
     ^ number1 + number2 == 10
  
  or am I thinking the totally 

Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Roelof Wobben

  
  
Richard thanks. 
  
  One thing I do not see direct. 
  
  you said : 
  
  
  
  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 me a direction is the direction the robot is facing so
something like north or east. 

the challenge also wants a output like this : 

test11_MovesTheRobotForward1SpaceInTheDirectionItIsPointingIncreasesTheYCoordinateOneWhenFacingNorth
    | result |
    result := robotSimulatorCalculator
        moveDirection: 'north'
        position:
            (Dictionary new
                add: 'x' -> 0;
                add: 'y' -> 0;
                yourself)
        instructions: 'A'.
    self
        assert: result
        equals:
            (Dictionary new
                add: 'direction' -> 'north';
                add:
                    'position'
                        ->
                            (Dictionary new
                                add: 'x' -> 0;
                                add: 'y' -> 1;
                                yourself);
                yourself)

so how do I "convert" the point you are using to the text. 

Or do I misunderstood you somewhere wrong. 

Roelof

  
  
  
  
  Op 8-4-2019 om 10:57 schreef Richard O'Keefe:


  
  
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 

Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Roelof Wobben

  
  
Op 8-4-2019 om 10:57 schreef Richard
  O'Keefe:


  
  
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  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
  
  
  
  
  
  

Re: [Pharo-users] can I do something like this with Double Dispatch

2019-04-08 Thread Richard O'Keefe
Remember, we cannot see the Smalltalk exercises in exercism.
We cannot help you without knowing what problem you are
trying to solve.  Is this problem basically the same as
https://www.reddit.com/r/dailyprogrammer/comments/3ntsni/20151007_challenge_235_intermediate_scoring_a/?ref=share_source=link
or is it different?

Double dispatch is a programming technique,
not an end in itself.

A weird thing about the exercism site is that you can
see *solutions* to problems for a language even if you
cannot see the *problems* themselves.  So I have seen
*solutions* to Bowling in several languages; some with
no objects at all, and some using single dispatch only.
This is a 'medium' problem, meaning the solution is
maybe 2 or 3 pages.

KEEP IT SIMPLE.
Not every *concept* needs to be a *class*.


On Sat, 6 Apr 2019 at 21:53, Roelof Wobben  wrote:

> Hello,
>
> Just thinking how to solve the bowling challenge from exercism.
>
> but I wonder if I can do something like this in the method that checks
> if I have the right object
>
> I was thinking about this :
>
> Result
> -- Strike
> -- Spare
> -- allOther
>
> then In  Strike something like this
>
> checkForBonus: number1 score2: number2
>^ number1 + number2 == 10
>
> or am I thinking the totally wrong way to solve this?
>
> Roelof
>
>
>
>


Re: [Pharo-users] difference between double dispatch and the method explains here

2019-04-08 Thread Richard O'Keefe
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  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  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