Opened 4 weeks ago

Last modified 3 weeks ago

#1703 accepted defect

Arguments being passed to procedure incorrectly

Reported by: Jakob L. Kreuze Owned by: sjamaan
Priority: major Milestone: someday
Component: compiler Version: 5.2.0
Keywords: Cc:
Estimated difficulty: hard

Description

Here is the offending part of a program I have been writing.

(define (reduce proc list init)
  (define (reduce-iter list result)
    (if (null? list)
        result
        (reduce-iter (cdr list) (proc result (car list)))))
  (reduce-iter list init))

(define-record-type <vec3>
  (make-vec3 x y z)
  vec3?
  (x vec3-x)
  (y vec3-y)
  (z vec3-z))

;; Macro for destructuring a vec3.
(define-syntax vec3-bind
  (syntax-rules ()
    ((vec3-bind ((names vec) ...)
       body)
     (let-values ((names (values (vec3-x vec)
                                 (vec3-y vec)
                                 (vec3-z vec)))
                  ...)
       body))))

(define (vec3- . vecs)
  "Return the difference of VECS, as in vector space subtraction."
  (define (sub u v)
    (vec3-bind (((x1 y1 z1) u) ((x2 y2 z2) v))
      (make-vec3 (- x1 x2) (- y1 y2) (- z1 z2))))
  (if (zero? (length vecs))
      (make-vec3 0 0 0)
      (reduce sub (cdr vecs) (car vecs))))

(vec3- (make-vec3 1.00 1.00 1.00)
       (make-vec3 1.00 1.00 1.00)
       (make-vec3 1.00 1.00 1.00))

This runs without error on Version 4.13.0 (rev 68eeaaef), but on Version 5.2.0 (rev 317468e4), I get the following runtime error.

Error: (vec3-x) bad argument type - not a structure of the required type
#<procedure (sub u v)>
<vec3>

	Call history:

	r7rs-raytracer.scm:35: make-vec3	  
	r7rs-raytracer.scm:36: make-vec3	  
	r7rs-raytracer.scm:37: make-vec3	  
	r7rs-raytracer.scm:35: vec3-	  
	r7rs-raytracer.scm:33: reduce	  
	r7rs-raytracer.scm:6: reduce-iter	  
	r7rs-raytracer.scm:5: proc	  
	r7rs-raytracer.scm:29: ##sys#call-with-values	  
	r7rs-raytracer.scm:29: vec3-x	  	<--

I could not build the master branch, so I was unable to see if this has been resolved.

I suspect the arguments are being passed in the wrong order to 'reduce', somehow. This error only occurs if the number of arguments to vec3- is greater than 2.

Change History (3)

comment:1 Changed 4 weeks ago by sjamaan

Owner: set to sjamaan
Status: newaccepted

This looks like a problem with the car/cdr rewrite of rest args

comment:2 Changed 3 weeks ago by felix winkelmann

Here a slightly simplified variant:

(define (reduce proc list init)
  (define (reduce-iter list result)
    (if (null? list)
        result
        (reduce-iter (cdr list) (proc result (car list)))))
  (reduce-iter list init))

(define (vec3- . vecs)
  (define (sub u v)
    (vector (- (vector-ref u 0) (vector-ref v 0))
            (- (vector-ref u 1) (vector-ref v 1))
            (- (vector-ref u 2) (vector-ref v 2))))
  (reduce sub (cdr vecs) (car vecs)))

(vec3- #(1.00 1.00 1.00)
       #(1.00 1.00 1.00)
       #(1.00 1.00 1.00))

which results in

Error: (vector-ref) bad argument type: #<procedure (sub u v)>

	Call history:

	x.scm:15: vec3-	  
	x.scm:13: reduce	  
	x.scm:6: reduce-iter	  
	x.scm:5: proc	  	<--

csc -debug 7 looks ok to me. Making sub trivial seems to make it run to completion, but again, the debug output doesn't show any noteworthy difference.

comment:3 Changed 3 weeks ago by megane

Smaller yet:

(set! reduce (lambda (_l ini) (+ ini 1)))

;; (print ((lambda xs (reduce xs (car xs))) 1 2 3)) ;; prints 2

(set! fold- (lambda xs (reduce xs (car xs))))
(print (fold- 1 2 3))

;; Error: (+) bad argument type - not a number: (1 2 3)
;;
;;         Call history:
;;
;;         rest-arg.scm:19: fold-
;;         rest-arg.scm:18: reduce         <--

Note: See TracTickets for help on using tickets.