From f225ca5e374ba315b4fefb9d24174cb942c59036 Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <vu3rdd@gmail.com>
Date: Wed, 18 Jan 2012 21:28:46 +0530
Subject: [PATCH] solution to 4.26

---
 src/sicp/ex4_26.rkt             | 19 +++++++++++++++++++
 src/sicp/metacircular2-test.rkt |  3 ++-
 src/sicp/metacircular2.rkt      |  1 +
 3 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 src/sicp/ex4_26.rkt

diff --git a/src/sicp/ex4_26.rkt b/src/sicp/ex4_26.rkt
new file mode 100644
index 0000000..01c33af
--- /dev/null
+++ b/src/sicp/ex4_26.rkt
@@ -0,0 +1,19 @@
+#lang racket
+
+#|
+
+Yes, if 'unless' were implemented in an applicative order language, then
+it would be implemented as a special form and would be translated into
+other functions before evaluation.
+
+Now, if such a special form is used in a higher order function like 'map'
+for instance:
+
+(map unless '((p-list) (usual-list) (exception-list)))
+
+then, unless gets expanded before evaluation. But map expects a function
+as its second argument.
+
+To see the implementation of unless, see metacircular2.rkt
+
+|#
diff --git a/src/sicp/metacircular2-test.rkt b/src/sicp/metacircular2-test.rkt
index 1644f95..cda363a 100644
--- a/src/sicp/metacircular2-test.rkt
+++ b/src/sicp/metacircular2-test.rkt
@@ -77,7 +77,8 @@
                   1
                   (* (factorial (- n 1)) n)))
            env1)
-     (check-equal? (eval '(factorial 10) env1) 3628800 "factorial test"))))
+     (check-equal? (eval '(factorial 10) env1) 3628800 "factorial test")
+     (check-equal? (eval '(unless true "true" "false") env1) "false" "unless test 1"))))
 
 
 (run-tests metacircular2-tests)
\ No newline at end of file
diff --git a/src/sicp/metacircular2.rkt b/src/sicp/metacircular2.rkt
index c45a5e7..ef387d4 100644
--- a/src/sicp/metacircular2.rkt
+++ b/src/sicp/metacircular2.rkt
@@ -227,6 +227,7 @@
     [`(define ,(? (lambda (x) (not (pair? x))) var) ,b) (define-variable! var (eval b env) env)]
     [`(define ,(? pair? var) ,b ..1) (define-variable! (car var) (eval (make-lambda (cdr var) b) env) env)]
     [`(if ,pred ,consequent ,alternative) (if (true? (eval pred env)) (eval consequent env) (eval alternative env))]
+    [`(unless ,condition ,consequent ,alternative) (if (true? (eval condition env)) (eval alternative env) (eval consequent env))]
     [`(lambda ,parameters ,body ..1) (make-procedure parameters body env)]
     [`(begin ,exp ...) (eval-sequence exp env)]
     [`(cond ,clauses ...) (eval (cond->if clauses) env)]
-- 
2.45.2