Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bowling Game once more

25 views
Skip to first unread message

ig...@yahoo.com

unread,
Dec 26, 2004, 2:09:38 PM12/26/04
to
Another December, another series of Bowling game articles
http://www.xprogramming.com/xpmag/index.htm

And the same question, why do the programs model a bowling-game rather
than model scoring-a-bowling-game? (Why the insistence on a frame
object?)

Ron Jeffries

unread,
Dec 27, 2004, 5:18:28 PM12/27/04
to

Well, not all the designs do have a frame object, so there's hardly
any "insistence". But many of them do, because that's the way the
designs feel right to me. If you'd like to present one of your own
preference, I'd be happy to publish the article.

I'd prefer that the article use the same spec, but if you think a
different spec would be more interesting, let 'er rip!

--
Ron Jeffries
www.XProgramming.com
I'm giving the best advice I have. You get to decide if it's true for you.

ig...@yahoo.com

unread,
Dec 27, 2004, 5:42:06 PM12/27/04
to
Is the point to model a bowling-game or to model scoring-a-bowling-game?

ig...@yahoo.com

unread,
Dec 27, 2004, 5:42:16 PM12/27/04
to

SP

unread,
Dec 27, 2004, 10:26:55 PM12/27/04
to
<ig...@yahoo.com> wrote in message
news:1104187326....@f14g2000cwb.googlegroups.com...

> Is the point to model a bowling-game or to model scoring-a-bowling-game?
>

Asking that question might be considered to be the point. Breaking down the
problem space is part of the point. Perhaps you should ask the onsite
customer or to reference my favorite chapter title perhaps you could ask
"The "Delegate from Troy".

SP


Ron Jeffries

unread,
Dec 28, 2004, 6:29:43 AM12/28/04
to
On 27 Dec 2004 14:42:06 -0800, ig...@yahoo.com wrote:

>Is the point to model a bowling-game or to model scoring-a-bowling-game?

I'm not sure that I understand what your concern is, but I'll do my
best. If this doesn't hit the target, please illuminate the target a
bit more:

The point is to /write a program/ that calculates the total score of a
bowling game, given only the sequence of rolls in the game.

A bowling game is broken down by frames, and as far as I can tell, the
frame concept is essential to producing the correct value even for the
total. For example, the sequence ... 6 4 2 ... is scored differently
depending on whether the 6 occurs as the first roll of a frame, or as
the second.

I could be wrong, but I believe that any program that gets the correct
score for all games will have to accomodate this toggling. As such, it
will include an idea which reflects the scoring peculiarities due to
the existence of the frame in the rules, and as such, I would
therefore suggest that the program should call that idea "frame" or
the equivalent.

Regards,

ig...@yahoo.com

unread,
Dec 28, 2004, 9:51:51 AM12/28/04
to
Ron Jeffries wrote:
> The point is to /write a program/ that calculates the total score
> of a bowling game, given only the sequence of rolls in the game.

Are there acceptance tests?


-snip-


> I'm giving the best advice I have. You get to decide if it's
> true for you.

We always get to decide if what we hear or read is true.

U-CDK_CHARLES\Charles

unread,
Dec 28, 2004, 10:05:37 AM12/28/04
to
On Tue, 28 Dec 2004 06:29:43 -0500, Ron Jeffries <ronje...@acm.org> wrote:
> On 27 Dec 2004 14:42:06 -0800, ig...@yahoo.com wrote:
>
>>Is the point to model a bowling-game or to model scoring-a-bowling-game?
>
> I'm not sure that I understand what your concern is, but I'll do my
> best. If this doesn't hit the target, please illuminate the target a
> bit more:
>
> The point is to /write a program/ that calculates the total score of a
> bowling game, given only the sequence of rolls in the game.
>
> A bowling game is broken down by frames, and as far as I can tell, the
> frame concept is essential to producing the correct value even for the
> total. For example, the sequence ... 6 4 2 ... is scored differently
> depending on whether the 6 occurs as the first roll of a frame, or as
> the second.
>

Does the OP also need to score Candlepins games?

ig...@yahoo.com

unread,
Dec 28, 2004, 10:15:55 AM12/28/04
to
Ron Jeffries wrote:
> A bowling game is broken down by frames, and as far as I can
> tell, the frame concept is essential to producing the correct
> value even for the total.
-snip-

> As such, it will include an idea which reflects the scoring
> peculiarities due to the existence of the frame in the rules, and
> as such, I would therefore suggest that the program should call
> that idea "frame" or the equivalent.

Explicitly representing a "frame" wasn't helpful last year, and seems
to have been no more helpful this year.

http://www.xprogramming.com/xpmag/StreamBowlingGame.htm


afaict the bowling game articles cover the same ground in a different
language - is that fair comment?

Ron Jeffries

unread,
Dec 28, 2004, 10:27:28 AM12/28/04
to
On 28 Dec 2004 06:51:51 -0800, ig...@yahoo.com wrote:

>Ron Jeffries wrote:
>> The point is to /write a program/ that calculates the total score
>> of a bowling game, given only the sequence of rolls in the game.
>
>Are there acceptance tests?

No, it's an exercise in test-driven development, design, and
refactoring, not a product or XP project. Why do you ask?


>
>
>-snip-
>> I'm giving the best advice I have. You get to decide if it's
>> true for you.
>We always get to decide if what we hear or read is true.

Some people seem to need a reminder. Sometimes the listener, sometimes
the speaker. ;->

Regards,

--
Ron Jeffries
www.XProgramming.com

Ron Jeffries

unread,
Dec 28, 2004, 10:28:12 AM12/28/04
to

I don't have a Story for that yet.

Ron Jeffries

unread,
Dec 28, 2004, 10:33:46 AM12/28/04
to
On 28 Dec 2004 07:15:55 -0800, ig...@yahoo.com wrote:

>Ron Jeffries wrote:
>> A bowling game is broken down by frames, and as far as I can
>> tell, the frame concept is essential to producing the correct
>> value even for the total.
>-snip-
>> As such, it will include an idea which reflects the scoring
>> peculiarities due to the existence of the frame in the rules, and
>> as such, I would therefore suggest that the program should call
>> that idea "frame" or the equivalent.
>
>Explicitly representing a "frame" wasn't helpful last year, and seems
>to have been no more helpful this year.

I'm not sure what you mean by it not being helpful, nor am I
understanding what larger point you may be getting at. Could you
perhaps be more specific?


>
>http://www.xprogramming.com/xpmag/StreamBowlingGame.htm
>
>
>afaict the bowling game articles cover the same ground in a different
>language - is that fair comment?

They use the same basic requirements as the basis for development;
they use the same developer, whose thought processes have probably not
changed greatly; and they follow many of the same basic principles,
such as test-driven development. That said, some of the solutions are
very similar, and some are quite different from any that came up in
the C# exercises.

So they cover the same ground in much the same way that a lawnmower
and a rake might do: somewhat the same, yet simply different.

My personal inclination is to attribute the differences in solutions
to something different in the language and tool set, that influences
my programming style, my ability to see options, and my willingness to
pursue them.

Again, I ask: what is the purpose of your comments and inquiries?

ig...@yahoo.com

unread,
Dec 28, 2004, 1:23:15 PM12/28/04
to
Ron Jeffries wrote:
> >> The point is to /write a program/ that calculates the total score
> >> of a bowling game, given only the sequence of rolls in the game.
> >
> >Are there acceptance tests?
>
> No, it's an exercise in test-driven development, design, and
> refactoring, not a product or XP project. Why do you ask?

Isn't it "normal" to write against to a tight spec or acceptance test?
With a loose spec there will be differences in interpretation rather
than differences in invention.

ig...@yahoo.com

unread,
Dec 28, 2004, 4:05:14 PM12/28/04
to
> Again, I ask: what is the purpose of your comments and inquiries?

