From: Ramakrishnan Muthukrishnan Date: Wed, 7 Sep 2011 16:26:13 +0000 (+0200) Subject: solutions for 4.1 - 4.4 X-Git-Url: https://git.rkrishnan.org/pf/content/quickstart.html?a=commitdiff_plain;h=70cd85563327ac622029847fb75349375a14dfe4;p=sicp.git solutions for 4.1 - 4.4 --- diff --git a/src/sicp/ex4_1.rkt b/src/sicp/ex4_1.rkt new file mode 100644 index 0000000..626ebd4 --- /dev/null +++ b/src/sicp/ex4_1.rkt @@ -0,0 +1,19 @@ +#lang racket + +;; left to right +(define (list-of-values exps env) + (define (iter valuelist expressions) + (if (no-operands? exps) + valuelist + (let ((value (eval (first-operand expressions) env))) + (iter (append valuelist (list value)) + (rest-operands expressions))))) + (iter '() exps)) + +;; right to left +(define (list-of-values exps env) + (if (no-operands? exps) + '() + (let ((right (list-of-values (rest-exps exps) env))) + (cons (eval (first-exp exps) env) + right)))) diff --git a/src/sicp/ex4_2.rkt b/src/sicp/ex4_2.rkt new file mode 100644 index 0000000..91daa83 --- /dev/null +++ b/src/sicp/ex4_2.rkt @@ -0,0 +1,28 @@ +#lang racket + +#| + +a. application? only checks whether the given expression is a pair. It assumes that the rest of + the built in language clauses are already handled. So this will upset all other classes like + define, let where Louis's eval would think define is a procedure and would proceed to evaluate + the operands, which is wrong. + +|# + +#| + +b. + +We only change the selectors and the predicate procedures, everything else remain the same to +implement the new proposal. + +|# + +(define (application? exp) + (if (pair? exp) + (tagged-list? expr 'call) + #f)) + +(define (operator exp) (car (cdr exp))) +(define (operands exp) (cdr (cdr exp))) + diff --git a/src/sicp/ex4_3.rkt b/src/sicp/ex4_3.rkt new file mode 100644 index 0000000..bbbf9a8 --- /dev/null +++ b/src/sicp/ex4_3.rkt @@ -0,0 +1,20 @@ +#lang racket + +(define (eval exp env) + (cond ((self-evaluating? exp) exp) + ((variable? exp) (lookup-variable-value exp env)) + ((get (type exp)) ((get (type exp)) exp env)))) + +(define (type expr) (car expr)) + +(put 'quote + (lambda (expr env) + (text-of-quotation expr))) + +(put 'set! + (lambda (expr env) + (eval-assignment expr env))) + + + + \ No newline at end of file diff --git a/src/sicp/ex4_4.rkt b/src/sicp/ex4_4.rkt new file mode 100644 index 0000000..aea7173 --- /dev/null +++ b/src/sicp/ex4_4.rkt @@ -0,0 +1,46 @@ +#lang racket + +(define (tagged-list? exp tag) + (if (pair? exp) + (eq? (car exp) tag) + #f)) + +(define (make-if predicate consequent alternative) + (list 'if predicate consequent alternative)) + +;; and +(define (and? expr) (tagged-list? expr 'and)) +(define (eval-and expr env) (eval-and-predicates (cdr expr) env)) + +(define (eval-and-predicates expr env) + (cond ((null? expr) #t) + ((eval (car expr) env) (eval-and-predicates (cdr expr) env)) + (else #f))) + +;; or +(define (or? expr) (tagged-list? expr 'or)) +(define (eval-or expr env) (eval-or-predicates (cdr expr) env)) + +(define (eval-or-predicates expr env) + (cond ((null? expr) #f) + ((eval (car expr) env) #t) + (else (eval-or-predicates (cdr expr) env)))) + +;; derived expressions +(define (and->if expr) + (expand-and-predicates (cdr expr))) + +(define (expand-and-predicates expr) + (cond ((null? expr) '#t) + (else (make-if (car expr) + (expand-and-predicates (cdr expr)) + '#f)))) + +(define (or->if expr) + (expand-or-predicates expr)) + +(define (expand-or-predicates expr) + (cond ((null? expr) '#f) + (else (make-if (car expr) + '#t + (expand-or-predicates (cdr expr)))))) \ No newline at end of file