2
votes

To learn the paradigm of OOP, we were asked to implement our own OOP language within scheme. I started by creating a single object, then a single class based off that object. My next step would be to create a 'class factory' as my professor calls it, a function that would create classes based off of a certain specification input. Before I can get to that though, I am facing what I think is a simple problem:

here is my class, it works:

(define pclass
  (λ input
    (let ((p-obj (list 'let `((xvar ,(caar input)) (yvar ,(cadar input)) (*this* null))
                       '(λ input
                          (let ((method (car input)) (args (cdr input)))
                            (cond
                              ((eq? 'display method) (begin
                                                       (display "Coords: x=") (display xvar) 
                                                       (display ", y=") (display yvar) (newline)))
                              ((eq? 'setx method) (set! xvar (cadr input)))
                              ((eq? 'getx method) xvar)
                              ((eq? 'gety method) yvar)
                              ((eq? 'polar method) (let ((radius (sqrt (+ (* xvar xvar) (* yvar yvar))))
                                                         (angle (/ (truncate (* (atan (/ yvar xvar)) 
                                                                            (/ 36000 (* 2 3.1415)))) 100))) 
                                                     (list radius angle)))
                              ((eq? 'dist method) (let ((x2 ((cadr input) 'getx)) 
                                                        (y2 ((cadr input) 'gety))) 
                                                    (sqrt (+ (expt (- x2 xvar) 2) (expt (- y2 yvar) 2)))))
                              ((and (eq? 'set method) (null? *this*)) (set! *this* (cadr input)))
                              (else (begin (display "Error: No method with signature: ") (display method)))
                           ))))))
      (eval p-obj))))

my problem is in my new function. If I run it this way:

(define new
  (λ input
    ((car input) (cdr input))))

it works just fine, aside from the issue of assigning my this variable. To assign it, I assume it is something like this:

(define new
  (λ input
    (let ((new-obj ((car input) (cdr input))))
      (new-obj 'set new-obj))))

but this method doesn't return a procedure object to assign when I run my code:

(define x (new pclass 3 5))

I am sure it is some small quirk of let that I don't fully understand. I should mention, if I define x with the first new code, it works fine and I can make method calls to x. I just don't have a this pointer for when I need it. I don't understand why the let block in my class returns a procedure object just fine, but the let block in my new function doesn't.

1
Why the indirection through quoting and eval? - molbdnilo
I'm pretty sure you don't need eval for this. You might need macros if you wat to automatically create accessors or have special pretty syntax instead of lambda, but not otherwise. See Simple OO in Scheme wiki for inspiration. - Sylwester

1 Answers

2
votes

...fixed it.

...
((and (eq? 'set method) (null? *this*)) (begin (set! *this* (cadr input)) *this*))
...