SICP Exercise 4.8

October 29, 2009

SICP Exercise 4.8

We note that

(define (fib n)
  (let fib-iter ((a 1)
                 (b 0)
                 (count n))
    (if (= count 0)
        b
        (fib-iter (+ a b) a (- count 1)))))

is equivalent to

(define (fib n)
  (define (fib-iter a b count)
    (if (= count 0)
        b
        (fib-iter (+ a b) a (- count 1))))
  (fib-iter 1 0 n))

Therefore we can implement “named let” as follows.

(define (named-let? exp)
  (if (variable? (cadr exp))
      true
      false))
(define (named-let-name exp) (cadr exp))
(define (named-let-assignment exp) (caddr exp))
(define (named-let-body exp)
  (cdr (cdr (cdr exp))))
(define (let->combination exp)
  (if (named-let? exp)
      (transform-named-let (named-let-name exp)
                           (named-let-assignment exp)
                           (named-let-body exp))
      (transform-let (let-assignment exp) (let-body exp))))
(define (transform-named-let name assignment body)
  (sequence->exp 
   (list (cons 'define 
               (cons (cons name (let-var assignment))
                     body))
         (cons name (let-exp assignment)))))

See also SICP Exercise 4.6


SICP Exercise 4.7

October 29, 2009

SICP Exercise 4.7

(define (eval exp env)
; ......
        ((let*? exp) (eval (let*->nested-lets exp) env))
; ......
)

(define (let*? exp) (tagged-list? exp 'let*))
(define (let*-assignment exp) (cadr exp))
(define (let*-body exp) (cddr exp))

(define (let*->nested-lets exp)
  (transform-let* (let*-assignment exp) (let*-body exp)))
(define (transform-let* assignment body)
  (if (null? (cdr assignment))
      (cons 'let (cons assignment body))
      (list 'let (list (car assignment))
            (transform-let* (cdr assignment) body))))

SICP Exercise 4.6

October 12, 2009

SICP Exercise 4.6

(define (eval exp env)
; ......
        ((let? exp) (eval (let->combination exp) env))
; ......
)

(define (let? exp) (tagged-list? exp 'let))
(define (let-assignment exp) (cadr exp))
(define (let-body exp) (cddr exp))
(define (let-exp assignment)
  (if (null? assignment)
      '()
      (cons (cadr (car assignment))
            (let-exp (cdr assignment)))))
(define (let-var assignment)
  (if (null? assignment)
      '()
      (cons (car (car assignment))
            (let-var (cdr assignment)))))
  
(define (let->combination exp)
  (transform-let (let-assignment exp) (let-body exp)))
(define (transform-let assignment body)
  (cons (make-lambda (let-var assignment) body)
        (let-exp assignment)))

SICP Exercise 4.5

October 12, 2009

SICP Exercise 4.5

(define (expand-clauses clauses)
  (if (null? clauses)
      'false                          ; no else clause
      (let ((first (car clauses))
            (rest (cdr clauses)))
        (if (cond-else-clause? first)
            (if (null? rest)
                (sequence->exp (cond-actions first))
                (error "ELSE clause isn't last -- COND->IF"
                       clauses))
            (make-if (cond-predicate first)
                     (sequence->exp-2 (cond-predicate first) 
                                      (cond-actions first))
                     (expand-clauses rest))))))

(define (sequence->exp-2 cond-part1 cond-part2)
  (if (eq? (car cond-part2) '=>)
      (list (cadr cond-part2) cond-part1)
      (sequence->exp cond-part2)))

Follow

Get every new post delivered to your Inbox.