Curiousity.
Among other things, I wonder if you've come across any solutions that
are different, rather than just being representations of the same
solution in a different language.

Ron Jeffries

unread,
Dec 28, 2004, 6:40:31 PM12/28/04
to

Yes. I'd suggest reading the articles to see them.

Ron Jeffries

unread,
Dec 28, 2004, 6:42:16 PM12/28/04
to

It's an etude, an exercise in Test-Driven Development, simple design,
refactoring, etc. Since I made up the problem and the solutions, the
spec is as tight as I need it to be.

The unit tests I've provided should serve quite adequately as
acceptance tests for anyone else trying their own hand at it. If more
information is needed, such persons should email me or comment on the
extremeprogramming yahoo group. Or here, where I might see them.

ig...@yahoo.com

unread,
Jan 1, 2005, 4:45:24 PM1/1/05
to
They are just different ways to queue the 2 or 3 roll values required
to score a frame - have you seen any solutions that don't require 2 or
3 roll values to be queued?

Ron Jeffries

unread,
Jan 1, 2005, 9:21:54 PM1/1/05
to

I'm not sure what you mean by this.

ig...@yahoo.com

unread,
Jan 1, 2005, 9:38:52 PM1/1/05
to
http://www.xprogramming.com/xpmag/StreamBowlingGame.htm

^self next + self next + self peek

Although this is presented as straightforward addition, it isn't
commutative.

self next + self next + self peek ~= self next + self peek + self
next

Ron Jeffries

unread,
Jan 2, 2005, 6:41:45 AM1/2/05
to

I still don't understand what you're getting at, but ... It's a
program, not an equation. And it's certainly not commutative. Nor is
the game commutative: the score depends on the order of rolls, not
just on their value. For example

10, 3, 4, [all zero] results in a game score of 24, but
3, 4, 10, [all zero] results in a game score of 17.

So any kind of addition in a scoring program will emphatically not be
independent of order, i.e. will not be commutative.

Certain rolls in the game of bowling are scored twice. If I roll a ten
on my first try, that frame is over, and my score in that frame is ten
plus the values of the next two rolls. (Note, therefore, that my score
in that frame cannot be computed at the end of the frame.)

The next two rolls occur in one or two future frames. In those frames,
they count as score there, and those frames may also include values
"from the future". For example, should I roll a 3 and a 4, my score in
that frame is 7. The preceding frame's score is 17 (10 + 3 + 4) and my
cumulative total so far is therefore 24.

So however you cut it, some rolls are counted two or three times. I've
seen various ways to express that:

0. I like the "peek" metaphor, because it is kind of looking "at the
future". There are other metaphors that have turned up:

1. Transform the sequence 10, 3, 4, ... into 10, 3, 4, 3, 4, ...,
duplicating all the rolls that will be counted multiple times. I've
not programmed this one myself but it seems to me that it just pushed
the problem of dealing with the future down a level.

2. Keep counters in the system describing how many times to count the
next two rolls. Each time a ball is rolled, multiply it by the
appropriate count, then update the counts. This generates an
interesting approach -- I have in my e-mail a version that was sent to
me in Haskell.

And there are probably more that don't come to mind. But they all have
to deal with the reality of the game's rules, which result in some
frames not being able to be scored until more is known about the
subsequent rolls.

Anyway, where, if anywhere are you going with this?

ig...@yahoo.com

unread,
Jan 2, 2005, 3:52:13 PM1/2/05
to
> I still don't understand what you're getting at, but ... It's a
> program, not an equation. And it's certainly not commutative. Nor is
> the game commutative: the score depends on the order of rolls, not
> just on their value.

Nothing about this problem or Smalltalk makes us write what appear to
be simple arithmetic expressions, but are not because they break a
basic arithmetic property.

roll0 := self next.
roll1 := self next.
roll2 := self peek.
roll0 + roll1 + roll2 = roll1 + roll2 + roll0

or if we weren't working the "peek" metaphor so hard

(rolls at: i) + (rolls at: i+1) + (rolls at: i+2) =
(rolls at: i+1) + (rolls at: i+2) + (rolls at: i)

ig...@yahoo.com

unread,
Jan 2, 2005, 4:03:19 PM1/2/05
to
> 2. Keep counters in the system describing how many times to count the
> next two rolls. Each time a ball is rolled, multiply it by the
> appropriate count, then update the counts.

Like this?
http://groups-beta.google.com/group/comp.object/msg/508ce258dc7f09d7

ig...@yahoo.com

unread,
Jan 2, 2005, 4:07:10 PM1/2/05
to
> Anyway, where, if anywhere are you going with this?
It's an etude, an exercise, raking the gravel.

Starshine Moonbeam

unread,
Jan 2, 2005, 5:04:35 PM1/2/05
to
In article <1104615924....@z14g2000cwz.googlegroups.com>,
ig...@yahoo.com (ig...@yahoo.com) dropped a +5 bundle of words...

> They are just different ways to queue the 2 or 3 roll values required
> to score a frame - have you seen any solutions that don't require 2 or
> 3 roll values to be queued?
>

Well no. That's the way bowling's scored.

Strike = 10 + your next two rolls
Spare = 10 + your next roll
whatever else is just your score.

--
Starshine Moonbeam
mhm31x9 Smeeter#29 WSD#30
sTaRShInE_mOOnBeAm aT HoTmAil dOt CoM

Ron Jeffries

unread,
Jan 2, 2005, 7:50:37 PM1/2/05
to
On 2 Jan 2005 12:52:13 -0800, ig...@yahoo.com wrote:

>> I still don't understand what you're getting at, but ... It's a
>> program, not an equation. And it's certainly not commutative. Nor is
>> the game commutative: the score depends on the order of rolls, not
>> just on their value.
>
>Nothing about this problem or Smalltalk makes us write what appear to
>be simple arithmetic expressions, but are not because they break a
>basic arithmetic property.

Nothing requires it. Some might like such a design. I guess you don't.


>
>roll0 := self next.
>roll1 := self next.
>roll2 := self peek.
>roll0 + roll1 + roll2 = roll1 + roll2 + roll0
>
>or if we weren't working the "peek" metaphor so hard
>
>(rolls at: i) + (rolls at: i+1) + (rolls at: i+2) =
>(rolls at: i+1) + (rolls at: i+2) + (rolls at: i)

As you know from reading the many articles I've done about this, I
also tried that solution. While it is true that you can reorder the
statements that way, and the program will still work, it's one of the
worst things one could do to that statement, in my opinion, because it
doesn't reflect the rules, which for a spare imply that you get the
two balls in your frame plus one more. Much better, in my opinion,
would be something like

frameFirstBall + frameSecondBall + nextFrameFirstBall.

And even those I'd not recommend reordering, because we have a
responsibility to express what's really going on as clearly as
possible.

In these articles, I'm exploring all the design ideas I can. The point
is that Test-Driven Development doesn't constrain the design, and that
refactoring lets us have most any design we want. I kind of like the
peek design, and since I know what peek and next mean in streams, it
doesn't surprise me that they don't commute: they never do.

But your mileage may vary. Would you care to write an article on
bowling showing your preferred solution and how you reach it? I'd be
happy to publish it.

Regards,

Ron Jeffries

unread,
Jan 2, 2005, 7:51:18 PM1/2/05
to
On 2 Jan 2005 13:07:10 -0800, ig...@yahoo.com wrote:

>> Anyway, where, if anywhere are you going with this?
>It's an etude, an exercise, raking the gravel.

Then give us something to study. Rake the gravel instead of
complaining about how other people rake it.

ig...@yahoo.com

unread,
Jan 3, 2005, 2:36:49 AM1/3/05
to
> frameFirstBall + frameSecondBall + nextFrameFirstBall
aka roll0 + roll1 + roll2

