Using letcc cor­rectly

Created: Thu Nov 15 17:36:18 CET 2018

Last mod­i­fied: Thu Dec 27 09:44:28 CET 2018


For con­ve­nience, I wrote the fol­low­ing de­f­i­n­i­tion of letcc:

(define-syntax letcc
    (syntax-rules ()
      ((_ name body ...)
       (call-with-current-continuation
         (lambda (name)
           body ...)))))

It lets us de­fine a ver­sion of mul­ti­ply-list which I believe is not good to use.

(define multiply-list
  (lambda (ls)
    (letcc north
      (if (null? ls)
          1
          (if (eqv? (car ls) 0)
              (north 0)
              (* (car ls)
                 (multiply-list (cdr ls))))))))

It’s dumb. Our lambda won’t per­form the non-lo­cal re­turn on 0. I agree that it will stop re­cur­ring on cdr but our letcc is to­tally use­less here.

We should de­fine two func­tions mul­ti­ply-list and mul­ti­ply-list-b. mul­ti­ply-list will de­fine north and pass it down to mul­ti­ply-list-b.

So we now have,

(define multiply-list-b
  (lambda (ls north)
    (if (null? ls)
        1
        (if (eqv? (car ls) 0)
            (north 0)
            (* (car ls)
               (multiply-list-b (cdr ls) north))))))

(define multiply-list
  (lambda (ls)
    (letcc north
      (multiply-list-b ls north))))

After ap­ply­ing a bunch of com­mand­ments from the Little Schemer:

(define multiply-list
  (lambda (ls)                              
    (let ((north (lambda (x) #f)))
      (letrec ((mls                
                (lambda (ls)
                  (if (null? ls)
                      1         
                      (if (zero? (car ls))
                          (north 0)       
                          (* (car ls)
                             (mls (cdr ls))))))))
        (letcc hop       
          (set! north hop)
          (mls ls))))))

And we now have a proper func­tion for mul­ti­ply­ing every num­bers in a list.

We should refac­tor it a lit­tle so it also ac­cepts an ac­cu­mu­la­tor.

(define multiply-list
  (lambda (ls)
    (let ((north (lambda (x) #f)))
      (letrec ((mls                
                (lambda (ls acc)
                  (if (null? ls)
                      acc
                      (if (zero? (car ls))
                          (north 0)
                          (mls (cdr ls)
                               (* (car ls)
                                  acc)))))))
        (letcc hop
          (set! north hop)
          (mls ls 1))))))

source code