The Inbox: Kernel-nice.1120.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Kernel-nice.1120.mcz

commits-2
Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1120.mcz

==================== Summary ====================

Name: Kernel-nice.1120
Author: nice
Time: 13 November 2017, 10:24:19.857289 pm
UUID: 24277641-be23-40ea-85ef-1db0d48f63d3
Ancestors: Kernel-mt.1119

1) Use // in Fraction>>gcd:, rather than / will was invoking the same gcd: computation 4 times!
2) Enhance the Fraction comment
 
The Fraction comment SHALL tell about the expected class invariants.
At least, it should help answering questions like:

https://stackoverflow.com/questions/46942103/squeak-smalltalk-why-sometimes-the-reduced-method-doesnt-work

https://stackoverflow.com/questions/46905203/squeak-smalltalk-why-reduction-of-a-fraction-does-not-happen-after-numerator-an

While at it, also tell why 3 isFraction answers true, and 3.0 asFraction -> an Integer, not a Fraction.
VW (st80?) has chosen better #isRational and #asRational messages for making things a bit more clear, but without a Rational superclass, it's not that obvious...

=============== Diff against Kernel-mt.1119 ===============

Item was changed:
  Number subclass: #Fraction
  instanceVariableNames: 'numerator denominator'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'Kernel-Numbers'!
 
+ !Fraction commentStamp: 'nice 11/13/2017 22:09' prior: 0!
+ Fraction provides methods for dealing with fractions like 1/3 as a ratio of two integers (as apposed to a decimal representation 0.33333...).
- !Fraction commentStamp: '<historical>' prior: 0!
- Fraction provides methods for dealing with fractions like 1/3 as fractions (not as 0.33333...).  All public arithmetic operations answer reduced fractions (see examples).
 
+ instance variables:
+ numerator <Integer> the number appearing before the fraction bar (above)
+ denominator <Integer> the number appearing after the fraction bar (below)
+
+ A Fraction is generally created by sending the message / to an Integer, like in
- instance variables: 'numerator denominator '
 
+     1 / 3
- Examples: (note the parentheses required to get the right answers in Smalltalk and Squeak):
 
+ Alternatively, it is possible to create a new instance of Fraction by sending #numerator:denominator: to the class.
+ In this later case, it is then user responsibility to ensure that it conforms to the following invariants:
+
+ - the denominator shall allways be positive.
+   A negative Fraction shall have a negative numerator, never a negative denominator.
+   Example: 1 / -3 will return -1/3
+ - the denominator shall allways be greater than 1.
+   A Fraction with denominator 1 shall be reduced to its numerator (an Integer).
+   Example 3 / 1 will answer 3 (the Integer) not 3/1
+ - the numerator and denominator shall never have common multiples.
+   Common multiples shall allways be simplified until (numerator gcd: denominator) = 1.
+   Example 8 / 6 will answer 4 / 3, because both 8=2*4 and 6=2*3 are both divisible by 2.
+
+ A Fraction non conforming to above invariants could be the cause of undefined behavior and unexpected results.
+ If unsure, it is advised to send the message #reduced to the freshly created instance so as to obtain a conforming Fraction, or an Integer.
+
+ Note that Fraction and Integer represent together the set of Rational numbers:
+ - Integer is a subset of rational (those which are whole numbers)
+ - Fraction is used for representing the complementary subset of rational (those which are not whole numbers)
+
+ There could have been a Rational superclass to both Integer and Fraction, and a message #isRational for testing if a Number is a Rational, as well as a message #asRational for converting a Number to a Rational.
+ But this level of indirection is not strictly necessary: instead, the notion of Rational and Fraction are collapsed in Squeak, and Integer are considered as a sort of special Fraction with unitary denominator.
+ Thus #isFraction is the testing message, to which every Integer will answer true, since considered as a sort of Fraction.
+ And #asFraction is the conversion message, that may answer an instance of Fraction of Integer, depending if the corresponding rational number is whole or not.
+
+ All public arithmetic operations will answer reduced fractions.
+ Examples:
+
  (2/3) + (2/3)
+ (2/3) + (1/2) "case showing reduction to common denominator"
+ (2/3) + (4/3) "case where result is reduced to an Integer"
+ (2/3) raisedToInteger: 5 "fractions also can be exponentiated"
- (2/3) + (1/2) "answers shows the reduced fraction"
- (2/3) raisedToInteger: 5 "fractions also can have exponents"
  !

