計算機プログラムの構造と解釈 第二版 P222 問題4.7
導出するだけで十分だと思う。なんかできてると思うし。
基本的にこの一個前の問題とやり方は一緒。
- evalに加える。
- let*?手続き
- let*-clauses手続き
- let*-parametars手続き (var exp)からなるリストを取り出す
- let*-body手続き
- let*->nested-lets手続き
- expand-let*-clauses手続き
あと書き換えできるように
- make-let
がいる。letの書き方がわかれば、別に難しくはない。
まず、let*をletで書き換えるとこんな感じになるかと。
こいつが、、、
(let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z))
こうなる、、、
(let ((x 3)) (let ((y (+ x 2))) (let ((z (+ x y 5))) (* x z))))
こういう書き換えを行ってあげれば良い。
用は単なるletの入れ子だから、問題4.6の
実装
#!/usr/local/bin/gosh ;; -*- coding: utf-8 -*- (print (let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z))) (print (let ((x 3)) (let ((y (+ x 2))) (let ((z (+ x y 5))) (* x z))))) (load "./modules/4th.scm") (load "./modules/let.scm") (define (eval exp env) (cond ((self-evaluating? exp) exp) ((variable? exp) (lookup-variable-value exp env)) ((quoted? exp) (text-of-quotation exp)) ((assignment? exp) (eval-assignment exp env)) ((definition? exp) (eval-definition exp env)) ((if? exp) (eval-if exp env)) ((lambda? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)) ((begin? exp) (eval-sequence (begin-actions exp) env)) ((cond? exp) (eval (cond->if exp) env)) ;;4.6 ((let? exp) (eval (let->combination exp) env)) ;;4.7 ((let*? exp) (eval (let*->nested-lets exp) env)) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))) (else (error "Unknown expression type -- EVAL" exp)))) ;;4.7 let* (define (let*? exp) (tagged-list? exp 'let*)) (define (let*-clauses exp) (cdr exp)) (define (let*-parameters clauses) (car clauses)) (define (let*-body clauses) (cadr clauses)) (define (make-let* defs body) (list 'let defs body)) (define (let*->nested-lets exp) (expand-let*-clauses (let*-clauses exp))) (define (expand-let*-clauses clauses) (if (null? clauses) '() (let ((parameters (let*-parameters clauses)) (body (let*-body clauses))) (define (expand-let*-clauses-i rest-parameters) (if (null? rest-parameters) body (make-let* (list (car rest-parameters)) (expand-let*-clauses-i (cdr rest-parameters))))) (expand-let*-clauses-i parameters)))) (define the-global-environment (setup-environment)) (driver-loop)
実行
39 39 ;;; M-Eval input: (let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z)) ;;; M-Eval value: 39
始めの39はlet*とその書き換えを確かめたやつ。