Scheme Debugging

Call of non-procedure #f

broken code
;;;;
;; insertR* :: Atom [a] -> [a]
;;
;; Returns `lst` with `new` inserted to the right of all occurrences
;; of `old`.
;;
(define insertR*
  (lambda (new old lst)
    ((null? lst) '())
    ((atom? (car lst))
     (cond
      ((eq? (car lst) old)
       (cons old
             (cons new
                   (insertR* new old (cdr lst)))))
      (else
       (cons (car lst)
             (insertR* new old (cdr lst))))))
    (else
     (cons (insertR* new old (car lst))
           (insertR* new old (cdr lst))))))

Running the code above with Chicken Scheme produces an error something like this:

chicken scheme error in REPL
#;1> (insertR* 'NEW 'qux '(foo (bar qux)))

Error: call of non-procedure: #f

	Call history:

	<syntax>	  (insertR* (quote NEW) (quote qux) (quote (foo (bar qux))))
	<syntax>	  (quote NEW)
	<syntax>	  (##core#quote NEW)
	<syntax>	  (quote qux)
	<syntax>	  (##core#quote qux)
	<syntax>	  (quote (foo (bar qux)))
	<syntax>	  (##core#quote (foo (bar qux)))
	<eval>	  (insertR* (quote NEW) (quote qux) (quote (foo (bar qux))))
	<eval>	  [insertR*] ((null? lst) (quote ()))
	<eval>	  [insertR*] (null? lst)	<--

The problem is in this line:

((null? lst) '())

Why‽ Look:

#;3> (define lst '())
#;3> ((null? lst) '())

Error: call of non-procedure: #t

	Call history:

	<syntax>	  ((null? lst) (quote ()))
	<syntax>	  (null? lst)
	<syntax>	  (quote ())
	<syntax>	  (##core#quote ())
	<eval>	  ((null? lst) (quote ()))
	<eval>	  (null? lst)	<--

(null? lst) returns #f. Our expression then evaluates to (#f '()), and #f is not a procedure (function). We cannot apply #f to '() #f is not a procedure.

simple referential transparency check
((null? lst) '())
(#f '())
...error...

But that same line works as expected inside cond. Here’s the working code with the cond in the correct place:

;;;;
;; insertR* :: Atom [a] -> [a]
;;
;; Returns `lst` with `new` inserted to the right of all occurrences
;; of `old`.
;;
(define insertR*
  (lambda (new old lst)
    (cond
     ((null? lst) '())
     ((atom? (car lst))
      (cond
       ((eq? (car lst) old)
        (cons old
              (cons new
                    (insertR* new old (cdr lst)))))
       (else
        (cons (car lst)
              (insertR* new old (cdr lst))))))
     (else
      (cons (insertR* new old (car lst))
            (insertR* new old (cdr lst)))))))