learning-sicp

My embarrassing half assed SICP run.
git clone https://kaka.farm/~git/learning-sicp
Log | Files | Refs

exercise-8.scm (3014B)


      1 (define-library (sicp solutions chapter-4 exercise-8)
      2   (import (scheme base)
      3           (ice-9 match))
      4 
      5   (begin
      6     (define (eval exp env)
      7       (cond ((self-evaluating? exp) exp)
      8             ((variable? exp) (lookup-variable-value exp env))
      9             ((quoted? exp) (text-of-quotation exp))
     10             ((assignment? exp) (eval-assignment exp env))
     11             ((definition? exp) (eval-definition exp env))
     12             ((if? exp) (eval-if exp env))
     13             ((lambda? exp)
     14              (make-procedure (lambda-parameters exp)
     15                              (lambda-body exp)
     16                              env))
     17             ((begin? exp)
     18              (eval-sequence (begin-actions exp) env))
     19             ((cond? exp) (eval (cond->if exp) env))
     20             ((let*? exp) (eval (let*->combination exp) env))
     21             ((application? exp)
     22              (apply (eval (operator exp) env)
     23                     (list-of-values (operands exp) env)))
     24             (else
     25              (error "Unknown expression type -- EVAL" exp))))
     26 
     27     (define (let*? exp) (eqv? (car exp) 'let*))
     28 
     29     (let*->combination '(let* () a b c))
     30     (let*->combination '(let* ((a (b)) (c (d))) 1))
     31 
     32     (define (let*->combination exp)
     33       (match exp
     34         (`(let* () ,first-code-expression . ,rest-of-code-expressions)
     35          `(begin ,first-code-expression
     36                  ,@rest-of-code-expressions))
     37         (`(let* ((,variable-name ,variable-expression))
     38             ,first-code-expression . ,rest-of-code-expressions)
     39          `((lambda (,variable-name)
     40              ,first-code-expression
     41              ,@rest-of-code-expressions)
     42            ,variable-expression))
     43         (`(let* ((,variable-name ,variable-expression) . ,rest-of-variables)
     44             ,first-code-expression . ,rest-of-code-expressions)
     45          (let ((inner
     46                 (let*->combination `(let* ,rest-of-variables
     47                                       ,first-code-expression
     48                                       ,@rest-of-code-expressions))))
     49            `((lambda (,variable-name)
     50                ,inner)
     51              ,variable-expression)))))
     52 
     53     (let*->nested-lets '(let* () a b c))
     54     (let*->nested-lets '(let* ((a (b)) (c (d))) 1 2 3))
     55 
     56     (define (let*->nested-lets exp)
     57       (match exp
     58         (`(let* () ,first-code-expression . ,rest-of-code-expressions)
     59          `(begin ,first-code-expression
     60                  ,@rest-of-code-expressions))
     61         (`(let* ((,variable-name ,variable-expression))
     62             ,first-code-expression . ,rest-of-code-expressions)
     63          `(let ((,variable-name ,variable-expression))
     64             ,first-code-expression
     65             ,@rest-of-code-expressions))
     66         (`(let* ((,variable-name ,variable-expression) . ,rest-of-variables)
     67             ,first-code-expression . ,rest-of-code-expressions)
     68          `(let ((,variable-name ,variable-expression))
     69             ,(let*->nested-lets
     70              `(let* ,rest-of-variables
     71                ,first-code-expression
     72                ,@rest-of-code-expressions))))))))