[squeak-dev] The Inbox: Kernel-nice.1120.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Nov 13 21:25:03 UTC 2017


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)!



More information about the Squeak-dev mailing list