> And even those I'd not recommend reordering

I mentioned it because it's the sort of thing someone might mindlessly
reorder, knowing that addition is commutive. (They might reorder the
statement sequence, but they'd be acting against the ordinary
expectation that statement sequence matters.)

> I know what peek and next mean

We have that in common. Of course, what we write may be read by others
less-adept.

The thing that I was curious about is that the obvious concern you have
for expressing the domain detail (frameFirstBall etc) seemed to
lose-out against the side-effects of the "peek" metaphor.

> preferred solution
The usual solution for the trivial version of the bowling game, in a
language which support pattern-matching on lists:

Start = score [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,3] 0 0

score rolls total 10 = total
score [x,y] total frame = total+x+y
score [x,y,z:rest] total frame
| x == 10 = score [y,z:rest] (total+x+y+z) frameCount
| x+y == 10 = score [z:rest] (total+x+y+z) frameCount
| otherwise = score [z:rest] (total+x+y) frameCount
where frameCount = frame+1

http://groups-beta.google.com/group/comp.object/msg/45ed159928b69648


> write an article
Better to get Paul Sinnett to write about his refactoring
http://groups-beta.google.com/group/comp.object/msg/0212c8de1848cd11

ig...@yahoo.com

unread,
Jan 3, 2005, 2:46:58 AM1/3/05
to
> Then give us something to study.
I have - my exercise was in review, not in refactoring.

> Rake the gravel
Been there, done that - a year ago.

> instead of complaining
You confuse inquiry with complaint.

Complaint would be more like this:
- why isn't scoreFrame called frameScore?
- why isn't scoreStream called streamScore?
- why the "famous author" appeal to authority?

Ron Jeffries

unread,
Jan 3, 2005, 5:58:35 AM1/3/05
to
On 2 Jan 2005 23:36:49 -0800, ig...@yahoo.com wrote:

>> preferred solution
>The usual solution for the trivial version of the bowling game, in a
>language which support pattern-matching on lists:
>
>Start = score [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,3] 0 0
>
>score rolls total 10 = total
>score [x,y] total frame = total+x+y
>score [x,y,z:rest] total frame
>| x == 10 = score [y,z:rest] (total+x+y+z) frameCount
>| x+y == 10 = score [z:rest] (total+x+y+z) frameCount
>| otherwise = score [z:rest] (total+x+y) frameCount
>where frameCount = frame+1
>
>http://groups-beta.google.com/group/comp.object/msg/45ed159928b69648

That's not a language I know. How does it manage not eating the z item
on a spare and the y and z items on a strike?

Ron Jeffries

unread,
Jan 3, 2005, 6:00:38 AM1/3/05
to
On 2 Jan 2005 23:36:49 -0800, ig...@yahoo.com wrote:

>> frameFirstBall + frameSecondBall + nextFrameFirstBall
>aka roll0 + roll1 + roll2
>
>> And even those I'd not recommend reordering
>I mentioned it because it's the sort of thing someone might mindlessly
>reorder, knowing that addition is commutive. (They might reorder the
>statement sequence, but they'd be acting against the ordinary
>expectation that statement sequence matters.)

If they reorder the statements, the tests will fail.


>
>> I know what peek and next mean
>We have that in common. Of course, what we write may be read by others
>less-adept.

True. If they are so maladroit that they reorder statements that they
do not understand, and then do not run the tests, I would suggest that
our approach should not be to dumb down our code but to smart up the
programmers.


>
>The thing that I was curious about is that the obvious concern you have
>for expressing the domain detail (frameFirstBall etc) seemed to
>lose-out against the side-effects of the "peek" metaphor.

Not necessarily. In each example I stop when I've learned what I want
to know. In that one, I wanted to know what the peek implementation
was like.

Ron Jeffries

unread,
Jan 3, 2005, 6:04:09 AM1/3/05
to
On 2 Jan 2005 23:46:58 -0800, ig...@yahoo.com wrote:

>> Then give us something to study.
>I have - my exercise was in review, not in refactoring.
>
>> Rake the gravel
>Been there, done that - a year ago.
>
>> instead of complaining
>You confuse inquiry with complaint.
>
>Complaint would be more like this:
>- why isn't scoreFrame called frameScore?
>- why isn't scoreStream called streamScore?

These seem more like inquiry to me than the comments about
commutativity in a language where there never is any.

>- why the "famous author" appeal to authority?

It isn't an appeal to authority, since the famous author in question
gets his code trashed in the article. It's a veiled bit of humor,
since most of my readers know exactly who the famous author is, as
he's been posting solutions like the one discussed to the xp list. Too
veiled for others, perhaps. But still no appeal to authority.

Regards,

ig...@yahoo.com

unread,
Jan 3, 2005, 1:04:51 PM1/3/05
to
> comments about commutativity in a language where there never is any

Now I'm confused!
Isn't this true in Smalltalk? (5 + 3 + 2) = (3 + 2 + 5)

> >Complaint would be more like this:
> >- why isn't scoreFrame called frameScore?
> >- why isn't scoreStream called streamScore?
> These seem more like inquiry to me

No, those aren't real questions, they are complaints that scoreFrame
should be called frameScore - there's no inquiry, there's no
curiousity, just you're wrong I'm right.

Laurent Bossavit

unread,
Jan 3, 2005, 1:21:34 PM1/3/05
to
Isaac, Ron...

> > >- why isn't scoreStream called streamScore?
> > These seem more like inquiry to me
>
> No, those aren't real questions, they are complaints

The rest of this thread is already archived...
http://www.mindspring.com/~mfpatton/sketch.htm

:)

ig...@yahoo.com

unread,
Jan 3, 2005, 1:18:51 PM1/3/05
to
recursive function score has 3 parameters, the first parameter is a
list of rolls.

[x,y,z:rest] matches the first 3 items from the head of the list
parameter to variables x y z

after identifying a strike, the list passed to the next call of score
is [y,z:rest] - which, of course, is just the initial list without x

ig...@yahoo.com

unread,
Jan 3, 2005, 1:23:45 PM1/3/05
to
Well that ruined my comic build-up :-)

ig...@yahoo.com

unread,
Jan 3, 2005, 4:24:41 PM1/3/05
to
Now you understand that, you'll understand this:

Start = score [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,3] 0

score [x,y] total = total+x+y
score [x,y,z] total = total+x+y+z

score [x,y,z : rest] total


| x == 10 = score [y,z : rest] (total+x+y+z)

| x+y == 10 = score [z : rest] (total+x+y+z)

ig...@yahoo.com

unread,
Jan 4, 2005, 2:19:15 PM1/4/05
to
"One of the things that makes Smalltalk easier to develop in is that
you don't have to do all that declaration of types..."

Incidentally, the Clean compiler inferred these parameter types for the
functions:

score :: !.[Int] !Int -> Int
Start :: Int

Robert C. Martin

unread,
Jan 5, 2005, 2:25:15 PM1/5/05
to
On Mon, 27 Dec 2004 17:18:28 -0500, Ron Jeffries <ronje...@acm.org>
wrote:

>On 26 Dec 2004 11:09:38 -0800, ig...@yahoo.com wrote:
>
>>Another December, another series of Bowling game articles
>>http://www.xprogramming.com/xpmag/index.htm
>>
>>And the same question, why do the programs model a bowling-game rather
>>than model scoring-a-bowling-game? (Why the insistence on a frame
>>object?)
>
>Well, not all the designs do have a frame object, so there's hardly
>any "insistence".