Item was changed:
  ----- Method: Fraction>>gcd: (in category 'arithmetic') -----
  gcd: aFraction
  | d |
  d := denominator gcd: aFraction denominator.
+ ^(numerator *(aFraction denominator//d) gcd: aFraction numerator*(denominator//d)) / (denominator//d*aFraction denominator)!
- ^(numerator *(aFraction denominator/d) gcd: aFraction numerator*(denominator/d)) / (denominator/d*aFraction denominator)!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-nice.1120.mcz

Nicolas Cellier


2017-11-13 22:25 GMT+01:00 <[hidden email]>:
Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1120.mcz

==================== Summary ====================

Name: Kernel-nice.1120
Author: nice
Time: 13 November 2017, 10:24:19.857289 pm
UUID: 24277641-be23-40ea-85ef-1db0d48f63d3
Ancestors: Kernel-mt.1119

1) Use // in Fraction>>gcd:, rather than / will was invoking the same gcd: computation 4 times!
argh, "which was invoking", I did not finish to rephrase :(

2) Enhance the Fraction comment
This is in inbox because a class comment is something difficult to make right and will benefit peer advices.
Feel free to improve!


The Fraction comment SHALL tell about the expected class invariants.
At least, it should help answering questions like:

https://stackoverflow.com/questions/46942103/squeak-smalltalk-why-sometimes-the-reduced-method-doesnt-work

https://stackoverflow.com/questions/46905203/squeak-smalltalk-why-reduction-of-a-fraction-does-not-happen-after-numerator-an

While at it, also tell why 3 isFraction answers true, and 3.0 asFraction -> an Integer, not a Fraction.
VW (st80?) has chosen better #isRational and #asRational messages for making things a bit more clear, but without a Rational superclass, it's not that obvious...

=============== Diff against Kernel-mt.1119 ===============

Item was changed:
  Number subclass: #Fraction
        instanceVariableNames: 'numerator denominator'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Kernel-Numbers'!

+ !Fraction commentStamp: 'nice 11/13/2017 22:09' prior: 0!
+ Fraction provides methods for dealing with fractions like 1/3 as a ratio of two integers (as apposed to a decimal representation 0.33333...).
- !Fraction commentStamp: '<historical>' prior: 0!
- Fraction provides methods for dealing with fractions like 1/3 as fractions (not as 0.33333...).  All public arithmetic operations answer reduced fractions (see examples).

+ instance variables:
+       numerator       <Integer> the number appearing before the fraction bar (above)
+       denominator     <Integer> the number appearing after the fraction bar (below)
+
+ A Fraction is generally created by sending the message / to an Integer, like in
- instance variables: 'numerator denominator '

+     1 / 3
- Examples: (note the parentheses required to get the right answers in Smalltalk and Squeak):

+ Alternatively, it is possible to create a new instance of Fraction by sending #numerator:denominator: to the class.
+ In this later case, it is then user responsibility to ensure that it conforms to the following invariants:
+
+ - the denominator shall allways be positive.
+   A negative Fraction shall have a negative numerator, never a negative denominator.
+   Example: 1 / -3 will return -1/3
+ - the denominator shall allways be greater than 1.
+   A Fraction with denominator 1 shall be reduced to its numerator (an Integer).
+   Example 3 / 1 will answer 3 (the Integer) not 3/1
+ - the numerator and denominator shall never have common multiples.
+   Common multiples shall allways be simplified until (numerator gcd: denominator) = 1.
+   Example 8 / 6 will answer 4 / 3, because both 8=2*4 and 6=2*3 are both divisible by 2.
+
+ A Fraction non conforming to above invariants could be the cause of undefined behavior and unexpected results.
+ If unsure, it is advised to send the message #reduced to the freshly created instance so as to obtain a conforming Fraction, or an Integer.
+
+ Note that Fraction and Integer represent together the set of Rational numbers:
+ - Integer is a subset of rational (those which are whole numbers)
+ - Fraction is used for representing the complementary subset of rational (those which are not whole numbers)
+
+ There could have been a Rational superclass to both Integer and Fraction, and a message #isRational for testing if a Number is a Rational, as well as a message #asRational for converting a Number to a Rational.
+ But this level of indirection is not strictly necessary: instead, the notion of Rational and Fraction are collapsed in Squeak, and Integer are considered as a sort of special Fraction with unitary denominator.
+ Thus #isFraction is the testing message, to which every Integer will answer true, since considered as a sort of Fraction.
+ And #asFraction is the conversion message, that may answer an instance of Fraction of Integer, depending if the corresponding rational number is whole or not.
+
+ All public arithmetic operations will answer reduced fractions.
+ Examples:
+
  (2/3) + (2/3)
+ (2/3) + (1/2)         "case showing reduction to common denominator"
+ (2/3) + (4/3)         "case where result is reduced to an Integer"
+ (2/3) raisedToInteger: 5               "fractions also can be exponentiated"
- (2/3) + (1/2)          "answers shows the reduced fraction"
- (2/3) raisedToInteger: 5               "fractions also can have exponents"
  !

Item was changed:
  ----- Method: Fraction>>gcd: (in category 'arithmetic') -----
  gcd: aFraction
        | d |
        d := denominator gcd: aFraction denominator.
+       ^(numerator *(aFraction denominator//d) gcd: aFraction numerator*(denominator//d)) / (denominator//d*aFraction denominator)!
-       ^(numerator *(aFraction denominator/d) gcd: aFraction numerator*(denominator/d)) / (denominator/d*aFraction denominator)!





Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-nice.1120.mcz

Nicolas Cellier


2017-11-13 22:29 GMT+01:00 Nicolas Cellier <[hidden email]>:


2017-11-13 22:25 GMT+01:00 <[hidden email]>:
Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1120.mcz

==================== Summary ====================

Name: Kernel-nice.1120
Author: nice
Time: 13 November 2017, 10:24:19.857289 pm
UUID: 24277641-be23-40ea-85ef-1db0d48f63d3
Ancestors: Kernel-mt.1119

1) Use // in Fraction>>gcd:, rather than / will was invoking the same gcd: computation 4 times!
argh, "which was invoking", I did not finish to rephrase :(

2) Enhance the Fraction comment
This is in inbox because a class comment is something difficult to make right and will benefit peer advices.
benefit from, but it seems my hands are a bit decoupled from my brain this evening...
Feel free to improve!


The Fraction comment SHALL tell about the expected class invariants.
At least, it should help answering questions like:

https://stackoverflow.com/questions/46942103/squeak-smalltalk-why-sometimes-the-reduced-method-doesnt-work

https://stackoverflow.com/questions/46905203/squeak-smalltalk-why-reduction-of-a-fraction-does-not-happen-after-numerator-an

While at it, also tell why 3 isFraction answers true, and 3.0 asFraction -> an Integer, not a Fraction.
VW (st80?) has chosen better #isRational and #asRational messages for making things a bit more clear, but without a Rational superclass, it's not that obvious...

=============== Diff against Kernel-mt.1119 ===============

Item was changed:
  Number subclass: #Fraction
        instanceVariableNames: 'numerator denominator'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Kernel-Numbers'!

+ !Fraction commentStamp: 'nice 11/13/2017 22:09' prior: 0!
+ Fraction provides methods for dealing with fractions like 1/3 as a ratio of two integers (as apposed to a decimal representation 0.33333...).
- !Fraction commentStamp: '<historical>' prior: 0!
- Fraction provides methods for dealing with fractions like 1/3 as fractions (not as 0.33333...).  All public arithmetic operations answer reduced fractions (see examples).

+ instance variables:
+       numerator       <Integer> the number appearing before the fraction bar (above)
+       denominator     <Integer> the number appearing after the fraction bar (below)
+
+ A Fraction is generally created by sending the message / to an Integer, like in
- instance variables: 'numerator denominator '

+     1 / 3
- Examples: (note the parentheses required to get the right answers in Smalltalk and Squeak):

+ Alternatively, it is possible to create a new instance of Fraction by sending #numerator:denominator: to the class.
+ In this later case, it is then user responsibility to ensure that it conforms to the following invariants:
+
+ - the denominator shall allways be positive.
+   A negative Fraction shall have a negative numerator, never a negative denominator.
+   Example: 1 / -3 will return -1/3
+ - the denominator shall allways be greater than 1.
+   A Fraction with denominator 1 shall be reduced to its numerator (an Integer).
+   Example 3 / 1 will answer 3 (the Integer) not 3/1
+ - the numerator and denominator shall never have common multiples.
+   Common multiples shall allways be simplified until (numerator gcd: denominator) = 1.
+   Example 8 / 6 will answer 4 / 3, because both 8=2*4 and 6=2*3 are both divisible by 2.
+
+ A Fraction non conforming to above invariants could be the cause of undefined behavior and unexpected results.
+ If unsure, it is advised to send the message #reduced to the freshly created instance so as to obtain a conforming Fraction, or an Integer.
+
+ Note that Fraction and Integer represent together the set of Rational numbers:
+ - Integer is a subset of rational (those which are whole numbers)
+ - Fraction is used for representing the complementary subset of rational (those which are not whole numbers)
+
+ There could have been a Rational superclass to both Integer and Fraction, and a message #isRational for testing if a Number is a Rational, as well as a message #asRational for converting a Number to a Rational.
+ But this level of indirection is not strictly necessary: instead, the notion of Rational and Fraction are collapsed in Squeak, and Integer are considered as a sort of special Fraction with unitary denominator.
+ Thus #isFraction is the testing message, to which every Integer will answer true, since considered as a sort of Fraction.
+ And #asFraction is the conversion message, that may answer an instance of Fraction of Integer, depending if the corresponding rational number is whole or not.
+
+ All public arithmetic operations will answer reduced fractions.
+ Examples:
+
  (2/3) + (2/3)
+ (2/3) + (1/2)         "case showing reduction to common denominator"
+ (2/3) + (4/3)         "case where result is reduced to an Integer"
+ (2/3) raisedToInteger: 5               "fractions also can be exponentiated"
- (2/3) + (1/2)          "answers shows the reduced fraction"
- (2/3) raisedToInteger: 5               "fractions also can have exponents"
  !

Item was changed:
  ----- Method: Fraction>>gcd: (in category 'arithmetic') -----
  gcd: aFraction
        | d |
        d := denominator gcd: aFraction denominator.
+       ^(numerator *(aFraction denominator//d) gcd: aFraction numerator*(denominator//d)) / (denominator//d*aFraction denominator)!
-       ^(numerator *(aFraction denominator/d) gcd: aFraction numerator*(denominator/d)) / (denominator/d*aFraction denominator)!






Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-nice.1120.mcz

Tobias Pape
In reply to this post by Nicolas Cellier

> On 13.11.2017, at 22:29, Nicolas Cellier <[hidden email]> wrote:
>
> argh, "which was invoking", I did not finish to rephrase :(
>
> 2) Enhance the Fraction comment
> This is in inbox because a class comment is something difficult to make right and will benefit peer advices.
> Feel free to improve!

I like :)
Well stated comment.

+1

Best regards
        -Tobias

Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Kernel-nice.1120.mcz

Nicolas Cellier
In reply to this post by Nicolas Cellier


2017-11-13 22:30 GMT+01:00 Nicolas Cellier <[hidden email]>:


2017-11-13 22:29 GMT+01:00 Nicolas Cellier <[hidden email]>:


2017-11-13 22:25 GMT+01:00 <[hidden email]>:
Nicolas Cellier uploaded a new version of Kernel to project The Inbox:
http://source.squeak.org/inbox/Kernel-nice.1120.mcz

==================== Summary ====================

Name: Kernel-nice.1120
Author: nice
Time: 13 November 2017, 10:24:19.857289 pm
UUID: 24277641-be23-40ea-85ef-1db0d48f63d3
Ancestors: Kernel-mt.1119

1) Use // in Fraction>>gcd:, rather than / will was invoking the same gcd: computation 4 times!
argh, "which was invoking", I did not finish to rephrase :(

2) Enhance the Fraction comment
This is in inbox because a class comment is something difficult to make right and will benefit peer advices.
benefit from, but it seems my hands are a bit decoupled from my brain this evening...
Feel free to improve!


The Fraction comment SHALL tell about the expected class invariants.
At least, it should help answering questions like:

https://stackoverflow.com/questions/46942103/squeak-smalltalk-why-sometimes-the-reduced-method-doesnt-work

https://stackoverflow.com/questions/46905203/squeak-smalltalk-why-reduction-of-a-fraction-does-not-happen-after-numerator-an

While at it, also tell why 3 isFraction answers true, and 3.0 asFraction -> an Integer, not a Fraction.
VW (st80?) has chosen better #isRational and #asRational messages for making things a bit more clear, but without a Rational superclass, it's not that obvious...

=============== Diff against Kernel-mt.1119 ===============

Item was changed:
  Number subclass: #Fraction
        instanceVariableNames: 'numerator denominator'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'Kernel-Numbers'!

+ !Fraction commentStamp: 'nice 11/13/2017 22:09' prior: 0!
+ Fraction provides methods for dealing with fractions like 1/3 as a ratio of two integers (as apposed to a decimal representation 0.33333...).
- !Fraction commentStamp: '<historical>' prior: 0!
- Fraction provides methods for dealing with fractions like 1/3 as fractions (not as 0.33333...).  All public arithmetic operations answer reduced fractions (see examples).

+ instance variables:
+       numerator       <Integer> the number appearing before the fraction bar (above)
+       denominator     <Integer> the number appearing after the fraction bar (below)
+
+ A Fraction is generally created by sending the message / to an Integer, like in
- instance variables: 'numerator denominator '

+     1 / 3
- Examples: (note the parentheses required to get the right answers in Smalltalk and Squeak):

+ Alternatively, it is possible to create a new instance of Fraction by sending #numerator:denominator: to the class.
+ In this later case, it is then user responsibility to ensure that it conforms to the following invariants:
+
+ - the denominator shall allways be positive.
+   A negative Fraction shall have a negative numerator, never a negative denominator.
+   Example: 1 / -3 will return -1/3
+ - the denominator shall allways be greater than 1.
+   A Fraction with denominator 1 shall be reduced to its numerator (an Integer).
+   Example 3 / 1 will answer 3 (the Integer) not 3/1
+ - the numerator and denominator shall never have common multiples.
+   Common multiples shall allways be simplified until (numerator gcd: denominator) = 1.
+   Example 8 / 6 will answer 4 / 3, because both 8=2*4 and 6=2*3 are both divisible by 2.
+
+ A Fraction non conforming to above invariants could be the cause of undefined behavior and unexpected results.
+ If unsure, it is advised to send the message #reduced to the freshly created instance so as to obtain a conforming Fraction, or an Integer.
+
+ Note that Fraction and Integer represent together the set of Rational numbers:
+ - Integer is a subset of rational (those which are whole numbers)
+ - Fraction is used for representing the complementary subset of rational (those which are not whole numbers)
+
+ There could have been a Rational superclass to both Integer and Fraction, and a message #isRational for testing if a Number is a Rational, as well as a message #asRational for converting a Number to a Rational.
+ But this level of indirection is not strictly necessary: instead, the notion of Rational and Fraction are collapsed in Squeak, and Integer are considered as a sort of special Fraction with unitary denominator.
+ Thus #isFraction is the testing message, to which every Integer will answer true, since considered as a sort of Fraction.
+ And #asFraction is the conversion message, that may answer an instance of Fraction of Integer, depending if the corresponding rational number is whole or not.
+

of Fraction OR Integer...

+ All public arithmetic operations will answer reduced fractions.
+ Examples:
+
  (2/3) + (2/3)
+ (2/3) + (1/2)         "case showing reduction to common denominator"
+ (2/3) + (4/3)         "case where result is reduced to an Integer"
+ (2/3) raisedToInteger: 5               "fractions also can be exponentiated"
- (2/3) + (1/2)          "answers shows the reduced fraction"
- (2/3) raisedToInteger: 5               "fractions also can have exponents"
  !

Item was changed:
  ----- Method: Fraction>>gcd: (in category 'arithmetic') -----
  gcd: aFraction
        | d |
        d := denominator gcd: aFraction denominator.
+       ^(numerator *(aFraction denominator//d) gcd: aFraction numerator*(denominator//d)) / (denominator//d*aFraction denominator)!
-       ^(numerator *(aFraction denominator/d) gcd: aFraction numerator*(denominator/d)) / (denominator/d*aFraction denominator)!