Very elegant, Alistair!

Even though I don't play bowling and I didn't participate in the exercise, I
followed it closely.  The dynamics of quest for simplicity and refactoring
reflect my own experience in quite a few cases.

> I felt pangs for the lack of ++ and 'break'

This feeling is quite common for people that come from Fortran and C kind of
languages (I was one), but Smalltalk has its own approaches and
justifications.

The break issue can be solved in two different ways:

1.    Using the whileTrue <whileFalse> family of methods (there are a few of
those) in the BlockClosure class.  It looks something like this:

[ something that evaluates to a Boolean ] whileTrue, or
[ something else that evaluates to a Boolean ]
    whileTrue: [ do something ]   , or

2.  Create your own method for the loop, with a return when a given
condition happens.  This approach also works with the other languages, and
in some cases it's also more elegant than break because it helps in
compartmentalizing larger methods and making them more readable.

The ++ is really bothersome for C people, yet it introduces ireadability to
the code.  So, Smalltalk is a little more verbose, but that's not
necessarily bad.


> I got similar, but in Smalltalk, after I finally gave up with
> objects (massive) ...

It is worth mentioning that in Smalltalk [ST] /everything/ (almost) is an
object, including methods and local variables.  People trained in
identifying objects with nouns have some trouble seeing that in ST nouns are
only a first approximation.  You didn't give up objects, you just threw out
superfluous objects.  You created a method (itself an object) that can be
introduced as a behavior of some other object (probably a noun) in a more
comprehensive system.  A candidate in this case could be the instance side
of the class BowlingGame.

> I got similar, but in Smalltalk, after I finally gave up with
> ... and TDD (clunky)

The Smalltalk workspace allows to do a lot of experimentation before or in
parallel with TDD.  VisualWorks ST has a great refactoring browser, where it
is a pleasure doing TDD.  Yet, in my view, the main reason to use TDD for
small projects is as a practice or illustration in preparation for larger
projects.  On the other hand, you never know when a small project may evolve
into a large project, and it's good to develop the self discipline to use
TDD.

Victor

============================


----- Original Message ----- 
From: "aacockburn" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Saturday, December 25, 2004 9:22 PM
Subject: Re: [XP] New Article - BowlingForSmalltalkV - a small procedural
example


>
>
> I got similar, but in Smalltalk, after I finally gave up with
> objects (massive) and TDD (clunky) and just sat down and
> worked out the algorithm. ... well, more exactly, after I
> stared long and hard at the clunky code and optimized it for
> a long time and then recognized the algorithm I might have
> ever thought up, and then worked on it some more (at which
> point the tests were great, since I broke it about every other
> time that I edited the thing). But it's still the one I like
> best, and it's similar to yours, only in Smalltalk ( where
> I felt pangs for the lack of ++ and 'break', which I had
> planned to use). Here's the Smalltalk.
>
> score: rolls
>
>   | score frameStart |
>   score := 0.
>   frameStart := 1.
>
>   10 timesRepeat: [  | roll1 roll2  open spare strike |
>     roll1 := rolls at: frameStart.
>     roll2 := rolls at: frameStart + 1.
>     open := roll1 + roll2 < 10.
>     spare := (roll1 < 10)   and:  (roll1 + roll2 = 10).
>     strike := roll1 = 10.
>
>     score := score + roll1 + roll2.
>     ( spare or: strike )
>       ifTrue: [ score := score + (rolls at: frameStart + 2)].
>
>     ( open or: spare ) ifTrue:  [ frameStart := frameStart + 2 ].
>     ( strike ) ifTrue:  [ frameStart := frameStart + 1 ].
>   ].
>   ^score
>
>
>
>
> --- In [EMAIL PROTECTED], "Jeff Grigg"
> <[EMAIL PROTECTED]> wrote:
> > And this is what I get:
> >
> >
> >    public int scoreBowlingGame(final int[] rolls)
> >    {
> >       final int framesInGame = 10;
> >       final int pinsInFrame = 10;
> >
> >       int totalScore = 0;
> >       int rollIndex = 0;
> >       for (int frame = 1; frame <= framesInGame; ++frame) {
> >          int firstRoll = rolls[rollIndex++];
> >          totalScore += firstRoll;
> >
> >          if (firstRoll == pinsInFrame) {   // Strike
> >             totalScore += rolls[rollIndex] + rolls[rollIndex + 1];
> >          }
> >          else {
> >             int secondRoll = rolls[rollIndex++];
> >             totalScore += secondRoll;
> >
> >             if (firstRoll + secondRoll == pinsInFrame) {   // Spare
> >                totalScore += rolls[rollIndex];
> >             }
> >          }
> >       }
> >
> >       return totalScore;
> >    }
> >
> >
> > Nice.  Minimal assumptions.  Short.  Sweet.
> >
> > (It was ugly for a while:  I started with a loop on rolls.  Then I
> > had to count frames.  Then I made it loop on frames.  This left
> > the 'for' statement a mix of roll indexes and a frame test.  Ick.
> > So I refactored the roll index and frame counting stuff to get
> > closer to idiomatic usage.  And that got me here.)
>
>
>
>
>
>
> To Post a message, send it to:   [EMAIL PROTECTED]
>
> To Unsubscribe, send a blank message to:
[EMAIL PROTECTED]
>
> ad-free courtesy of objectmentor.com
> Yahoo! Groups Links
>
>
>
>
>
>
>



To Post a message, send it to:   [EMAIL PROTECTED]

To Unsubscribe, send a blank message to: [EMAIL PROTECTED]

ad-free courtesy of objectmentor.com 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/extremeprogramming/

<*> To unsubscribe from this group, send an email to:
    [EMAIL PROTECTED]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Reply via email to