Indeed, the original Bowling Game article
(http://www.objectmentor.com/resources/articles/xpepisode.htm) did not
use a Frame object. We thought about using one, planned on using one,
but found that it was not necessary.


-----
Robert C. Martin (Uncle Bob) | email: uncl...@objectmentor.com
Object Mentor Inc. | blog: www.butunclebob.com
The Agile Transition Experts | web: www.objectmentor.com
800-338-6716


"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo

Robert C. Martin

unread,
Jan 5, 2005, 2:27:31 PM1/5/05
to
On 27 Dec 2004 14:42:06 -0800, ig...@yahoo.com wrote:

>Is the point to model a bowling-game or to model scoring-a-bowling-game?

The point is not to model anything. The point is to calculate the
score of a bowling game given a list of all the rolls.

More specifically, given a class that has the following methods:

class BowlingGame {
public void roll(int pins);
public int score();
}

If roll is called for each roll within a bowling game, then score can
be called to get the score of that game. Score cannot be called
before the end of the game.

Robert C. Martin

unread,
Jan 5, 2005, 2:29:44 PM1/5/05
to
On 28 Dec 2004 06:51:51 -0800, ig...@yahoo.com wrote:

>Ron Jeffries wrote:
>> The point is to /write a program/ that calculates the total score
>> of a bowling game, given only the sequence of rolls in the game.
>
>Are there acceptance tests?

http://www.fitnesse.org/FitNesse.WritingAcceptanceTests.BowlingGameProject.SuiteGames.TestFinalScores

Sylvia Gardner

unread,
Jan 5, 2005, 3:23:11 PM1/5/05
to

Robert C. Martin wrote:
> More specifically, given a class that has the following methods:
>
> class BowlingGame {
> public void roll(int pins);
> public int score();
> }

Requirements changed. I want to know what my rolls were
on the third frame. A frameless approach makes any kind
of higher level analyis impossible.

This is an architecture issue. I have found
architectures that record the raw data and build up
behaviours on the raw data are robust against all
manner of changes. I would use this knowledge up
front and create such a system secure in the knowledge
my system will be very simple and robust against
almost any requirement that comes down the line.

Your fascination with just comming up with a final
score seems particularly odd.

ig...@yahoo.com

unread,
Jan 5, 2005, 4:07:05 PM1/5/05
to
Slightly confused...

If the point is to calculate the score given a list of all the rolls,
then wouldn't we have something more like this
class BowlingGameScorer {
public int score(List rolls);
}

ig...@yahoo.com

unread,
Jan 5, 2005, 4:14:12 PM1/5/05
to
> Your fascination with just coming up with a final score
> seems particularly odd.
This has been going around-and-around for years, there are many
variations, including more interesting ones that take rolls one-by-one
and put frame-scores as soon as they can be calculated.

Ron Jeffries

unread,
Jan 5, 2005, 9:55:36 PM1/5/05
to

It's an exercise. An etude. An example that, in an hour, can help
those who will do or observe the exercise, learn something about what
TDD does to help, what refactoring can change, how different designs
for the same program might work. The problem is stated the way it is
because I can do it in an hour, while talking and answering questions.

If I had two hours, I'd implement a whole bowling alley.

In a "real" bowling app, one can't build up the total data and then
go, because in a "real" bowling app they actually want to know a
frame's score as soon as possible. That means, of course, that it
might be as soon as the frame is over ... or as many as two frames
later.

Building that is kind of fun. My take after doing this app N different
ways is that at this scale, at least, the main criterion for how to
start is "simply". The main criterion for how to proceed is "clearly".
Given that, the design can grow as it needs to.

I could be wrong, of course, but remember that I currently hold the
record on number of times implementing the same silly program. For
baseball, someone might have a point. For bowling, I'm pretty sure. :)

Ron Jeffries

unread,
Jan 5, 2005, 9:57:13 PM1/5/05
to
On Wed, 05 Jan 2005 13:25:15 -0600, Robert C. Martin
<uncl...@objectmentor.com> wrote:

>On Mon, 27 Dec 2004 17:18:28 -0500, Ron Jeffries <ronje...@acm.org>
>wrote:
>
>>On 26 Dec 2004 11:09:38 -0800, ig...@yahoo.com wrote:
>>
>>>Another December, another series of Bowling game articles
>>>http://www.xprogramming.com/xpmag/index.htm
>>>
>>>And the same question, why do the programs model a bowling-game rather
>>>than model scoring-a-bowling-game? (Why the insistence on a frame
>>>object?)
>>
>>Well, not all the designs do have a frame object, so there's hardly
>>any "insistence".
>
>Indeed, the original Bowling Game article
>(http://www.objectmentor.com/resources/articles/xpepisode.htm) did not
>use a Frame object. We thought about using one, planned on using one,
>but found that it was not necessary.

They do, of course, have a frame /concept/, sometimes very thinly
disguised, sometimes a little more difficult to detect. I think
there's no way out of that, given how the rules of the game work.

Sylvia Gardner

unread,
Jan 5, 2005, 11:36:16 PM1/5/05
to

Ron Jeffries wrote:
> It's an exercise.

Then you certainly don't mind when frames are used. It seems to
a frowned upon solution.

> In a "real" bowling app, one can't build up the total data and then
> go,

You have the total data at all times. You can then create
a total at any point of time. So i'm not sure what can't be done.

Ron Jeffries

unread,
Jan 6, 2005, 5:29:25 AM1/6/05
to
On Wed, 05 Jan 2005 20:36:16 -0800, Sylvia Gardner <s...@aol.com> wrote:

>Ron Jeffries wrote:
>> It's an exercise.
>
>Then you certainly don't mind when frames are used. It seems to
>a frowned upon solution.

Frames /as an object, a class/ seem to many readers and implementors
to be overkill for the problem as stated. The frame idea, as I've
mentioned elsewhere in the thread, cannot be avoided.


>
>> In a "real" bowling app, one can't build up the total data and then
>> go,
>
>You have the total data at all times. You can then create
>a total at any point of time. So i'm not sure what can't be done.

In ten-pin bowling, the score of a given frame can depend on rolls
from future frames. You can have a running total of "what we know
now", but it doesn't progress as one might think. For example

Frame number, roll[s], what we know about the score
1: 10, _, it's at least ten
2: 10, _, frame one >= 20, f2 >= 10, tot >= 30.
3: 5, 5, f1 = 25, f2 = 20, f3 >= 10, tot >= 55
4: 4, 4, f3 = 14, f4 = 8, tot = 67 (so far)

if I did the artithmetic right. According to the rules of bowling, the
score of a strike frame is ten, plus the values of the next two balls
rolled. //Those balls are rolled in future frames, after the turns of
all the other opponents. If they all roll open frames or spares, and
if there are four people bowling, the score of a strike frame might
not be known until as many as 14 more rolls, and an unknown number of
beers, had elapsed.

Sylvia Gardner

unread,
Jan 6, 2005, 11:19:58 AM1/6/05
to

Ron Jeffries wrote:
> Frames /as an object, a class/ seem to many readers and implementors
> to be overkill for the problem as stated. The frame idea, as I've
> mentioned elsewhere in the thread, cannot be avoided.

How does one define overkill? Is it possible to have a hard won
philosophy of programming that can make something not overkill,
even though you think it is?


> In ten-pin bowling, the score of a given frame can depend on rolls
> from future frames. You can have a running total of "what we know
> now", but it doesn't progress as one might think. For example

If you faithfully record every roll in every frame then you
can always recreate the score at any point in time. It
doesn't really matter if it progresses as one might think.
And if you record the data it won't matter if you make
an error, because it is always possible to fix the algorithm
later. If you combine the data and the algorithm, then if
the algorithm is wrong, you have lost the data forever.
I don't even have to keep a running total. I can calculate
it as needed because it's a cheap operation.

This approach may not win the do it with two registers
contest, but it wins in almost every other way. That's
not overkill.

Ron Jeffries

unread,
Jan 6, 2005, 2:04:58 PM1/6/05
to
On Thu, 06 Jan 2005 08:19:58 -0800, Sylvia Gardner <s...@aol.com> wrote:

>Ron Jeffries wrote:
>> Frames /as an object, a class/ seem to many readers and implementors
>> to be overkill for the problem as stated. The frame idea, as I've
>> mentioned elsewhere in the thread, cannot be avoided.
>
>How does one define overkill? Is it possible to have a hard won
>philosophy of programming that can make something not overkill,
>even though you think it is?

In the context above, I meant that /given that the sole requirement is
coming up with the total score from a complete collection of rolls/ ,
the designs with a frame object seem unnecessarily complex.

I don't understand the philosophy question, nor what we would do
differently if it were answered Yes, or No. If you'd like to explore
that question further, please help me understand.


>
>
>> In ten-pin bowling, the score of a given frame can depend on rolls
>> from future frames. You can have a running total of "what we know
>> now", but it doesn't progress as one might think. For example
>
>If you faithfully record every roll in every frame then you
>can always recreate the score at any point in time.

Certainly the requirement as stated is sufficient to score the game
correctly. I believe that it is literally /impossible/ to recreate the
score at any given time, because at some given times the score is
undefined. Even the "running" score.

One issue is that the spec does not include frame information. The
problem is somewhat simpler if the incoming rolls are parsed into
frames, e.g. [10] [10] [6 4] [4 4] etc. But they are not: the input is
10 10 6 4 4 4 etc. I'm not sure whether you were thinking of of that
when you wrote the phrase "record every roll in every frame".

> It
>doesn't really matter if it progresses as one might think.

Given that one understands the rules of bowling, that's true. Some
correspondents have not understood them, so I am trying to be clear
about them. If you were presenting code that passed the tests, it
might be easier to have this discussion.

>And if you record the data it won't matter if you make
>an error, because it is always possible to fix the algorithm
>later.

I'm not sure just what you mean about errors not mattering. On my
planet, it does matter if we make errors, and fixing them later is not
always practical. We can't bring people back from the dead, for
example, if our radiation therapy program burns them to death. In
bowling the errors are less serious, unless the programmer has to be
in the bowling alley with a bunch of angry beer-drinking bowlers.

>If you combine the data and the algorithm, then if
>the algorithm is wrong, you have lost the data forever.
>I don't even have to keep a running total. I can calculate
>it as needed because it's a cheap operation.

I'm not sure I understand your point here. Are you concerned because
some of the algorithms consume the rolls list? If one cared about that
(I do not), then it would be the difference between

self scoreRolls: rollsCollection

and

self scoreRolls: rollsCollection copy

in the examples that consume the rolls. Most of the examples don't
consume them anyway.


>
>This approach may not win the do it with two registers
>contest, but it wins in almost every other way. That's
>not overkill.

I'd like to see the code that you are imagining, and perhaps a
definition of "wins". I'm sure that at least one of us will learn
something.

Sylvia Gardner

unread,
Jan 6, 2005, 3:10:16 PM1/6/05
to

Ron Jeffries wrote:
> In the context above, I meant that /given that the sole requirement is
> coming up with the total score from a complete collection of rolls/ ,
> the designs with a frame object seem unnecessarily complex.

There's never just a single requirement. You bring yourself
and your experience to every problem. You are able use your
judgement as well. I know that certain approaches are more
robust against certain types of changes and failures. I
will use those approaches unless i can't. A sole requirement
is not an "i can't" reason.

> Certainly the requirement as stated is sufficient to score the game
> correctly. I believe that it is literally /impossible/ to recreate the
> score at any given time, because at some given times the score is
> undefined. Even the "running" score.

The score is never undefined. There's always a total score. The
next calculation of total score may be waiting on a particular
event in its state machine.


> One issue is that the spec does not include frame information. The
> problem is somewhat simpler if the incoming rolls are parsed into
> frames, e.g. [10] [10] [6 4] [4 4] etc. But they are not: the input is
> 10 10 6 4 4 4 etc.

That certainly doesn't have to be the input. Not questioning assumptions
and figuring out a better way is a waste.

>If you were presenting code that passed the tests, it
>might be easier to have this discussion.

I think we can talk about it generally speaking.

> I'm not sure just what you mean about errors not mattering. On my
> planet, it does matter if we make errors, and fixing them later is not
> always practical.

If you base your approach on refactoring then it is always possible.
An error you can't correct is different than an error you can correct.
If you keep the raw data then all errors can be fixed by algorithm
changes. If you toss away data then you can never fix the error
because information has been lost. This seems a very simple idea.


>We can't bring people back from the dead, for
>example, if our radiation therapy program burns them to death.

Could you please show me the code that shows this? :-)


> I'm not sure I understand your point here. Are you concerned because
> some of the algorithms consume the rolls list? If one cared about that
> (I do not), then it would be the difference between

And what determines what you care about? It's not a matter of
adding a copy, it's a matter of approach. Copying without
integrating into your solution means nothing.

ig...@yahoo.com

unread,
Jan 6, 2005, 3:31:34 PM1/6/05
to
> There's never just a single requirement.
By definition, in this case, there is.

> The score is never undefined. There's always a total score.

Yes, the score increases monotonically.
If the score ever could be considered undefined, it would be before the
game began ;-)

