About SICP The following Qi code is derived from the examples provided in the book:
      "Structure and Interpretation of Computer Programs, Second Edition" by Harold Abelson and Gerald Jay Sussman with Julie Sussman.
      http://mitpress.mit.edu/sicp/

SICP Chapter #01 Examples in Qi

\* 1.1.1 The Elements of Programming - Expressions*\
486
(+ 137 349)
(- 1000 334)
(* 5 99)
(/ 10 5)
(+ 2.7 10)
(+ (+ 21 35) (+ 12 7))
(* (* 25 4) 12)
(+ (* 3 5) (- 10 6))
(+ (* 3 (+ (* 2 4) (+ 3 5))) (+ (- 10 7) 6))

\* 1.1.2 The Elements of Programming - Naming and the Environment*\
(set size 2)
(value size)
(* 5 (value size))
(set pi 3.14159)
(set radius 10)
(* (value pi) (* (value radius) (value radius)))
(set circumference (* 2 (* (value pi) (value radius))))
(value circumference)

\* 1.1.3 The Elements of Programming - Evaluating Combinations*\
(* (+ 2 (* 4 6))
   (+ 3 (+ 5 7)))

\* 1.1.4 The Elements of Programming - Compound Procedures*\
(define square
   { number --> number }
   X -> (* X X)
)
(square 21)
(square (+ 2 5))
(square (square 3))

(define sum-of-squares
   { number --> number --> number }
   X Y -> (+ (square X) (square Y))
)
(sum-of-squares 3 4)
(define f
   { number --> number }
   A -> (sum-of-squares (+ A 1) (* A 2))
)
(f 5)

\* 1.1.5 The Elements of Programming - The Substitution Model for Procedure Application*\
(f 5)
(sum-of-squares (+ 5 1) (* 5 2))
(+ (square 6) (square 10))
(+ (* 6 6) (* 10 10))
(+ 36 100)
(f 5)
(sum-of-squares (+ 5 1) (* 5 2))
(+ (square (+ 5 1)) (square (* 5 2)))

(+ (* (+ 5 1) (+ 5 1)) (* (* 5 2) (* 5 2)))
(+ (* 6 6) (* 10 10))
(+ 36 100)
136

\* 1.1.6 The Elements of Programming - Conditional Expressions and Predicates*\
(define abs
   { number --> number }
   X ->
      (if (> X 0)
          X
          (if (= X 0) X (- 0 X)))
)
(define abs
   { number --> number }
   X -> (if (< X 0) (- 0 X) X)
)
(set x 6)
(and (> (value x) 5) (< (value x) 10))
(define ge
   { number --> number }
   X Y -> (or (> X Y) (= X Y))
)
(define ge
   { number --> number }
   X Y -> (not (< X Y))
)

\* Exercise 1.1 *\
10
(+ 5 (+ 3 4))
(- 9 1)
(/ 6 2)
(+ (* 2 4) (- 4 6))
(set a 3)
(set b (+ (value a) 1))
(+ (+ (value a) (value b)) (* (value a) (value b)))
(= a b)
(if (and (> (value b) (value a))
         (< (value b) (* (value a) (value b))))
    (value b)
    (value a))
(if (= a 4)
    6
    (if (= b 4)
        (+ 6 (+ 7 a))
        25))
(+ 2 (if (> (value b) (value a)) (value b) (value a)))
(* (if (> (value a) (value b))
       (value a)
       (if (< (value a) (value b)) (value b) -1))
   (+ (value a) 1))


\* Exercise 1.2 *\
(/ (+ (+ 5 4) (- 2 (- 3 (+ 6 (/ 4 5)))))
   (* 3 (* (- 6 2) (- 2 7))))

\* Exercise 1.3 *\
(define three-n
   { number --> number --> number --> number }
   N1 N2 N3 ->
      (if (> N1 N2)
         (if (> N1 N3)
            (if (> N2 N3)
                (+ (* N1 N1) (* N2 N2))
                (+ (* N1 N1) (* N3 N3)))
            (+ (* N1 N1) (* N3 N3)))
         (if (> N2 N3)
            (if (> N1 N3)
                (+ (* N2 N2) (* N1 N1))
                (+ (* N2 N2) (* N3 N3)))
            (+ (* N2 N2) (* N3 N3))))
)

\* Exercise 1.4 *\
(define a-plus-abs-b
   { number --> number --> number }
   A B ->
      (if (> B 0)
         (+ A B)
         (- A B))
)

