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

2020-02-15 Thread Richard O'Keefe
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  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 
> :
>>
>> 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
>>



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

2019-12-30 Thread ponyatov
What Smalltalk has for full-sized pattern matching?
Is it possible to make in message-only syntax?



--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



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

2019-12-30 Thread Richard Sargent
Pharo Smalltalk Users mailing list wrote
> 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 ? 

Roelof, this example is too simple to "really do it the Smalltalk way".

In a more realistic scenario, you would have classes for each "rule" with
corresponding differences in behaviour. In the above example, you could get
away with a single class with two instance variables and configure three
instances of it appropriately.

In more complex scenarios, your start up code instantiates the various
rules, with precedence determined by the order of the rule instances. Then
when you need to determine which rule to apply, you use #detect:ifNone: to
find the rule that applies with the #ifNone: block providing the fallback
result.

Sometimes, you work with classes themselves to determine which class to use,
but I have described working with instances for the general concept. (After
all, classes are instances.)

Using rules with a #select: allows you to handle a scenario where multiple
rules apply. A good example is rules to provide the default coverages for an
auto insurance policy, where each possible coverage can have one or more
rules to assess the many characteristics of the applicants and so determine
the one rule that applies for each possible coverage. (And yes, it is
reasonable that a possible coverage has no rule applicable, in which case
the coverage is not included in the default offering.)


As mentioned, you /could/ apply this to your scenario, as an exercise. You
might be tempted to utilize an existing class with two instance variables.
That would be a bad design practice, but reasonable for a /disposable/
experiment to quickly study how it works. Always (create and) use classes
which truly reflect their purpose and have named properties which truly
reflect the objects they hold. In your scenario, #distance and #score seem
appropriate.

  

>   
>   Regards, 
>   
>   Roelof





--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



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

2019-12-29 Thread Esteban Lorenzano
The “Kent Beck approved solutions” here are two: 

1) To use a dictionary (or ordered dictionary).


case := OrderedDictionary newFromPairs: {
[ cond ]. [ do ].
[ cond ]. [ do ].
[ true ]. [ otherwise do ] }

case keysAndValuesDo: [  :cond :do | 
(cond value: expression)  ifTrue: [
“you need to break here"
^ do value ].

2) To use a “case method”

caseMethod: expression 

expression = cond1 ifTrue: [ ^ do1 ].
expression = cond2 ifTrue: [ ^ do2 ].
^ otherwise

Personally, I prefer the second one because is more concise, performant and 
easy to understand.

Esteban


> On 28 Dec 2019, at 11:58, Dennis Schetinin  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 
> mailto:pharo-users@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
> 



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

2019-12-28 Thread Dennis Schetinin
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@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
>
>


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

2019-12-27 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

Hello Richard,

Thanks for the feedback. I was using it because the challenge was 
talking about it, that yu have the use the formula
a ^2  +  b ^2  =  c ^2   and the challenge was talking about the 
distance and not the distance squared.


I think a better name schould be then x or xCoordinate and y or 
Y_Coordinate.


Roelof



Op 27-12-2019 om 22:48 schreef Richard O'Keefe:

Myself, I see only one issue in your code, and that is the pointless
use of sqrt.
scoreX: anInteger y: anInteger2
 | radiusSquared |
 radiusSquared := anInteger squared + anInteger2 squared.
 radiusSquared > 100
 ifTrue: [ ^ 0 ].
 radiusSquared > 25
 ifTrue: [ ^ 1 ].
 radiusSquared > 1
 ifTrue: [ ^ 5 ].
 ^ 10

Make that two issues.  The names anInteger and anInteger2.
How about
scoreHorizontal: horizontal vertical: vertical
   ...

The OO dogma about "if' that you refer to is about not using
"if" to make decisions based on TYPE.  Making decisions based
on NUMERIC RANGES is perfectly OK.

You could introduce a 'HalfOpenRangeDictionary" class
[K1,K2) -> V1
[K2,K3) -> V2
...
[Kn,infinity) -> Vn
But "You Ain't Gonna Need It", so don't.

On Sat, 28 Dec 2019 at 08:18, Roelof Wobben via Pharo-users
 wrote:

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




--- End Message ---


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