Sylvia Gardner

unread,
Jan 6, 2005, 3:40:49 PM1/6/05
to

ig...@yahoo.com wrote:
>>There's never just a single requirement.
>
> By definition, in this case, there is.

They are only just rules, aren't they? So by definition,
there isn't.

>>The score is never undefined. There's always a total score.
>
> Yes, the score increases monotonically.
> If the score ever could be considered undefined, it would be before the
> game began ;-)

It would be zero.

ig...@yahoo.com

unread,
Jan 6, 2005, 4:44:00 PM1/6/05
to
> They are only just rules, aren't they?
> So by definition, there isn't.

We can create different definitions.
That doesn't alter Ron's single requirement definition.

> > If the score ever could be considered undefined, it would be
> > before the game began ;-)
> It would be zero.

So the score in a bowling game that has not been played and never will
be played is zero? I wonder how many 0:0 bowling games I've had with
Ron ;-)

ig...@yahoo.com

unread,
Jan 6, 2005, 4:45:56 PM1/6/05
to
> If you faithfully record every roll in every frame then you
> can always recreate the score at any point in time.
If you faithfully record every roll then ...

Sylvia Gardner

unread,
Jan 6, 2005, 5:24:23 PM1/6/05
to

ig...@yahoo.com wrote:
> We can create different definitions.
> That doesn't alter Ron's single requirement definition.

Ron says they are just rules, so you don't have to
stick to it, especially when you are asked to solve
a problem. Your experiences become part of the problem
and part of the solution. Unless you think of yourself
as some sort of abstract solution generation machine.
I don't. So i don't accept the false choice.


> So the score in a bowling game that has not been played and never will
> be played is zero? I wonder how many 0:0 bowling games I've had with
> Ron ;-)

If we are talking a game instance then the score starts at 0.
If we are talking about the class of games, then it probably won't
have a score attribute, so it wouldn't even be undefined.

Ron Jeffries

unread,
Jan 6, 2005, 5:58:13 PM1/6/05
to
On 6 Jan 2005 12:31:34 -0800, ig...@yahoo.com wrote:

>> There's never just a single requirement.
>By definition, in this case, there is.

;-> My point exactly.


>
>> The score is never undefined. There's always a total score.
>Yes, the score increases monotonically.
>If the score ever could be considered undefined, it would be before the
>game began ;-)

I'm not convinced, but I'm not convinced that it matters, either.

If you throw 9, 0 in your first frame, and 9,0 in y our second, your
score at the end of two frames is 18. If I throw 10 in the first and
ten in the second, my score is zero. But by any reasonable measure,
I'm ahead. That's why I'm not convinced that there exists an
intermediate score.

