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