2019-12-27 Thread Richard O'Keefe
Myself, I see only one issue in your code, and that is the pointless
use of sqrt.
scoreX: anInteger y: anInteger2
| radiusSquared |
radiusSquared := anInteger squared + anInteger2 squared.
radiusSquared > 100
ifTrue: [ ^ 0 ].
radiusSquared > 25
ifTrue: [ ^ 1 ].
radiusSquared > 1
ifTrue: [ ^ 5 ].
^ 10

Make that two issues.  The names anInteger and anInteger2.
How about
scoreHorizontal: horizontal vertical: vertical
  ...

The OO dogma about "if' that you refer to is about not using
"if" to make decisions based on TYPE.  Making decisions based
on NUMERIC RANGES is perfectly OK.

You could introduce a 'HalfOpenRangeDictionary" class
[K1,K2) -> V1
[K2,K3) -> V2
...
[Kn,infinity) -> Vn
But "You Ain't Gonna Need It", so don't.

On Sat, 28 Dec 2019 at 08:18, Roelof Wobben via Pharo-users
 wrote:
>
> 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
>



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

2019-12-27 Thread tbrunz
You could also accomplish this with a simple 'do:' construct by creating the
associations with the the ring limits & points "staggered" (by one level),
so that when (each < key) you can return the 'current' association value...

Which, now that I'm looking closely at your solution, Kasper, seems to be
what you already proposed...  Either should work.



--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



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

2019-12-27 Thread tbrunz
Doing it the way I describe above eliminates repetitive if-then statements
('switch' or 'case' statements in other languages, which make for a
maintenance mess), automatically extends for additional rings, doesn't embed
"magic numbers" for defined rings within the decision logic, and takes
advantage of the naturally recursive nature of this kind of graduated
comparison test.

-t



--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



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

2019-12-27 Thread tbrunz
I would probably set up an array of associations whose keys are the boundary
limits and whose values are the target values (ordered, in this example,
from outer to inner).  

Then loop over the array's associations using inject:into:, testing for the
point where (each < key), at which point you return the previous
association's value.

-t




--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



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

2019-12-27 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

  
  
Hello Kasper
  
  Thanks for the feedback.
  
  I also like readable and  easy to understand code but I get the
  feeling that it;s good practice to use as minimal as possible if
  then's 
  So I wonder if and how I can achieve that here.
  
  Roelof
  
  
  Op 27-12-2019 om 20:47 schreef Kasper Østerbye:


  
  
  Hi
  
  
  First, I
think your code is readable and easy to understand.
  
  
  I think
the problem does not lend itself too much towards having “an
object oriented solution”, as such.
  
  
  If you are
looking for a one-liner using smalltalk libraries, you could do:
  ({10 ->
0. 5 -> 1. 1 -> 5. 0 -> 10} detect: [ :dist | dist key
< distance ]) value
  
  
  but I
really think your code is easier to read, which is what I
appreciate the most.
  
  
  Best,
  
  
  Kasper

On 27 December 2019 at 20.18.38, Roelof
  Wobben via Pharo-users (pharo-users@lists.pharo.org)
  wrote:


  

  
  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
  

  

  
  


  


--- End Message ---


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

2019-12-27 Thread Kasper Østerbye
Hi

First, I think your code is readable and easy to understand.

I think the problem does not lend itself too much towards having “an object
oriented solution”, as such.

If you are looking for a one-liner using smalltalk libraries, you could do:
({10 -> 0. 5 -> 1. 1 -> 5. 0 -> 10} detect: [ :dist | dist key < distance
]) value

but I really think your code is easier to read, which is what I appreciate
the most.

Best,

Kasper

On 27 December 2019 at 20.18.38, Roelof Wobben via Pharo-users (
pharo-users@lists.pharo.org) wrote:

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


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

2019-12-27 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

Thanks,

But it looks to me I still need the ifTrue because the between gives 
also a true or false.


Roelof



Op 27-12-2019 om 20:38 schreef tbrunz:

You might try Magnitude >> between: min and: max




--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html





--- End Message ---


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

2019-12-27 Thread tbrunz
You might try Magnitude >> between: min and: max 




--
Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html



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

2019-12-27 Thread Roelof Wobben via Pharo-users
--- Begin Message ---

  
  
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

  


--- End Message ---