But it might just be angels on the point of a pin. It's the tests and
code that matter to me.

Ron Jeffries

unread,
Jan 6, 2005, 6:01:30 PM1/6/05
to
On Thu, 06 Jan 2005 14:24:23 -0800, Sylvia Gardner <s...@aol.com> wrote:

>> So the score in a bowling game that has not been played and never will
>> be played is zero? I wonder how many 0:0 bowling games I've had with
>> Ron ;-)
>
>If we are talking a game instance then the score starts at 0.
>If we are talking about the class of games, then it probably won't
>have a score attribute, so it wouldn't even be undefined.

It would be easy to have a game instance where the score starts at
nil, or where it starts at -100. I think in at least one of my
examples, it does in fact start at nil.

And if we were playing requirements games, we might need to do that,
to tell the difference between a game of all gutter balls, and a game
that hasn't been played yet.

But of course, we aren't playing requirements games, are we?

Ron Jeffries

unread,
Jan 6, 2005, 5:59:36 PM1/6/05
to
On Thu, 06 Jan 2005 12:40:49 -0800, Sylvia Gardner <s...@aol.com> wrote:

>ig...@yahoo.com wrote:
>>>There's never just a single requirement.
>>
>> By definition, in this case, there is.
>
>They are only just rules, aren't they? So by definition,
>there isn't.

Word play. Think of it as an exam. (It's really an exercise.) The prof
has set forth an exam question or an exercise. We get to answer that
question, not some other question.

Now in a real project, sure, we can be pretty certain that there are
more requirements. And that's an interesting topic. It's just not
/this/ topic.

Sylvia Gardner

unread,
Jan 6, 2005, 6:21:03 PM1/6/05
to

Ron Jeffries wrote:
> Word play. Think of it as an exam. (It's really an exercise.) The prof
> has set forth an exam question or an exercise. We get to answer that
> question, not some other question.

That's word play. Your program will contain a hundred things that aren't
specified in the question. You'll use good names because that's good
practice, yet the question won't say to. If I used all numeric
variable names i am sure i would flunk your exam. Why then should
i limit other tactics i think are good practice when taking
your exam?

Sylvia Gardner

unread,
Jan 6, 2005, 6:23:35 PM1/6/05
to

Ron Jeffries wrote:
> It would be easy to have a game instance where the score starts at
> nil, or where it starts at -100.

Then that wouldn't be bowling.

> And if we were playing requirements games, we might need to do that,
> to tell the difference between a game of all gutter balls, and a game
> that hasn't been played yet.
>
> But of course, we aren't playing requirements games, are we?

I am trying to write the best programs.

Ron Jeffries

unread,
Jan 6, 2005, 6:18:59 PM1/6/05
to
On Thu, 06 Jan 2005 12:10:16 -0800, in comp.object Sylvia wrote:

>
>Ron Jeffries wrote:
>> In the context above, I meant that /given that the sole requirement is
>> coming up with the total score from a complete collection of rolls/ ,
>> the designs with a frame object seem unnecessarily complex.
>
>There's never just a single requirement. You bring yourself
>and your experience to every problem. You are able use your
>judgement as well. I know that certain approaches are more
>robust against certain types of changes and failures. I
>will use those approaches unless i can't. A sole requirement
>is not an "i can't" reason.

You'll find that I rarely say "I can't". However, at the stage where
the program just meets that first requirement, a frame object seems
premature to me, and to many other readers, because discernibly
simpler solutions exist at that moment in time.

Some people like to build a solution that is in fact more ready for
the future. One of the lessons of Agile methods that I like to
demonstrate is how very little one needs to be concerned about this,
letting the current code meet the current requirements, and adapting
to new requirements as they arise.


>
>> Certainly the requirement as stated is sufficient to score the game
>> correctly. I believe that it is literally /impossible/ to recreate the
>> score at any given time, because at some given times the score is
>> undefined. Even the "running" score.
>
>The score is never undefined. There's always a total score. The
>next calculation of total score may be waiting on a particular
>event in its state machine.

You apparently have some model in mind. I'd like to see that converted
to code that runs the same tests as the existing examples. That would
make it easier to be specific in our comparisons.

The game of bowling, despite your or my models of it, doesn't have
"score" defined until the end of the ten frames and all bonus balls.
And frames are scored when the data becomes available. (But that's not
part of our initial requirements, so that providing that feature, by
the rules of the game as I play it, is premature.)


>
>
>> One issue is that the spec does not include frame information. The
>> problem is somewhat simpler if the incoming rolls are parsed into
>> frames, e.g. [10] [10] [6 4] [4 4] etc. But they are not: the input is
>> 10 10 6 4 4 4 etc.
>
>That certainly doesn't have to be the input. Not questioning assumptions
>and figuring out a better way is a waste.

It's an etude. The whole point is to start with a fixed point and see
where you wind up. If we started with different input, we'd quite
likely get a different result. That would be worth doing as well, time
permitting. I'd welcome an article that started somewhere else.

The objection that I have to pre-framed input is that more of the
problem (scoring bowling) has been determined outside the system. That
makes the first steps a bit too easy to make an effective etude (in my
opinion), though it might well leave time to add more features within
the time constraints of the exercise.


>
>>If you were presenting code that passed the tests, it
>>might be easier to have this discussion.
>
>I think we can talk about it generally speaking.

Indeed, we are. But we're not likely to agree on much, since your
ideas are never made explicit. But that's fine with me if you don't
want to code it up.


>
>> I'm not sure just what you mean about errors not mattering. On my
>> planet, it does matter if we make errors, and fixing them later is not
>> always practical.
>
>If you base your approach on refactoring then it is always possible.
>An error you can't correct is different than an error you can correct.
>If you keep the raw data then all errors can be fixed by algorithm
>changes. If you toss away data then you can never fix the error
>because information has been lost. This seems a very simple idea.

It is. I just don't see why you've brought it up. Has someone
suggested that throwing the data away is a good idea?


>
>
>>We can't bring people back from the dead, for
>>example, if our radiation therapy program burns them to death.
>
>Could you please show me the code that shows this? :-)

Wish I could. Maybe I could fix the bug. That's starting to look like
it'd be useful.


>
>
>> I'm not sure I understand your point here. Are you concerned because
>> some of the algorithms consume the rolls list? If one cared about that
>> (I do not), then it would be the difference between
>
>And what determines what you care about? It's not a matter of
>adding a copy, it's a matter of approach. Copying without
>integrating into your solution means nothing.

My solutions all pass the tests. It's hard to see just what "means
nothing" means in that context.

Sylvia Gardner

unread,
Jan 6, 2005, 6:32:12 PM1/6/05
to

Ron Jeffries wrote:
> If you throw 9, 0 in your first frame, and 9,0 in y our second, your
> score at the end of two frames is 18. If I throw 10 in the first and
> ten in the second, my score is zero. But by any reasonable measure,
> I'm ahead. That's why I'm not convinced that there exists an
> intermediate score.

Your being ahead or not depends on the definition of a comparison operator for
type bowling game. That doesn't change that there is a score.

> But it might just be angels on the point of a pin. It's the tests and
> code that matter to me.

What matters are ideas. You can always create tests and code.

ig...@yahoo.com

unread,
Jan 6, 2005, 6:29:03 PM1/6/05
to
> > > There's never just a single requirement.
> > By definition, in this case, there is.
> ;-> My point exactly.

Take it as evidence that when I disagree, I disagree with the text not
the author ;-)

Robert C. Martin

unread,
Jan 6, 2005, 6:31:20 PM1/6/05
to
On Wed, 05 Jan 2005 12:23:11 -0800, Sylvia Gardner <s...@aol.com> wrote:

