[Pharo-users] can I write this without the three if then;s

Richard O'Keefe raoknz at gmail.com
Sat Feb 15 09:02:49 EST 2020


Start with
scoreX: anInteger y: anInteger2
    | distance |
    distance := (anInteger squared + anInteger2 squared) sqrt.
    distance > 10
        ifTrue: [ ^ 0 ].
    distance > 5
        ifTrue: [ ^ 1 ].
    distance > 1
        ifTrue: [ ^ 5 ].
    ^ 10

(1) Use better argument names.
(2) Forget about the square root.
(3) Note the repetitive pattern.
So
scoreX: x y: y
    | distanceSquared |
    distanceSquared := x squared + y squared.
    #((100 0) (25 1) (1 5)) do: [:each |
        distanceSquared > each first ifTrue: [^each last]].
    ^10

But I'd say that apart from the argument names and pointless square root,
your original code is about as clear as it gets.
The "ifs stink" dogma is about *type* testing, not *range* testing,
and this is range testing.  It is also a tiny piece of code which
can only be made *less* readable by trying to avoid the ifs.
Remember the slogan YAGNI?  You Ain't Gonna Need it?
The time to go for a more elaborate solution is when you HAVE to.
Do The Simplest Thing That Could Possibly Work.

On Sat, 28 Dec 2019 at 23:59, Dennis Schetinin <chaetal at gmail.com> wrote:
>
> It would be an overkill to do it for this particular case, but Smalltalk makes it possible to implement a case-like construction:
>
> [ expression ]
>      when: [ :value | condition1 ] do: [-0do :value | ... ];
>      when: [ :value | condition2 ] do: [ :value | ... ];
>      otherwiseDo: [ :value | ... ];
>      evaluate
>
>
> I am sure, something like this has been implemented already somewhere (maybe in Squeak?). Still not sure it is practical as compared to simple if-s, and for sure not widely used :)
> ...On the other hand, sometimes the case-like construction can be considered a more intension-revealing style.
>
> пт, 27 дек. 2019 г., 22:18 Roelof Wobben via Pharo-users <pharo-users at lists.pharo.org>:
>>
>> Hello,
>>
>> Im trying to solve a challenge from exercism where  I have to calculate the points somehow gets on a very simple darts board.
>>
>> I solved it like this :
>>
>>
>> scoreX: anInteger y: anInteger2
>>     | distance |
>>     distance := (anInteger squared + anInteger2 squared) sqrt.
>>     distance > 10
>>         ifTrue: [ ^ 0 ].
>>     distance > 5
>>         ifTrue: [ ^ 1 ].
>>     distance > 1
>>         ifTrue: [ ^ 5 ].
>>     ^ 10
>>
>>
>> but now I use three if then and I think it's ugly code.
>>
>> Is there a way I can make it more the smalltalk way ?
>>
>>
>> Regards,
>>
>> Roelof
>>



More information about the Pharo-users mailing list