Hi Matt,<div><br></div><div>Thanks, what you wrote makes perfect sense (of course... that's what I get for programming at such hours!)</div><div><br></div><div>Anyway, working code included below and the main purpose of learning about classes in Racket helped along the way. </div>
<div><br></div><div>To take a step back and look at what I've "accomplished" in this exercise:</div><div><br></div><div>1) I was able to re-use the rational-rep code in gencontfrac% which was the main intent.</div>
<div>2) rational-rep calls expand-repeat which in the base class calls a client-provided function called repeat, in the sqrtcontfrac% subclass expand-repeat uses a list called repeatlst instead of the function</div><div>3) in sqrtcontfrac% repeat is set to #<void>. The is-a relationship is not honored by what I've done.</div>
<div><br></div><div>Questions:</div><div>1) Is what I've done an abomination? Am I simply abusing inheritance?</div><div>2) To make the code below work, I had to make expand-repeat public as I couldn't override a private function. Is there another way (something like "protected" in C++)?</div>
<div><br></div><div>Thanks again!</div><div>-Joe</div><div><br></div><div><br></div><div><div>(module contfrac racket</div><div> (require racket/class)</div><div> (provide gencontfrac%)</div><div> (provide sqrtcontfrac%)</div>
<div> </div><div> ; class that represents the continued fraction of a general irrational number and acts as a base class for continued fractions of other sorts</div><div> (define gencontfrac% </div><div> (class object%</div>
<div> (super-new)</div><div> (init-field start)</div><div> (init-field repeat)</div><div> ; create a n-long list of repeat digits (in reverse order - which makes creation of a rational easier)</div><div>
(define/public (expand-repeat n)</div><div> (let lp ([c n] [rl '()])</div><div> (if (zero? c) rl (lp (sub1 c) (cons (repeat) rl)))))</div><div> ; create a rational representation using the passed number of repeat digits</div>
<div> (define/public (rational-rep n)</div><div> (define rdiglst (expand-repeat n))</div><div> (let lp ([rdigs (rest rdiglst)] [res (first rdiglst)])</div><div> (if (empty? rdigs) (+ start (/ 1 res)) (lp (rest rdigs) (+ (first rdigs) (/ 1 res))))))</div>
<div> ; display the continued fraction</div><div> (define/public (show)</div><div> (printf "[~a; ~a]~n" start repeat))</div><div> ))</div><div> </div><div> ; define a class that represents the continued fraction of a square root</div>
<div> (define sqrtcontfrac% </div><div> (class gencontfrac%</div><div> (init sqrval)</div><div> (define repeatlst (build-repeatlst sqrval))</div><div> (super-new [start (integer-sqrt sqrval)] [repeat (void)])</div>
<div> (inherit rational-rep show)</div><div> (inherit-field start)</div><div> ; build the repeating sequence (see <a href="http://en.wikipedia.org/wiki/Continued_fraction">http://en.wikipedia.org/wiki/Continued_fraction</a>)</div>
<div> (define/private (build-repeatlst n)</div><div> (define start (integer-sqrt n))</div><div> (let loop ([adder start] [denom (- n (sqr start))] [result '()])</div><div> (cond [(zero? denom) '()] ; perfect square</div>
<div> [(= 1 denom) (reverse (cons (+ (integer-sqrt n) adder) result))] ; found the end of the repeating sequence</div><div> [else </div><div> (let* ([nextval (quotient (+ adder start) denom)] [nextadd (- (* nextval denom) adder)])</div>
<div> (loop nextadd (quotient (- n (sqr nextadd)) denom) (cons nextval result)))])))</div><div> ; create a n-long list of repeat digits (in reverse order - which makes creation of a rational easier)</div>
<div> (define/override (expand-repeat n)</div><div> (let lp ([c n] [rl '()] [stock repeatlst])</div><div> (if (zero? c) rl (lp (sub1 c) (cons (first stock) rl) (if (empty? (rest stock)) repeatlst (rest stock))))))</div>
<div> ; accessor</div><div> (define/public (get-repeatlst) repeatlst)</div><div> ))</div><div> )</div></div><div><br></div><div><div><br><div class="gmail_quote">On Sun, May 20, 2012 at 6:49 AM, Matthew Flatt <span dir="ltr"><<a href="mailto:mflatt@cs.utah.edu" target="_blank">mflatt@cs.utah.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The problem is that `start' doesn't get a value for a `sqrtcontfrac%'<br>
instance until `super-new' in `sqrtcontfrac%' is evaluated. But the<br>
expression for the second argument in `super-new' calls `build-repeat',<br>
so that `build-repeat' tries to use `start' before it has a value.<br>
<br>
I'm not sure of the solution in this case, but it might be to pass the<br>
value for `start' into `build-repeat' instead of trying to get the<br>
value from the `start' field within `build-repeat'.<br>
<div class="im"><br>
At Sun, 20 May 2012 02:06:35 -0700, Joe Gilray wrote:<br>
> I'm trying to learn to use classes in Racket. I did some successful simple<br>
> experiments then moved on to inheritance. When I try to use the code<br>
> below, the following code:<br>
><br>
> (new sqrtcontfrac% [sqrval i]) leads to the message: sqr: expected<br>
> argument of type <number>; given #<undefined><br>
><br>
> Why isn't start being inherited properly? Any help is appreciated!<br>
><br>
> Thanks,<br>
> -joe<br>
><br>
> Here is the class code:<br>
><br>
> (module contfrac racket<br>
> (require racket/class)<br>
> (provide gencontfrac%)<br>
> (provide sqrtcontfrac%)<br>
><br>
> ; class that represents the continued fraction of a general irrational<br>
> number and acts as a base class for continued fractions of other sorts<br>
> (define gencontfrac%<br>
> (class object%<br>
> (super-new)<br>
</div>> (init-field start) *; here start is defined*<br>
<div><div class="h5">> (init-field repeat)<br>
> ; create a n-long list of repeat digits (in reverse order - which<br>
> makes creation of a rational easier)<br>
> (define/private (expand-repeat n)<br>
> (let lp ([c n] [rl '()])<br>
> (if (zero? c) rl (lp (sub1 c) (cons (repeat) rl)))))<br>
> ; create a rational representation using the passed number of repeat<br>
> digits<br>
> (define/public (rational-rep n)<br>
> (define rdiglst (expand-repeat n))<br>
> (let lp ([rdigs (rest rdiglst)] [res (first rdiglst)])<br>
> (if (empty? rdigs) (+ start (/ 1 res)) (lp (rest rdigs) (+ (first<br>
> rdigs) (/ 1 res))))))<br>
> ; display the continued fraction<br>
> (define/public (show)<br>
> (printf "[~a; ~a]~n" start repeat))<br>
> ))<br>
><br>
> ; define a class that represents the continued fraction of a square root<br>
> (define sqrtcontfrac%<br>
> (class gencontfrac%<br>
> (init sqrval)<br>
> (super-new [start (integer-sqrt sqrval)] [repeat (build-repeat<br>
> sqrval)])<br>
> (inherit rational-rep show)<br>
> (inherit-field start repeat)<br>
> ; build the repeating sequence (see<br>
> <a href="http://en.wikipedia.org/wiki/Continued_fraction" target="_blank">http://en.wikipedia.org/wiki/Continued_fraction</a>)<br>
> (define/private (build-repeat n)<br>
</div></div>> (let loop ([adder start] [denom (- n (sqr start))] [result '()]) *;<br>
> this is where the error is occurring *<br>
<div class="im">> (cond [(zero? denom) '()] ; perfect square<br>
> [(= 1 denom) (reverse (cons (+ start adder) result))] ;<br>
> found the end of the repeating sequence<br>
> [else<br>
> (let* ([nextval (quotient (+ adder (integer-sqrt n))<br>
> denom)] [nextadd (- (* nextval denom) adder)])<br>
> (loop nextadd (quotient (- n (sqr nextadd)) denom) (cons<br>
> nextval result)))])))<br>
> ; create a n-long list of repeat digits (in reverse order - which<br>
> makes creation of a rational easier)<br>
> (define/private (expand-repeat n)<br>
> (let lp ([c n] [rl '()] [stock repeat])<br>
> (if (zero? c) rl (lp (sub1 c) (cons (first stock) rl) (if (empty?<br>
> (rest stock)) repeat (rest stock))))))<br>
> ))<br>
> )<br>
</div>> ____________________<br>
> Racket Users list:<br>
> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</blockquote></div><br></div></div>