>
>
>Robert C. Martin wrote:
>> More specifically, given a class that has the following methods:
>>
>> class BowlingGame {
>> public void roll(int pins);
>> public int score();
>> }
>
>Requirements changed. I want to know what my rolls were
>on the third frame. A frameless approach makes any kind
>of higher level analyis impossible.

In fact the change to the "frameless" code that gives you what you
want is remarkably trivial. It's a matter of adding an argument (n)
to the score function, and changing the loop in the score function to
terminate at n instead of 10.

This is always the first objection people have when I present the
bowling game example. They say: "Yeah, but this isn't a good OO
solution and therefore isn't flexible. What if you wanted to know the
score at the end of each frame instead of just at the end of the
game."

BTW the "Frameless" implementation is not really frameless. There is
no frame object per se, but there is an integer that represents the
frame number.


>
>This is an architecture issue. I have found
>architectures that record the raw data and build up
>behaviours on the raw data are robust against all
>manner of changes. I would use this knowledge up
>front and create such a system secure in the knowledge
>my system will be very simple and robust against
>almost any requirement that comes down the line.

This is exactly the approach taken by the "frameless" solution.

>
>Your fascination with just comming up with a final
>score seems particularly odd.

All requirements are particularly odd. What is interesting is how to
solve them, and how to keep the code both simple and flexible.

Here is the "frameless" solution. Notice how it reads like the rules
of bowling. I leave the simple change that allows scoring individual
frames as an exercise for the reader. Oh, and don't get upset by the
fact that this code doesn't do any error detection. That's also left
as an exercise for the reader.