\* Exercise 1.5 *\
(define p
   () -> (p ())
)
(define test
   { number --> number --> number }
   X Y ->
   (if (= X 0) 0 Y)
)
\* commented out as this is in infinite loop
   (test 0 (p ()))  *\

\* 1.1.7 The Elements of Programming - Example: Square Roots by Newton's Method*\
(define square
   { number --> number }
   X -> (* X X)
)

(define good-enough?
   { number --> number --> number }
   Guess X -> (< (abs (- (square Guess) X)) 0.001)
)

(define average
   { number --> number --> number }
   X Y -> (/ (+ X Y) 2)
)

(define improve
   { number --> number --> number }
   Guess X -> (average Guess (/ X Guess))
)

(define sqrt-iter
   { number --> number --> number }
   Guess X ->
      (if (good-enough? Guess X)
         Guess
         (sqrt-iter (improve Guess X) X))
)

(define sqrtx
   { number --> number }
   X -> (sqrt-iter 1.0 X)
)

(sqrtx 9)
(sqrtx (+ 100 37))
(sqrtx (sqrtx (+ 2 (sqrtx 3))))
(square (sqrtx 1000))

\* Exercise 1.6 *\
(define new-if
   Predicate Then-Clause Else-Clause ->
      (if Predicate
         Then-Clause
         Else-Clause)
)
(new-if (= 2 3) 0 5)
(new-if (= 1 1) 0 5)
(define sqrt-iter
   { number --> number --> number }
   Guess X ->
      (new-if (good-enough? Guess X)
         Guess
         (sqrt-iter (improve Guess X) X))
)

\* from wadler paper *\
(define new-if
   true  X Y -> X
   false X Y -> Y
)

\* Exercse 1.7 *\
(define good-enough-gp?
   { number --> number --> number }
   Guess Prev -> (< (/ (abs (- Guess Prev)) Guess) 0.001)
)

(define sqrt-iter-gp
   { number --> number --> number }
   Guess Prev X ->
      (if (good-enough-gp? Guess Prev)
         Guess
         (sqrt-iter-gp (improve Guess X) Guess X))
)

(define sqrt-gp
   { number --> number }
   X -> (sqrt-iter-gp 4.0 1.0 X)
)

\* Exercise 1.8 *\
(define improve-cube
   { number --> number }
   Guess X ->
   (/ (+ (* 2 Guess) (/ X (* Guess Guess))) 3)
)

(define cube-iter
   { number --> number --> number }
   Guess Prev X ->
      (if (good-enough-gp? Guess Prev)
         Guess
         (cube-iter (improve-cube Guess X) Guess X))
)

(define cube-root
   { number --> number }
   X -> (cube-iter 27.0 1.0 X)
)

\* 1.1.8 The Elements of Programming - Procedures as Black-Box Abstractions*\
(define square
   { number --> number }
   X -> (* X X)
)

(define double
   { number --> number }
   X -> (+ X X)
)

\*
(define square
   { number --> number }
   X -> Math.exp(double(Math.ln x))
)
*\

(define good-enough?
   { number --> number --> number }
   Guess X -> (< (abs (- (square Guess) X)) 0.001)
)

(define improve
   { number --> number --> number }
   Guess X -> (average Guess (/ X Guess))
)

(define sqrt-iter
   { number --> number --> number }
   Guess X ->
      (if (good-enough? Guess X)
         Guess
         (sqrt-iter (improve Guess X) X))
)

(define sqrtx
   { number --> number }
   X -> (sqrt-iter 1.0 X)
)

(square 5)

\* Block-structured *\
(define sqrtx
   { number --> number }
   X -> (sqrt-iter 1.0 X)
)
fun sqrt x =
   let
      fun good_enough (guess, x) =
         abs(square_real guess - x) < 0.001

      fun improve (guess, x) =
         average(guess, x / guess)

      fun sqrtxiter (guess, x) =
         if good_enough(guess, x)
            then guess
            else sqrtxiter(improve(guess, x), x)
   in
      sqrtxiter(1.0, x)
   end

\* Taking advantage of lexical scoping *)
fun sqrt x =
   let
      fun good_enough guess =
         abs(square_real guess - x) < 0.001

      fun improve guess =
         average(guess, x / guess)

      fun sqrtxiter guess =
         if good_enough guess
            then guess
            else sqrtxiter(improve guess)
   in
      sqrtxiter 1.0
   end
*\

Chris Rathman / Chris.Rathman@tx.rr.com