(module tests mzscheme (provide tests-for-run tests-for-check) ;;;;;;;;;;;;;;;; tests ;;;;;;;;;;;;;;;; (define tests-for-run '( ;; simple arithmetic (positive-const "11" 11) (negative-const "-33" -33) (simple-arith-1 "-(44,33)" 11) ;; nested arithmetic (nested-arith-left "-(-(44,33),22)" -11) (nested-arith-right "-(55, -(22,11))" 44) ;; simple variables (test-var-1 "x" 10) (test-var-2 "-(x,1)" 9) (test-var-3 "-(1,x)" -9) ;; simple unbound variables (test-unbound-var-1 "foo" error) (test-unbound-var-2 "-(x,foo)" error) ;; simple conditionals (if-true "if zero?(0) then 3 else 4" 3) (if-false "if zero?(1) then 3 else 4" 4) ;; test dynamic typechecking (no-bool-to-diff-1 "-(zero?(0),1)" error) (no-bool-to-diff-2 "-(1,zero?(0))" error) (no-int-to-if "if 1 then 2 else 3" error) ;; make sure that the test and both arms get evaluated ;; properly. (if-eval-test-true "if zero?(-(11,11)) then 3 else 4" 3) (if-eval-test-false "if zero?(-(11, 12)) then 3 else 4" 4) ;; and make sure the other arm doesn't get evaluated. (if-eval-test-true-2 "if zero?(-(11, 11)) then 3 else foo" 3) (if-eval-test-false-2 "if zero?(-(11,12)) then foo else 4" 4) ;; simple let (simple-let-1 "let x = 3 in x" 3) ;; make sure the body and rhs get evaluated (eval-let-body "let x = 3 in -(x,1)" 2) (eval-let-rhs "let x = -(4,1) in -(x,1)" 2) ;; check nested let and shadowing (simple-nested-let "let x = 3 in let y = 4 in -(x,y)" -1) (check-shadowing-in-body "let x = 3 in let x = 4 in x" 4) (check-shadowing-in-rhs "let x = 3 in let x = -(x,1) in x" 2) ;; simple applications (apply-proc-in-rator-pos "(proc(int x) -(x,1) 30)" 29) (interp-ignores-type-info-in-proc "(proc((int -> int) x) -(x,1) 30)" 29) (apply-simple-proc "let f = proc (int x) -(x,1) in (f 30)" 29) (let-to-proc-1 "(proc((int -> int) f)(f 30) proc(int x)-(x,1))" 29) (nested-procs "((proc (int x) proc (int y) -(x,y) 5) 6)" -1) (nested-procs2 "let f = proc(int x) proc (int y) -(x,y) in ((f -(10,5)) 6)" -1) (y-combinator-1 " let fix = proc (bool f) let d = proc (bool x) proc (bool z) ((f (x x)) z) in proc (bool n) ((f (d d)) n) in let t4m = proc (bool f) proc(bool x) if zero?(x) then 0 else -((f -(x,1)),-4) in let times4 = (fix t4m) in (times4 3)" 12) ;; simple letrecs (simple-letrec-1 "letrec int f(int x) = -(x,1) in (f 33)" 32) (simple-letrec-2 "letrec int f(int x) = if zero?(x) then 0 else -((f -(x,1)), -2) in (f 4)" 8) (simple-letrec-3 "let m = -5 in letrec int f(int x) = if zero?(x) then 0 else -((f -(x,1)), m) in (f 4)" 20) ; (fact-of-6 "letrec ; fact(x) = if zero?(x) then 1 else *(x, (fact sub1(x))) ;in (fact 6)" ; 720) (HO-nested-letrecs "letrec int even((int -> int) odd) = proc(int x) if zero?(x) then 1 else (odd -(x,1)) in letrec int odd(int x) = if zero?(x) then 0 else ((even odd) -(x,1)) in (odd 13)" 1) (modules-take-one-value "module m : {val u : int} = {val u = 3} from m take u" 3) ;; the interpreter doesn't know about the abstraction boundaries. (modules-take-from-parameterized-module "module m (m1:{}) : {val u : int} = {val u = 3} from m take u" error) (modules-check-interface-subtyping-1 " module m : {val u : int} = {val u = 3 val v = 4} from m take u" 3) (modules-take-one-value-but-interface-bad " module m : {} = {val u = 3} from m take u" 3) (modules-take-bad-value "module m : {} = {val u = 3} from m take x" error) (modules-two-vals "module m : {val u:int val v:int} = {val u = 44 val v = 33} -(from m take u, from m take v)" 11) (modules-two-vals-bad-interface-1 "module m : {val u : int val v : bool} = {val u = 44 val v = 33} -(from m take u, from m take v)" 11) (modules-check-let*-1 "module m : {val u : int val v : int} = {val u = 44 val v = -(u,11)} -(from m take u, from m take v)" 11) (modules-check-let*-2 "module m1 : {val u : int} = {val u = 44} module m2 : {val v : int} = {val v = -(from m1 take u,11)} -(from m1 take u, from m2 take v)" 11) (modules-export-abs-type-1 "module m1 : {type t} = {type-abbrev t = int} 33" 33) (modules-take-from-ints-0.1 "module m1 : {type t val zero:t} = {type-abbrev t = int val zero = 0} 33" 33) (modules-take-from-ints-0.1.91 "module m1 : {type t val zero : t} = {type-abbrev t = int val zero = 0 val foo = 3} let check = proc (from m1 take t x) zero?(0) in (check from m1 take zero)" #t) (modules-take-from-ints-0.2 "module m1 : {type t val zero:t val check : (t -> bool) } = {type-abbrev t = int val zero = 0 val check = proc(t x) zero?(x)} (from m1 take check from m1 take zero)" #t) (modules-take-from-ints-1 "module int1 : {type t val zero:t val succ: (t -> t) val pred: (t -> t) val check: (t -> bool) } = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val check = proc(t x) zero?(x) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let check = from int1 take check in (check (s (s (p (s z)))))" #f) (modules-take-from-ints-2 "module int1 : {type t val zero: t val succ: (t -> t) val pred: (t -> t) val is-zero : (t -> bool) } = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let z? = from int1 take is-zero in if (z? (s z)) then 22 else 33" 33) (modules-take-from-ints-2-bad-1 "module int1 : {type t val zero: t val succ: (t -> t) val pred: (t -> t) val is-zero : (t -> bool) } = {val zero = proc (? x) x val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(0) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let z? = from int1 take is-zero in if (z? (s z)) then 22 else 33" error) (modules-take-from-ints-3 "module int1 : {type t val zero: t val succ: (t -> t) val pred: (t -> t) val is-zero : (t -> int) } = {val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let z? = from int1 take is-zero in if (z? (s z)) then 22 else 33" 33) (modules-apply-param-module-0.1 "module copy-module ( m : {type t val zero:t }) : {type t val zero:t} = {type-abbrev t = from m take t val zero = from m take zero} 33" 33) (modules-myints-0.1 " module int1:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = {val zero = 0 val succ = proc(? x) -(x,-2) val pred = proc(? x) -(x,2) val is-zero = proc (? x) zero?(x) } let zero = from int1 take zero in let succ = from int1 take succ in let is-zero = from int1 take is-zero in (succ (succ zero))" 4) (modules-myints-0.2 " module int1:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = {val zero = 0 val succ = proc(? x) -(x,2) val pred = proc(? x) -(x,-2) val is-zero = proc (? x) zero?(x) } let zero = from int1 take zero in let succ = from int1 take succ in let is-zero = from int1 take is-zero in (succ (succ zero))" -4) (modules-apply-param-module-1 " module makeints (m:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)}) : {type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = {val zero = from m take zero val succ = proc (? x) (from m take succ (from m take succ x)) val pred = proc (? x) (from m take pred (from m take pred x)) val is-zero = proc (? x) (from m take is-zero x) } module int1:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = {val zero = 0 val succ = proc(? x) -(x,2) val pred = proc(? x) -(x,-2) val is-zero = proc (? x) zero?(x) } module int2:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = (makeints int1) (from int2 take succ (from int2 take succ from int2 take zero)) " -8) (modules-apply-param-module-2 "module makeints ( m : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool) }) : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = {type-abbrev t = from m take t val zero = from m take zero val succ = proc (? x) (from m take succ (from m take succ x)) val pred = proc (? x) (from m take pred (from m take pred x)) val is-zero = proc (? x) (from m take is-zero x) } module int1 : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,2) val pred = proc(? x) -(x,-2) val is-zero = proc (? x) zero?(x) } module int2 : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = (makeints int1) let check = proc (from int2 take t x) zero?(0) in (check (from int2 take succ (from int2 take succ from int2 take zero)))" #t) (modules-apply-param-module-3 " module makeints (m:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)}) : {type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = {val zero = from m take zero val succ = proc (? x) (from m take succ (from m take succ x)) val pred = proc (? x) (from m take pred (from m take pred x)) val is-zero = proc (? x) (from m take is-zero x) } module int1:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,2) val pred = proc(? x) -(x,-2) val is-zero = proc (? x) zero?(x) } module int2:{type t val zero : (t -> t) val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)} = (makeints int1) let zero = from int2 take zero in let succ = from int2 take succ in let pred = from int2 take pred in let is-zero = from int2 take is-zero in letrec ? to-int (? n) = if (is-zero n) then 0 else -( (to-int (pred n)), -1) in (to-int (succ (succ zero))) " 2 ) (type-abbrev-0 "module m1 : {type-abbrev t = int val zero : t} = {type-abbrev t = int val zero = 0} -(from m1 take zero,1)" -1) (type-abbrev-1 "module m1 : {type t val zero : t } = {type-abbrev t = int val zero = 0 } module m2 : {type-abbrev t = from m1 take t % don't know % what's in m1! val one : t} = {type-abbrev t = int val one = 1} -(from m2 take one, from m1 take zero) " 1) (type-abbrev-2 "module m1 : {type-abbrev t = int val zero : t } = {type-abbrev t = int val zero = 0 } module m2 : {type-abbrev t = from m1 take t % now known to be int. val one : t} = {type-abbrev t = int val one = 1 } -(from m2 take one, from m1 take zero) " 1) ;; this example shows the need for substitution in types in a module ;; application. This also means you need to have the bound ;; variable in type of a parameterized module. (diamond-1 " module maker1 (m : {type t val succ : (t -> t)}) : {type-abbrev t = from m take t val double : (t -> t) } = {type-abbrev t = from m take t val double = let s = from m take succ in proc (? x) (s (s x)) } module m0 : {type t val succ : (t -> t) val zero : t } = {type-abbrev t = int val succ = proc(?x)-(x,-1) val zero = 0 } module m2 : {type-abbrev t = from m0 take t val double : (t -> t) } = (maker1 m0) let check = proc (from m0 take t x) zero?(0) in (check (from m2 take double from m0 take zero)) " #t) )) (define tests-for-check '( ;; tests from run-tests: ;; simple arithmetic (positive-const "11" int) (negative-const "-33" int) (simple-arith-1 "-(44,33)" int) ;; nested arithmetic (nested-arith-left "-(-(44,33),22)" int) (nested-arith-right "-(55, -(22,11))" int) ;; simple variables (test-var-1 "x" int) (test-var-2 "-(x,1)" int) (test-var-3 "-(1,x)" int) (zero-test-1 "zero?(-(3,2))" bool) (zero-test-2 "-(2,zero?(0))" error) ;; simple unbound variables (test-unbound-var-1 "foo" error) (test-unbound-var-2 "-(x,foo)" error) ;; simple conditionals (if-true "if zero?(1) then 3 else 4" int) (if-false "if zero?(0) then 3 else 4" int) ;; make sure that the test and both arms get evaluated ;; properly. (if-eval-test-true "if zero?(-(11,12)) then 3 else 4" int) (if-eval-test-false "if zero?(-(11, 11)) then 3 else 4" int) (if-eval-then "if zero?(1) then -(22,1) else -(22,2)" int) (if-eval-else "if zero?(0) then -(22,1) else -(22,2)" int) ;; make sure types of arms agree (new for lang5-1) (if-compare-arms "if zero?(0) then 1 else zero?(1)" error) (if-check-test-is-boolean "if 1 then 11 else 12" error) ;; simple let (simple-let-1 "let x = 3 in x" int) ;; make sure the body and rhs get evaluated (eval-let-body "let x = 3 in -(x,1)" int) (eval-let-rhs "let x = -(4,1) in -(x,1)" int) ;; check nested let and shadowing (simple-nested-let "let x = 3 in let y = 4 in -(x,y)" int) (check-shadowing-in-body "let x = 3 in let x = 4 in x" int) (check-shadowing-in-rhs "let x = 3 in let x = -(x,1) in x" int) ;; simple applications (apply-proc-in-rator-pos "(proc(int x) -(x,1) 30)" int) (checker-doesnt-ignore-type-info-in-proc "(proc((int -> int) x) -(x,1) 30)" error) (apply-simple-proc "let f = proc (int x) -(x,1) in (f 30)" int) (let-to-proc-1 "(proc( (int -> int) f)(f 30) proc(int x)-(x,1))" int) (nested-procs "((proc (int x) proc (int y) -(x,y) 5) 6)" int) (nested-procs2 "let f = proc (int x) proc (int y) -(x,y) in ((f -(10,5)) 3)" int) ;; simple letrecs (simple-letrec-1 "letrec int f(int x) = -(x,1) in (f 33)" int) (simple-letrec-2 "letrec int f(int x) = if zero?(x) then 0 else -((f -(x,1)), -2) in (f 4)" int) (simple-letrec-3 "let m = -5 in letrec int f(int x) = if zero?(x) then -((f -(x,1)), m) else 0 in (f 4)" int) (double-it " letrec int double (int n) = if zero?(n) then 0 else -( (double -(n,1)), -2) in (double 3)" int) ;; tests of expressions that produce procedures (build-a-proc-typed "proc (int x) -(x,1)" (int -> int)) (build-a-proc-typed-2 "proc (int x) zero?(-(x,1))" (int -> bool)) (bind-a-proc-typed "let f = proc (int x) -(x,1) in (f 4)" int) (bind-a-proc-return-proc "let f = proc (int x) -(x,1) in f" (int -> int)) (type-a-ho-proc-1 "proc((int -> bool) f) (f 3)" ((int -> bool) -> bool)) (type-a-ho-proc-2 "proc((bool -> bool) f) (f 3)" error) (apply-a-ho-proc "proc (int x) proc ( (int -> bool) f) (f x)" (int -> ((int -> bool) -> bool))) (apply-a-ho-proc-2 "proc (int x) proc ( (int -> (int -> bool)) f) (f x)" (int -> ((int -> (int -> bool)) -> (int -> bool))) ) (apply-a-ho-proc-3 "proc (int x) proc ( (int -> (int -> bool)) f) (f zero?(x))" error) (apply-curried-proc "((proc(int x) proc (int y)-(x,y) 4) 3)" int) (apply-a-proc-2-typed "(proc (int x) -(x,1) 4)" int) (apply-a-letrec " letrec int f(int x) = -(x,1) in (f 40)" int) (letrec-non-shadowing "(proc (int x) letrec bool loop(bool x) =(loop x) in x 1)" int) (letrec-return-fact " let times = proc (int x) proc (int y) -(x,y) % not really times in letrec int fact(int x) = if zero?(x) then 1 else ((times x) (fact -(x,1))) in fact" (int -> int)) (letrec-apply-fact " let times = proc (int x) proc (int y) -(x,y) % not really times in letrec int fact(int x) = if zero?(x) then 1 else ((times x) (fact -(x,1))) in (fact 4)" int) (pgm7b " letrec ? fact (? x) = if zero?(x) then 1 else -(x, (fact -(x,1))) in fact" (int -> int)) (dont-infer-circular-type "letrec ? f (? x) = (f f) in 33" error) (polymorphic-type-1 "letrec ? f (? x) = (f x) in f" (tvar01 -> tvar02)) ;; this test should fail, because the type given is insufficiently ;; polymorphic. So we use it for testing the test harness, but not for ;; testing the checker. ;; (polymorphic-type-1a ;; "letrec ? f (? x) = (f x) in f" ;; (tvar01 -> tvar01)) (polymorphic-type-2 "letrec ?f (? x) = (f x) in proc (? n) (f -(n,1))" (int -> tvar01)) (modules-take-one-value "module m : {val u : int} = {val u = 3} from m take u" int) (modules-take-from-parameterized-module "module m (m1:{}) : {val u : int} = {val u = 3} from m take u" error) (modules-check-interface-subtyping-1 " module m : {val u : int} = {val u = 3 val v = 4} from m take u" int) (modules-take-one-value-but-interface-bad " module m : {} = {val u = 3} from m take u" error) (modules-take-bad-value "module m : {} = {val u = 3} from m take x" error) (modules-two-vals "module m : {val u:int val v:int} = {val u = 44 val v = 33} -(from m take u, from m take v)" int) (modules-two-vals-bad-interface-1 "module m : {val u : int val v : bool} = {val u = 44 val v = 33} -(from m take u, from m take v)" error) (modules-two-vals-bad-interface-2 "module m:{val u:int val v:bool} = {val v = zero?(0) val u = 33} -(from m take u, from m take v)" error) (modules-check-let*-1 "module m : {val u : int val v : int} = {val u = 44 val v = -(u,11)} -(from m take u, from m take v)" int) (modules-check-let*-2 "module m1 : {val u : int} = {val u = 44} module m2 : {val v : int} = {val v = -(from m1 take u,11)} -(from m1 take u, from m2 take v)" int) (modules-export-abs-type-1 "module m1 : {type t} = {type-abbrev t = int} 33" int) (modules-take-from-ints-0.1 "module m1 : {type t val zero:t} = {type-abbrev t = int val zero = 0} 33" int) (modules-take-from-ints-0.1.91 "module m1 : {type t val zero:t} = {type-abbrev t = int val zero = 0 val foo = 3} let check = proc (from m1 take t x) zero?(0) in (check from m1 take zero)" bool) (modules-take-from-ints-0.2 "module m1 : {type t val zero:t val check : (t -> bool) } = {type-abbrev t = int val zero = 0 val check = proc(t x) zero?(x)} (from m1 take check from m1 take zero)" bool) (modules-mybool-1 "module mybool : {type t val true : t val false : t val and : (t -> (t -> t)) val not : (t -> t) val to-bool : (t -> bool)} = {type-abbrev t = int val true = 0 val false = 1 val and = proc (t x) proc (t y) if zero?(x) then y else false val not = proc (t x) if zero?(x) then false else true val to-bool = proc (t x) if zero?(x) then zero?(0) else zero?(1) } (from mybool take to-bool from mybool take false) " bool) (modules-take-from-ints-1 "module int1 : {type t val zero:t val succ: (t -> t) val pred: (t -> t) val check: (t -> bool) } = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val check = proc(t x) zero?(0) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let check = from int1 take check in (check (s (s (p (s z)))))" bool) (modules-take-from-ints-2 "module int1 : {type t val zero: t val succ: (t -> t) val pred: (t -> t) val is-zero : (t -> bool) } = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let z? = from int1 take is-zero in if (z? (s z)) then 22 else 33" int ) (modules-take-from-ints-2-bad-1 "module int1 : {type t val zero: t val succ: (t -> t) val pred: (t -> t) val is-zero : (t -> bool) } = {val zero = proc (? x) x val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let z? = from int1 take is-zero in if (z? (s z)) then 22 else 33" error) (modules-take-from-ints-3 "module int1 : {type t val zero: t val succ: (t -> t) val pred: (t -> t) val is-zero : (t -> int) } = {val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } let z = from int1 take zero in let s = from int1 take succ in let p = from int1 take pred in let z? = from int1 take is-zero in if (z? (s z)) then 22 else 33" error) (modules-check-shadowing-1 " module int1:{type t val zero : t val succ : (t -> t) val is-zero : (t -> bool)} = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } module int2 : {val zero : from int1 take t val succ : (from int1 take t -> from int1 take t) val is-zero : (from int1 take t -> bool)} = {val zero = from int1 take zero val succ = from int1 take succ val is-zero = from int1 take is-zero} let s = from int2 take succ in let z? = from int2 take is-zero in let z = from int2 take zero in (z? (s z))" bool) (modules-check-shadowing-1.8 "module int1 : {type t val zero : t} = {type-abbrev t = int val zero = 0} module int2 : {val foo : from int1 take t} = {val foo = from int1 take zero} let v = from int2 take foo in 33 " int) (modules-check-shadowing-1.9 "module int1 : {type t val zero : t} = {type-abbrev t = int val zero = 0} module int1 : {val foo : from int1 take t} = {val foo = from int1 take zero} let v = from int1 take foo in 33 " int) (modules-check-shadowing-2 " module int1:{type t val zero : t val succ : (t -> t) val is-zero : (t -> bool)} = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,-1) val pred = proc(? x) -(x,1) val is-zero = proc (? x) zero?(x) } module int1 : {val zeroz : from int1 take t val succ : (from int1 take t -> from int1 take t) val is-zero : (from int1 take t -> bool)} = {val zeroz = from int1 take zero val succ = from int1 take succ val is-zero = from int1 take is-zero} let s = from int1 take succ in let z? = from int1 take is-zero in let z = from int1 take zeroz in (z? (s z))" bool) (modules-apply-param-module-0.1 "module copy-module ( m : {type t val zero:t }) : {type t val zero:t} = {type-abbrev t = from m take t val zero = from m take zero} 33" int) (modules-add-double-1 "module add-double (m:{type t val zero : t val succ : (t -> t) val pred : (t -> t) val is-zero : (t -> bool)}) : {val double : (from m take t -> from m take t)} = {val double = letrec from m take t double (from m take t x) = if (from m take is-zero x) then from m take zero else (from m take succ (from m take succ x)) in double} module int1 : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,2) val pred = proc(? x) -(x,-2) val is-zero = proc (? x) zero?(x) } module int2 : {val double : (from int1 take t -> from int1 take t) } = (add-double int1) (from int1 take is-zero (from int2 take double (from int1 take succ from int1 take zero)))" bool) (modules-apply-param-module-1 "module makeints ( m : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool) }) : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = {type-abbrev t = from m take t val zero = from m take zero val succ = proc (? x) (from m take succ (from m take succ x)) val pred = proc (? x) (from m take pred (from m take pred x)) val is-zero = proc (? x) (from m take is-zero x) } module int1 : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = {type-abbrev t = int val zero = 0 val succ = proc(? x) -(x,2) val pred = proc(? x) -(x,-2) val is-zero = proc (? x) zero?(x) } module int2 : {type t val zero:t val succ:(t -> t) val pred:(t -> t) val is-zero:(t -> bool)} = (makeints int1) let check = proc (from int2 take t x) zero?(0) in (check (from int2 take succ (from int2 take succ from int2 take zero)))" bool) (type-abbrev-0 "module m1 : {type-abbrev t = int val zero : t} = {type-abbrev t = int val zero = 0} -(from m1 take zero,1)" int) (type-abbrev-1 "module m1 : {type t val zero : t } = {type-abbrev t = int val zero = 0 } module m2 : {type-abbrev t = from m1 take t % don't know % what's in m1! val one : t} = {type-abbrev t = int val one = 1} -(from m2 take one, from m1 take zero) " error) (type-abbrev-2 "module m1 : {type-abbrev t = int val zero : t } = {type-abbrev t = int val zero = 0 } module m2 : {type-abbrev t = from m1 take t % now known to be int. val one : t} = {type-abbrev t = int val one = 1 } -(from m2 take one, from m1 take zero) " int) ;; this example shows the need for substitution in types in a module ;; application. This also means you need to have the bound ;; variable in type of a parameterized module. (diamond-1 " module maker1 (m : {type t val succ : (t -> t)}) : {type-abbrev t = from m take t val double : (t -> t) } = {type-abbrev t = from m take t val double = let s = from m take succ in proc (? x) (s (s x)) } module m0 : {type t val succ : (t -> t) val zero : t } = {type-abbrev t = int val succ = proc(?x)-(x,-1) val zero = 0 } module m2 : {type-abbrev t = from m0 take t val double : (t -> t) } = (maker1 m0) let check = proc (from m0 take t x) zero?(0) in (check (from m2 take double from m0 take zero)) " bool) )) )