Search code examples
schememit-scheme

The compound object is not applicable


I'm writing a small plotting utility for MIT-Scheme. Source: [plotlib].

At the top level is the (make-plot output mode args) function that takes in an output device object, the plotting mode, and a list containing the parameters for the kind of plot specified in the mode. I will use the function (range start stop increment) to generate lists from inclusive start to exclusive stop for each increment. (range -1 1 .1) creates the list (-1 -.9 -.8 ... .9).

make-plot works for its other modes, but does not work when called with 'vector-field-plot

(define window (make-graphics-device 'win32))

(define (vector-field-plot device color xrange yrange func) 
  (let* ((cords (append-all (map (lambda (i) 
                                   (map (lambda (j) 
                                          (cond ((eq? j '()) '()) 
                                                (else (cons i j)))) 
                                        xrange)) 
                                  yrange))) 
         (input (map (lambda (point) 
                       (list (car point) (cdr point) 
                             (car (func (car point) (cdr point))) 
                             (cdr (func (car point) (cdr point))))) 
                     cords))) 
    (draw-vector-list device color input)))

;This is the part of make-plot that is called for 
;(make-plot window 'vector-field-plot '(args))

((eq? mode 'vector-field-plot)
       ;does not work yet
        (let* ((bg-color (car args))
               (grid-color (cadr args))
               (line-color (caddr args))
               (xrange (car (cadddr args)))
               (yrange (cadr (cadddr args)))
               (func   (cddr (cadddr args))))
         (clear output bg-color);sets background to white
         (coord-grid-cart output grid-color);prints Cartesian coordinate grid
         (vector-field-plot output line-color xrange yrange func)))))
         ;calls vector-field-plot with parameters given to make-plot
;I have left out some function definitions here, they are in the source file
;but you can assume all of those work correctly for this section

One mode of make-plot prints vector fields, It calls the function (vector-field-plot output line-color xrange yrange func) With xrange and yrange being lists of numbers like '(-1 -.9 ... 1) and a func of the form (lambda (x y) (cons x y)). If I use:

(make-plot window 'vector-field-plot (list "white" "black" "red"
                                           (list (range -1 1 .1) (range -1 1 .1) 
                                           (lambda (x y) (cons (* -.1 y) (* -.1 x))))))

It returns The object (#[compound procedure ]) is not applicable.

But if I use:

(vector-field-plot window "red" (range -1 1 .1) (range -1 1 .1) 
                                (lambda (x y) (cons (* -.1 y) (*  .1 x))))

It displays the correct plot (a circular vector field) in the graphics window. output


Solution

  • The error is because the expression to get the function outside the list of arguments returns a list containing the function, not the function itself.

    You should change:

    (func   (cddr (cadddr args))))
    

    with:

    (func   (caddr (cadddr args))))