<div class="gmail_quote">On Sat, Aug 28, 2010 at 20:38, David Simcha <span dir="ltr">&lt;<a href="mailto:dsimcha@gmail.com">dsimcha@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000">

  
    
  
  <div class="im"><blockquote type="cite"><div class="gmail_quote">
      </div>
    </blockquote>
    <br></div>&gt; Let say from nom on, I prefix everything with rational.<br>
        
    Don&#39;t worry about module issues.  As Lars pointed out, the library
    will not be named rational if/when it&#39;s integrated into Phobos.  It
    will be std.rational or be included in std.numerics</div></blockquote><div><br> Yes, you&#39;re right.<br></div><div><br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000"><div class="im"><blockquote type="cite"><div class="gmail_quote"><div><br>
          auto r = rational(1,2);<br>
          r = 1; // do not work.<br>
          <br>
          Maybe you could add opAssign from integer numbers?<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    I fixed this right after I sent out the request for comment, because
    I realized that not allowing it was a bit silly.  Unfortunately, I
    accidentally sent a link that pointed to a specific revision. 
    Here&#39;s a new link that updates will be reflected in: 
    <a href="http://dsource.org/projects/scrapple/browser/trunk/rational/rational.d" target="_blank">http://dsource.org/projects/scrapple/browser/trunk/rational/rational.d</a><div class="im"><br></div></div></blockquote>
<div><br>Good.<br><br>line 76: isAssignable would be a good addition to std.traits.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000"><div class="im"><blockquote type="cite">
      <div class="gmail_quote">
        <div>
          <br>
          Next, 1/0. OK, it&#39;s correctly dealt with (Integer Divide By
          Zero Error)<br>
          But 0/1 botches. In fact, any rational that&#39;s zero creates a
          DBZ error. r-= r, etc.<br>
          I guess it&#39;s a pb in simplify (454-455) or gcf (638), you
          should test for a zero numerator or divisor<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    I can&#39;t believe I forgot to test this edge case.  Fixed by simply
    testing for zero as a special case in simplify().</div></blockquote><div><br>Put in some very basic unit tests :-)  0+0==0, 1-1==0, that kind of thing :)<br><br><br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000"><div class="im"><br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>
          <br>
          Now, for the code itself:<br>
          line 35: Maybe you should add %, %=, they are part of what I
          consider &#39;integer like&#39;. You use them in gcf anyway<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    Good point.  Done.  Also added comparison.</div></blockquote><div><br>Man, integer-like is beginning to be quite big.<br><br>What about adding ++ and -- ?<br><br>Btw, I&#39;m against putting ++ and -- in Rational, but please do add opUnary!&quot;+&quot;, opUnary!&quot;-&quot;.<br>
<br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000"><div class="im">
    <blockquote type="cite">
      <div class="gmail_quote">
        <div><br>
          As an aside, isIntegerLike, the equivalent isFloatingPointLike
          and defineOperators!( some string tuple) could be interesting
          additions to std.traits. <br>
          I don&#39;t know what FP-like would be, maybe test for values
          between 0 and 1, and test for NaN.<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    You may be right, but I&#39;d rather wait until more user defined
    integer and floating point types are around to see exactly what such
    templates should require.</div></blockquote><div><br>You&#39;re right. As of now, I see three traits: <br>isNumeric (ie, defines + - / * and is ordered: defines &lt; &gt; ==), <br>isIntegerLike(isNumeric, and % &lt;&lt; &gt;&gt; &lt;&lt;&lt; ++ --), <br>
