<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-11-13 22:29 GMT+01:00 Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">2017-11-13 22:25 GMT+01:00  <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Nicolas Cellier uploaded a new version of Kernel to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Kernel-nice.1120.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/inbox<wbr>/Kernel-nice.1120.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-nice.1120<br>
Author: nice<br>
Time: 13 November 2017, 10:24:19.857289 pm<br>
UUID: 24277641-be23-40ea-85ef-1db0d4<wbr>8f63d3<br>
Ancestors: Kernel-mt.1119<br>
<br>
1) Use // in Fraction>>gcd:, rather than / will was invoking the same gcd: computation 4 times!<br></blockquote></span><div>argh, "which was invoking", I did not finish to rephrase :(</div><span class=""><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2) Enhance the Fraction comment<br></blockquote></span><div>This is in inbox because a class comment is something difficult to make right and will benefit peer advices.</div></div></div></div></blockquote><div>benefit from, but it seems my hands are a bit decoupled from my brain this evening... <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Feel free to improve!</div><div><div class="h5"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
The Fraction comment SHALL tell about the expected class invariants.<br>
At least, it should help answering questions like:<br>
<br>
<a href="https://stackoverflow.com/questions/46942103/squeak-smalltalk-why-sometimes-the-reduced-method-doesnt-work" rel="noreferrer" target="_blank">https://stackoverflow.com/ques<wbr>tions/46942103/squeak-smalltal<wbr>k-why-sometimes-the-reduced-<wbr>method-doesnt-work</a><br>
<br>
<a href="https://stackoverflow.com/questions/46905203/squeak-smalltalk-why-reduction-of-a-fraction-does-not-happen-after-numerator-an" rel="noreferrer" target="_blank">https://stackoverflow.com/ques<wbr>tions/46905203/squeak-smalltal<wbr>k-why-reduction-of-a-fraction-<wbr>does-not-happen-after-<wbr>numerator-an</a><br>
<br>
While at it, also tell why 3 isFraction answers true, and 3.0 asFraction -> an Integer, not a Fraction.<br>
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...<br>
<br>
=============== Diff against Kernel-mt.1119 ===============<br>
<br>
Item was changed:<br>
  Number subclass: #Fraction<br>
        instanceVariableNames: 'numerator denominator'<br>
        classVariableNames: ''<br>
        poolDictionaries: ''<br>
        category: 'Kernel-Numbers'!<br>
<br>
+ !Fraction commentStamp: 'nice 11/13/2017 22:09' prior: 0!<br>
+ Fraction provides methods for dealing with fractions like 1/3 as a ratio of two integers (as apposed to a decimal representation 0.33333...).<br>
- !Fraction commentStamp: '<historical>' prior: 0!<br>
- 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).<br>
<br>
+ instance variables:<br>
+       numerator       <Integer> the number appearing before the fraction bar (above)<br>
+       denominator     <Integer> the number appearing after the fraction bar (below)<br>
+<br>
+ A Fraction is generally created by sending the message / to an Integer, like in<br>
- instance variables: 'numerator denominator '<br>
<br>
+     1 / 3<br>
- Examples: (note the parentheses required to get the right answers in Smalltalk and Squeak):<br>
<br>
+ Alternatively, it is possible to create a new instance of Fraction by sending #numerator:denominator: to the class.<br>
+ In this later case, it is then user responsibility to ensure that it conforms to the following invariants:<br>
+<br>
+ - the denominator shall allways be positive.<br>
+   A negative Fraction shall have a negative numerator, never a negative denominator.<br>
+   Example: 1 / -3 will return -1/3<br>
+ - the denominator shall allways be greater than 1.<br>
+   A Fraction with denominator 1 shall be reduced to its numerator (an Integer).<br>
+   Example 3 / 1 will answer 3 (the Integer) not 3/1<br>
+ - the numerator and denominator shall never have common multiples.<br>
+   Common multiples shall allways be simplified until (numerator gcd: denominator) = 1.<br>
+   Example 8 / 6 will answer 4 / 3, because both 8=2*4 and 6=2*3 are both divisible by 2.<br>
+<br>
+ A Fraction non conforming to above invariants could be the cause of undefined behavior and unexpected results.<br>
+ 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.<br>
+<br>
+ Note that Fraction and Integer represent together the set of Rational numbers:<br>
+ - Integer is a subset of rational (those which are whole numbers)<br>
+ - Fraction is used for representing the complementary subset of rational (those which are not whole numbers)<br>
+<br>
+ 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.<br>
+ 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.<br>
+ Thus #isFraction is the testing message, to which every Integer will answer true, since considered as a sort of Fraction.<br>
+ 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.<br>
+<br>
+ All public arithmetic operations will answer reduced fractions.<br>
+ Examples:<br>
+<br>
  (2/3) + (2/3)<br>
+ (2/3) + (1/2)         "case showing reduction to common denominator"<br>
+ (2/3) + (4/3)         "case where result is reduced to an Integer"<br>
+ (2/3) raisedToInteger: 5               "fractions also can be exponentiated"<br>
- (2/3) + (1/2)          "answers shows the reduced fraction"<br>
- (2/3) raisedToInteger: 5               "fractions also can have exponents"<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: Fraction>>gcd: (in category 'arithmetic') -----<br>
  gcd: aFraction<br>
        | d |<br>
        d := denominator gcd: aFraction denominator.<br>
+       ^(numerator *(aFraction denominator//d) gcd: aFraction numerator*(denominator//d)) / (denominator//d*aFraction denominator)!<br>
-       ^(numerator *(aFraction denominator/d) gcd: aFraction numerator*(denominator/d)) / (denominator/d*aFraction denominator)!<br>
<br>
<br>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>