public class Game {
private int rolls[] = new int[21];
private int currentRoll = 0;

public void roll(int pins) {
rolls[currentRoll++] = pins;
}

public int score() {
int score = 0;
int frame = 0;
for (int frameNumber = 0; frameNumber < 10; frameNumber++) {
if (isStrike(frame))
{
score += 10 + nextTwoBallsAfterStrike(frame);
frame += 1;
}
else if (isSpare(frame))
{
score += 10 + nextBallAfterSpare(frame);
frame += 2;
} else {
score += twoBallsInFrame(frame);
frame += 2;
}
}
return score;
}

private int twoBallsInFrame(int i) {
return rolls[i] + rolls[i + 1];
}

private int nextBallAfterSpare(int i) {
return rolls[i+2];
}

private int nextTwoBallsAfterStrike(int i) {
return rolls[i+1] + rolls[i+2];
}

private boolean isStrike(int i) {
return rolls[i] == 10;
}

private boolean isSpare(int i) {
return rolls[i] + rolls[i + 1] == 10;

Robert C. Martin

unread,
Jan 6, 2005, 6:34:49 PM1/6/05
to
On Wed, 05 Jan 2005 20:36:16 -0800, Sylvia Gardner <s...@aol.com> wrote:

>
>Ron Jeffries wrote:
>> It's an exercise.
>
>Then you certainly don't mind when frames are used. It seems to
>a frowned upon solution.

What *I* frown upon is the *insistence* that a frame object is always
a superior solution. One poster presented 400 lines of code to
support his claim that frame objects are better even though the
"frameless" solution is 50 lines.

>You have the total data at all times. You can then create
>a total at any point of time. So i'm not sure what can't be done.

You can't calculate the score for a strike frame until the next two
balls have been rolled.

Sylvia Gardner

unread,
Jan 6, 2005, 6:43:28 PM1/6/05
to

Ron Jeffries wrote:
> You'll find that I rarely say "I can't". However, at the stage where
> the program just meets that first requirement, a frame object seems
> premature to me, and to many other readers, because discernibly
> simpler solutions exist at that moment in time.

Simpler isn't inherently better. Clearer can be better. Understandable
can be better. Faster can be better. Slower can be better. You can't
argue better in only one dimension.


> Some people like to build a solution that is in fact more ready for
> the future. One of the lessons of Agile methods that I like to
> demonstrate is how very little one needs to be concerned about this,
> letting the current code meet the current requirements, and adapting
> to new requirements as they arise.

It's quite arrogant to assume you are demonstrating a lesson.

>>And what determines what you care about? It's not a matter of
>>adding a copy, it's a matter of approach. Copying without
>>integrating into your solution means nothing.
>
> My solutions all pass the tests. It's hard to see just what "means
> nothing" means in that context.

I am reminded of the pharisees.

Robert C. Martin

unread,
Jan 6, 2005, 6:39:49 PM1/6/05
to
On Thu, 06 Jan 2005 08:19:58 -0800, Sylvia Gardner <s...@aol.com> wrote:

>
>Ron Jeffries wrote:
>> Frames /as an object, a class/ seem to many readers and implementors
>> to be overkill for the problem as stated. The frame idea, as I've
>> mentioned elsewhere in the thread, cannot be avoided.
>
>How does one define overkill? Is it possible to have a hard won
>philosophy of programming that can make something not overkill,
>even though you think it is?

Look at this function:


public int score() {
int score = 0;
int frame = 0;
for (int frameNumber = 0; frameNumber < 10; frameNumber++) {
if (isStrike(frame)) {
score += 10 + nextTwoBallsAfterStrike(frame);
frame += 1;
}
else if (isSpare(frame)) {
score += 10 + nextBallAfterSpare(frame);
frame += 2;
} else {
score += twoBallsInFrame(frame);
frame += 2;
}
}
return score;
}

This reads like the rules of bowling. It's hard to imaging anything
simpler than this (in Java). I'd say that anything more complex is
overkill for the current requirements.

>> In ten-pin bowling, the score of a given frame can depend on rolls
>> from future frames. You can have a running total of "what we know
>> now", but it doesn't progress as one might think. For example
>
>If you faithfully record every roll in every frame then you
>can always recreate the score at any point in time.

If you faithfully record every roll, you can derive the frame, and
still recreate the score at any point in time. You don't have to
record the frame, because the frame is implicit in the rolls.

Robert C. Martin

unread,
Jan 6, 2005, 6:42:05 PM1/6/05
to
On Thu, 06 Jan 2005 12:10:16 -0800, Sylvia Gardner <s...@aol.com> wrote:

>>We can't bring people back from the dead, for
>>example, if our radiation therapy program burns them to death.
>
>Could you please show me the code that shows this? :-)

Several years ago there was an unfortunate event in which a lab-tech
entered an invalid number into a radiation therapy machine, and a
software fault caused the shutter to open and stay open. The patient
died.

This may be an urban legend.

Robert C. Martin

unread,
Jan 6, 2005, 6:43:33 PM1/6/05
to
On 5 Jan 2005 13:07:05 -0800, ig...@yahoo.com wrote:

>Slightly confused...
>
>If the point is to calculate the score given a list of all the rolls,
>then wouldn't we have something more like this
>class BowlingGameScorer {
> public int score(List rolls);
>}

It's the same problem in either case.

Sylvia Gardner

unread,
Jan 6, 2005, 6:49:19 PM1/6/05
to

Robert C. Martin wrote:
> What *I* frown upon is the *insistence* that a frame object is always
> a superior solution.

I don't recall making any such insistence, so T off on someone else
please.

Sylvia Gardner

unread,
Jan 6, 2005, 6:50:38 PM1/6/05
to

Robert C. Martin wrote:

> Several years ago there was an unfortunate event in which a lab-tech
> entered an invalid number into a radiation therapy machine, and a
> software fault caused the shutter to open and stay open. The patient
> died.
>
> This may be an urban legend.

It was a slightly more metaphysical question.

ig...@yahoo.com

unread,
Jan 6, 2005, 6:47:19 PM1/6/05
to
> >You have the total data at all times. You can then create
> >a total at any point of time. So i'm not sure what can't be done.

>You can't calculate the score for a strike frame until the next two
>balls have been rolled.

Ummm, true and irrelevant?
The score would be defined and unchanged.

Sylvia Gardner

unread,
Jan 6, 2005, 6:52:37 PM1/6/05
to

Robert C. Martin wrote:
> In fact the change to the "frameless" code that gives you what you
> want is remarkably trivial. It's a matter of adding an argument (n)
> to the score function, and changing the loop in the score function to
> terminate at n instead of 10.

What kind of split did i have? I don't think your change
answers that question.

> This is always the first objection people have when I present the
> bowling game example. They say: "Yeah, but this isn't a good OO
> solution and therefore isn't flexible.

It's not really an OO issue imho. Any arguments from form are bogus.
It would be like you rejecting a program because it wasn't written
using TDD. That's not a valid criticism.

ig...@yahoo.com

unread,
Jan 6, 2005, 6:58:00 PM1/6/05
to
> It's the same problem in either case

It's a little less ambiguous to have- public int score(List rolls)
We'd still want a pre-condition that 'rolls' represents a complete
correct game.

With the description, it wasn't clear who's responsibility it was to
know that we had reached the end of the game, or if score could be
called but the result was undefined, or...

"If roll is called for each roll within a bowling game, then score can
be called to get the score of that game. Score cannot be called
before the end of the game."

ig...@yahoo.com

unread,
Jan 6, 2005, 7:14:07 PM1/6/05
to
> > > And what determines what you care about? It's not a matter of
> > > adding a copy, it's a matter of approach. Copying without
> > > integrating into your solution means nothing.

> > My solutions all pass the tests. It's hard to see just what "means
> > nothing" means in that context.

> I am reminded of the pharisees

I hope the recollection was enjoyable for you - it communicated nothing
to me.

Sylvia Gardner

unread,
Jan 6, 2005, 7:29:36 PM1/6/05
to

Pharisees were people for whom the obeying forms and rules was most
important. Jesus thought the spirit of the law was more important.
Caring only about tests strikes me as pharisitical.

ig...@yahoo.com

unread,
Jan 6, 2005, 7:48:09 PM1/6/05
to
The letter-of-the-law vs the spirit-of-the-law is a distinction I
understand.

I can see where Ron Jeffries demonstrates concern for the
letter-of-the-law (programmer tests). That doesn't demonstrate lack of
concern for the spirit.

Sylvia Gardner

unread,
Jan 7, 2005, 12:11:02 AM1/7/05
to

ig...@yahoo.com wrote:
> I can see where Ron Jeffries demonstrates concern for the
> letter-of-the-law (programmer tests). That doesn't demonstrate lack of
> concern for the spirit.

Well, when he says all cares about is the tests, what does that demonstrate
to you? Not a lot of room for spirit.

Ilja Preuß

unread,
Jan 7, 2005, 3:56:11 AM1/7/05
to
Robert C. Martin wrote:

> Several years ago there was an unfortunate event in which a lab-tech
> entered an invalid number into a radiation therapy machine, and a
> software fault caused the shutter to open and stay open. The patient
> died.

As I remember it from reading it somewhere, the software sometimes did show
different values on the screen from those it actually used when you tried to
correct already entered values, or something...

Regards, Ilja


Robert C. Martin

unread,
Jan 7, 2005, 2:44:03 PM1/7/05
to
On Thu, 06 Jan 2005 15:52:37 -0800, Sylvia Gardner <s...@aol.com> wrote:

>
>
>Robert C. Martin wrote:
>> In fact the change to the "frameless" code that gives you what you
>> want is remarkably trivial. It's a matter of adding an argument (n)
>> to the score function, and changing the loop in the score function to
>> terminate at n instead of 10.
>
>What kind of split did i have? I don't think your change
>answers that question.

Indeed, not! If that becomes a new requirement, then I'm going to
have to drastically change the input to algorithm. I'll have to know
the exact pins that were knocked down, not just their count.

Having said that, I could add a new method: roll(List<int>), and have
it call my old roll(int) method. I could maintain a array of those
lists that had the same index as my rolls array. Then, inside the
scoring loop I could query that array and set the type of split. I
don't think it'd be too hard.

>> This is always the first objection people have when I present the
>> bowling game example. They say: "Yeah, but this isn't a good OO
>> solution and therefore isn't flexible.
>
>It's not really an OO issue imho. Any arguments from form are bogus.

Tell that to the IRS.

Ron Jeffries

unread,
Jan 7, 2005, 5:15:08 PM1/7/05
to
On Thu, 06 Jan 2005 17:42:05 -0600, Robert C. Martin
<uncl...@objectmentor.com> wrote:

>Several years ago there was an unfortunate event in which a lab-tech
>entered an invalid number into a radiation therapy machine, and a
>software fault caused the shutter to open and stay open. The patient
>died.
>
>This may be an urban legend.

Not an urban legend. Google "Therac" or "Therac-25".

Ron Jeffries

unread,
Jan 7, 2005, 5:23:52 PM1/7/05
to
On Thu, 06 Jan 2005 15:43:28 -0800, Sylvia Gardner <s...@aol.com> wrote:

>
>Ron Jeffries wrote:
>> You'll find that I rarely say "I can't". However, at the stage where
>> the program just meets that first requirement, a frame object seems
>> premature to me, and to many other readers, because discernibly
>> simpler solutions exist at that moment in time.
>
>Simpler isn't inherently better. Clearer can be better. Understandable
>can be better. Faster can be better. Slower can be better. You can't
>argue better in only one dimension.

Certainly. I'm just reporting that to me, and to many other readers --
though not all -- introduction of a frame /object/ into the solution
seems premature, on the basis that it creates a solution that is more
complex than the situation warrants.


>
>
>> Some people like to build a solution that is in fact more ready for
>> the future. One of the lessons of Agile methods that I like to
>> demonstrate is how very little one needs to be concerned about this,
>> letting the current code meet the current requirements, and adapting
>> to new requirements as they arise.
>
>It's quite arrogant to assume you are demonstrating a lesson.

My articles report how I work, and what lessons I learn. Some people
enjoy reading them and some even say that they learn something.

The bowling game example came up, if I correctly recall, in a
demonstration of pair programming some years ago, at an XP Immersion
course that Bob Martin and I were teaching at Object Mentor.

It seems to be a good-sized example for experimenting with test-driven
development and refactoring, and it serves as a platform for many
interesting discussions about the design, the process, and so on.
That's why I do it.

Ron Jeffries

unread,
Jan 7, 2005, 5:37:56 PM1/7/05
to

Did I say that all [I] care about is the tests? I don't think so. I
would respectfully suggest that providing several different programs
all of which pass the tests, is in fact an exploration of the spirit
of programming.

But I'd certainly be delighted to see your examples of programs
solving the same problem with more of what you call "spirit". I think
that would be far more enlightening than name-calling.

I'd be happy to publish them with the other articles if you wished.
Not that that the publication is worth much, but all such articles are
welcome on my site. People do read and enjoy them.

Ron Jeffries

unread,
Jan 7, 2005, 5:46:00 PM1/7/05
to

Ideas matter, but they are not all that matters. Ideas are delightful
and fun to think. Programming, however, is about using those ideas to
create a program that meets some requirements.

The code has at least two purposes: to solve the problem through the
use of the ideas, and to communicate that solution, and the ideas, to
the human reader of the code.

The tests have at least two purposes as well: to demonstrate how the
program is called; to demonstrate that it gets the right answer in the
cases tested. Used as I use them in the test-driven style, the tests
also serve to guide the implementation and if expressed in a
"literate" form as in the articles, to illuminate the thought process
I used in the implementation.

Programming, it seems to me, involves ideas from beginning to end. But
it's making those ideas concrete in tests and code that differentiates
programming from daydreaming.

0 new messages