isFPLike(isNumeric, and (0.0+1.0)/2.0 is not zero)<br>As I&#39;m no specialist of floating points, I&#39;ll let other decide.<br> <br>So, there is also isOrdered or isComparable for opCmp and opEqual<br><br>Hmm, asking for NaN to be FP might not be a good idea: wasn&#39;t there some plan to build a BigDecimal type at some point? I gather BigDecimal wouldn&#39;t have NaN.<br>
I tried to do one 2 years ago, built on BigInt+decimal point position. I remember it to be awfully buggy :-)<br><br>I also tried to represent &#39;real&#39; real numbers with a BigInt + an infinite range (for the part after the .), but that was a mistake :)<br>
<br><br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000"><div class="im">
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div><br>
          75: if you make it public, you should add a template
          constraint if(isIntegral!I1 &amp;&amp; isIntegral!i2). The
          same for gcf at line 640<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    Good point.  Fixed.<br></div></blockquote><div><br>I wasn&#39;t sure you wanted to make this public.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000">
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>
          76: why * instead of +?<br>
        </div>
      </div>
    </blockquote>
    <br>
    No particular reason.  Any reasonable type should return the same
    type for either one.  I can&#39;t see why it would matter either way.</div></blockquote><div><br>It shouldn&#39;t. That was just curiosity on my part. I&#39;d have use an addition.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000"><div class="im"><br><blockquote type="cite"><div class="gmail_quote"><div>
          559: could toRational be a constructor? auto r = rational(PI,
          1e-8);<br>
        </div>
      </div>
    </blockquote><br>
    <br></div>
    I&#39;d rather leave it as a free function for a few reasons:<br>
    <br>
    1.  In general the convention in Phobos is that non-trivial
    construction steps for structs are done in free functions.  Even
    though the reasons for that convention don&#39;t apply here, I&#39;d rather
    follow it unless there&#39;s really a good reason to violate it.<br>
    <br>
    2.  IIRC templated constructors are generally buggy, though I can&#39;t
    remember specifically how they&#39;re buggy.<br>
    <br>
    3.  Lower case names are easier to type and read.<br>
    <br>
    4.  It&#39;s what I already have written and I&#39;m lazy. :-)<br>
    <br>
    I don&#39;t feel very strongly about this, though.  If you really feel
    strongly that it should be a constructor, though, and can explain
    why, then I&#39;m willing to reconsider.<div class="im"><br></div></div></blockquote><div><br>I meant a factory function, not a real constructor per se. See my example: auto r = rational(PI, 1e-8);<br>It takes care of point 1, 2 and 3. As for 4, maybe just an alias would be ok?<br>
<br>But I see in any case, the user has to provide the integer type she wants to use, so my example is not OK.<br><br> </div><br>
    <blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000"><div class="im"><blockquote type="cite">
      <div class="gmail_quote">
        <div>* a fractional part function (ie 22/7 is ~3.14 -&gt; 0.14)
          as a FP<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    Ditto.</div></blockquote><div><br>Thinking about it some more, maybe the fractional part should return a 
typeof(this): 22/7 -&gt; 1/7. Not a float.<br> 
<br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000"><div class="im">
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>* Accordingly,  floor/ceil functions could be interesting,
          unless you think the user should use
          std.math.floor(cast(real)rat), which I could understand.<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    Again, good idea.  Using std.math sucks because a major point of
    Rational is that it&#39;s supposed to work with arbitrary precision, and
    reals aren&#39;t arbitrary precision. <br></div></blockquote><div><br><br>I could argue that floor or ceil are exactly when you get rid of this arbitrary precision, but to answer the question in your next post, I think these should be part of the rational module and be free functions: it makes the module self-supported. And having rational support in std math means it must in turn import the rational module. I&#39;m against this.<br>
<br>In any case, people will probably import both at the same time...<br><br>I&#39;m not clear on the subtle nuances between the integer part, the floor and the ceil for positive and negative Rationals, though.<br><br>See std.math: ceil, floor, nearbyInt, round, trunc! Awww.<br>
<br>The next question would be: what other free function? I&#39;ll add abs(), but not much more. Maybe pow or opBinary!&quot;^^&quot; ?<br>I wouldn&#39;t add any trigonometric function. <br>sqrt is on the fence for me. Is there an algorithm to calculate the square root of a rational apart from the Babylonian method? <br>
 </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000"><div class="im">
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>
          * Addendum (probably not a good idea): you can have infinity
          and NaN-like values with 1/0, -1/0 and 0/0...<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    Probably not.  I really despise NaNs in floating point code because
    they break fundamental mathematical axioms that appear to be common
    sense (such as x == x, x * 0 == 0, if !(x &lt;= y) then x &gt; y,
    and x &lt; y || x == y || x &gt; y).  For example, try making a
    sorting algorithm or a binary tree with floating point numbers if
    they may be NaNs.  I&#39;d rather just leave it the way it is, where it
    throws if the denominator is zero.</div></blockquote><div><br>So it&#39;s ditched then.<br><br>We might at one point need an integer-like type adding negative and positive infinity, if only to cleanly represent slices on infinite ranges.<br>
