corrections to examples, tests, and reference implementation William D Clinger 03 Mar 2015 02:16 UTC

Here are some corrections to some examples in SRFI 116 (immutable
lists) and to its reference implementation and tests.

I believe the following examples need a quote mark in front
of the x:

    ;; Failure is error on a dotted ilist.
    (ifind even? (ipair (1 (ipair 3 x)))        => error
    (iany  even? (ipair (1 (ipair 3 x)))        => error

The test program needs the same correction.

The following examples are incorrect because imember uses equal?,
and SRFI 116 does not require (or recommend) equal? be extended
to traverse immutable lists.

    (imemq (ilist 'a) (iq b (a) c)) =>  #f
    (imember (ilist 'a)
             (iq b (a) c))          =>  ((a) c)

These examples and the test program should be corrected like

  (let ((x (iq (a))))
    (test (ilist x 'c) (imember x (ilist 'b x 'c))))

The examples and tests for iassoc need a similar correction:

  (let* ((y (iq a))
         (x (ilist y)))
    (test x (iassoc y (ilist x (iq (b)) (iq (c))))))

The reference implementation's definition of ievery is
incorrect.  Here is a corrected definition:

(define (ievery pred lis1 . lists)
  (check-arg procedure? pred ievery)
  (if (pair? lists)    ; FIXED: was (ipair? lists)

      ;; N-ary case
      (receive (heads tails)
               (%cars+cdrs (cons lis1 lists)) ; FIXED: was (ipair lis1 lists))
	(or (not (pair? heads))               ; FIXED: was (ipair? heads)
	    (let lp ((heads heads) (tails tails))
	      (receive (next-heads next-tails) (%cars+cdrs tails)
		(if (pair? next-heads)        ; FIXED: was (ipair? next-heads)
		    (and (apply pred heads)
                         (lp next-heads next-tails))
		    (apply pred heads)))))) ; Last PRED app is tail call.

      ;; Fast path
      (or (null-ilist? lis1)
	  (let lp ((head (icar lis1))  (tail (icdr lis1)))
	    (if (null-ilist? tail)
		(pred head)	; Last PRED app is tail call.
		(and (pred head) (lp (icar tail) (icdr tail))))))))