<br> <br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000"><div class="im">
    
    <blockquote type="cite">
      <div class="gmail_quote">
        <div><br>
          ***<br>
           2.  I couldn&#39;t figure out how to handle the case of
          user-defined fixed-width integer types in the decimal
          conversion (opCast) function, so it just assumes non-builtin
          integer types are arbitrary precision.  The biggest problem is
          lack of a way of introspecting whether the integer is fixed or
          arbitrary width and what its fixed width might be if it is, in
          fact, fixed.  The secondary problem is that I don&#39;t know of a
          good algorithm (though I&#39;m sure I could find one if I tried)
          for converting fixed-width integers to floating point numbers
          in software.  Arbitrary precision is much easier.<br>
          ***<br>
          <br>
          About converting fixed-width integer-like types, maybe these
          should provide .min and .max properties?<br>
          That way you know the range of possible values and maybe it&#39;s
          then possible to convert (I didn&#39;t think this through so I may
          be completly mistaken)<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    I think what I&#39;m going to do here is just throw an exception iff the
    denominator has both the highest and lowest order bit set.  This is
    enough of a corner case in that it will only happen close to the
    limit of the largest denominator value that can be represented that
    I don&#39;t consider it a major limitation.  It&#39;s easily detectable
    because the numerator will never become bigger than the denominator
    by bit shifting iff either the numerator is zero or the denominator
    has its highest order bit set.  If the denominator&#39;s lowest order
    bit isn&#39;t set then I can shift the denominator right to make it not
    have its highest order bit set.<br></div></blockquote><div><br>What&#39;s the pb with having a numerator bigger than the denominator? Sorry, I didn&#39;t read the conversion function carefully.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000">
    <br>
    If anyone has any better ideas, or considers this too severe a
    limitation, let me know.</div></blockquote><div><br>Do that and we&#39;ll see how it goes.<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000"><div class="im"><br>
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>
          <br>
          Good work David. My only pb is that you write code faster that
          I can read it, and don&#39;t let me any time to write some myself!
          It took me a week to read the recent additions in Phobos!<br>
        </div>
      </div>
    </blockquote>
    <br></div>
    This code has been around in some form for almost a year.  It&#39;s just
    that the proposal for a units library made me remember that I&#39;ve
    been meaning to clean up all the bit rot, improve it and submit it
    for inclusion.</div></blockquote><div><br>Seeing that you have time, talent and energy, I&#39;ll order a BigDecimal module :-)<br><br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div bgcolor="#ffffff" text="#000000"><div class="im">
    <br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div><br>
          <br>
          *goes back to cleaning his algebraic data types and type
          mimicry code*<br>
          <br>
        </div>
      </div>
    </blockquote>
    <br></div>
    Great.  I look forward to when this code is ready.<br></div></blockquote><div><br>No you don&#39;t :) It&#39;s full of string mixins, variadic templates, CT type witchery, typetuples, objects hierarchies generated by CTFE and such. All in all, it&#39;s a smorgasbord of D possibilities :)<br>
But it&#39;s slowly coming together and the use is very easy.  I can already imitate std.Tuple and std.Algebraic, make recursive types: lists and trees, cyclic types (graphs?), imitate Haskell&#39;s Either and Maybe types, do statically checked pattern matching on them, and create map/reduce functions. So I&#39;m not far from ADT in other languages that have them with compiler support (Scala, Haskell, ML, F#...)<br>
I still have to automate this last point (automatically generating a reduce function on any recursive algebraic type), add variadic arguments (which AFAICT no other language provide) and then code generalized algebraic datatypes, the flagship of the most powerful functional languages: CAML and Haskell :-)  Strangely, I see no difficulty *for now* in the last part.<br>
In any case, even if I&#39;m not sure this should be part of D standard library, I&#39;d be fun and good for PR to have them in a library somewhere.<br><br>As for type mimic it&#39;s nothing fancy but I&#39;ll try to post something soon, to restart the discussion on typedef once more.<br>
<br>Philippe<br><br></div></div>