(module test-suite mzscheme (provide tests-for-run tests-for-check tests-for-parse) (define the-test-suite '( ;; tests from run-tests: ;; ;; simple arithmetic ;; (positive-const "11" int 11) ;; (negative-const "-33" int -33) ;; (simple-arith-1 "-(44,33)" int 11) ;; ;; nested arithmetic ;; (nested-arith-left "-(-(44,33),22)" int -11) ;; (nested-arith-right "-(55, -(22,11))" int 44) ;; ;; simple variables ;; (test-var-1 "x" error) ;; (test-var-2 "-(x,1)" error) ;; (test-var-3 "-(1,x)" error) ;; (zero-test-1 "zero?(-(3,2))" bool #f) ;; (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?(0) then 3 else 4" int 3) ;; (if-false "if zero?(1) then 3 else 4" int 4) ;; ;; make sure that the test and both arms get evaluated ;; ;; properly. ;; (if-eval-test-true "if zero?(-(11,11)) then 3 else 4" int 3) ;; (if-eval-test-false "if zero?(-(11,12)) then 3 else 4" int 4) ;; (if-eval-then "if zero?(0) then -(22,1) else -(22,2)" int 21) ;; (if-eval-else "if zero?(1) then -(22,1) else -(22,2)" int 20) ;; ;; 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 3) ;; ;; make sure the body and rhs get evaluated ;; (eval-let-body "let x = 3 in -(x,1)" int 2) ;; (eval-let-rhs "let x = -(4,1) in -(x,1)" int 2) ;; ;; check nested let and shadowing ;; (simple-nested-let "let x = 3 in let y = 4 in -(x,y)" int -1) ;; (check-shadowing-in-body "let x = 3 in let x = 4 in x" int 4) ;; (check-shadowing-in-rhs "let x = 3 in let x = -(x,1) in x" int 2) ;; simple applications (apply-proc-in-rator-pos "(proc(x : int) -(x,1) 30)" int 29) (checker-doesnt-ignore-type-info-in-proc-but-interp-does "(proc(x : (int -> int)) -(x,1) 30)" error 29) (apply-simple-proc "let f = proc (x : int) -(x,1) in (f 30)" int 29) (let-to-proc-1 "(proc( f : (int -> int))(f 30) proc(x : int)-(x,1))" int 29) (nested-procs "((proc (x : int) proc (y : int) -(x,y) 5) 6)" int -1) (nested-procs2 "let f = proc (x : int) proc (y : int) -(x,y) in ((f -(10,5)) 3)" int 2) ;; simple letrecs (simple-letrec-1 "letrec int f(x : int) = -(x,1) in (f 33)" int 32) (simple-letrec-2 "letrec int double(x : int) = if zero?(x) then 0 else -((double -(x,1)), -2) in (double 4)" int 8) (simple-letrec-3 "let m = -5 in letrec int f(x : int) = if zero?(x) then 0 else -((f -(x,1)), m) in (f 4)" int 20) (double-it " letrec int double (n : int) = if zero?(n) then 0 else -( (double -(n,1)), -2) in (double 3)" int 6) ;; tests of expressions that produce procedures (build-a-proc-typed "proc (x : int) -(x,1)" (int -> int)) (build-a-proc-typed-2 "proc (x : int) zero?(-(x,1))" (int -> bool)) (bind-a-proc-typed "let f = proc (x : int) -(x,1) in (f 4)" int 3) (bind-a-proc-return-proc "let f = proc (x : int) -(x,1) in f" (int -> int)) (type-a-ho-proc-1 "proc(f : (int -> bool)) (f 3)" ((int -> bool) -> bool)) (type-a-ho-proc-2 "proc(f : (bool -> bool)) (f 3)" error) (apply-a-ho-proc "proc (x : int) proc ( f : (int -> bool)) (f x)" (int -> ((int -> bool) -> bool))) (apply-a-ho-proc-2 "proc (x : int) proc ( f : (int -> (int -> bool))) (f x)" (int -> ((int -> (int -> bool)) -> (int -> bool))) ) (apply-a-ho-proc-3 "proc (x : int) proc ( f : (int -> (int -> bool))) (f zero?(x))" error) (apply-curried-proc "((proc(x : int) proc (y : int)-(x,y) 4) 3)" int 1) (apply-a-proc-2-typed "(proc (x : int) -(x,1) 4)" int 3) (apply-a-letrec " letrec int f(x : int) = -(x,1) in (f 40)" int 39) (letrec-non-shadowing "(proc (x : int) letrec bool loop(x : bool) =(loop x) in x 1)" int 1) (letrec-return-fact " let times = proc (x : int) proc (y : int) -(x,y) % not really times in letrec int fact(x : int) = if zero?(x) then 1 else ((times x) (fact -(x,1))) in fact" (int -> int)) (letrec-apply-the-fcn " let f = proc (x : int) proc (y : int) -(x,y) in letrec int loop(x : int) = if zero?(x) then 1 else ((f x) (loop -(x,1))) in (loop 4)" int 3) (modules-declare-and-ignore " module m interface [u : int] body [u = 3] 33" int 33) (modules-take-one-value " module m interface [u : int] body [u = 3] from m take u" int 3) (modules-take-one-value-no-import "module m interface [u : int] body [u = 3] from m take u" int 3) (modules-take-from-parameterized-module " module m interface ((m1 : []) => [u : int]) body module-proc (m1 : []) [u = 3] from m take u " error error) (modules-check-iface-subtyping-1 " module m interface [u : int] body [u = 3 v = 4] from m take u" int 3) ;; if the interpreter always called the typechecker, or put ;; only declared variables in the module, this would raise an ;; error. Exercise: make this modification. (modules-take-one-value-but-interface-bad " module m interface [] body [u = 3] from m take u" ; this version for permissive interp error 3 ; this version for strict interp ; error error ) (modules-take-bad-value "module m interface [] body [u = 3] from m take x" error error) (modules-two-vals " module m interface [u : int v : int] body [u = 44 v = 33] -(from m take u, from m take v)" int 11) (modules-two-vals-bad-interface-1 "module m interface [u : int v : bool] body [u = 44 v = 33] -(from m take u, from m take v)" error 11) (modules-extra-vals-are-ok-1 " module m interface [x : int] body [x = 3 y = 4] from m take x" int 3) (module-extra-vals-are-ok-2 " module m interface [y : int] body [x = 3 y = 4] from m take y" int) (module-extra-types-are-ok-11 "module m interface [y : int] body [x = 3 type t = int y = 4] from m take y" int 4) (module-extra-types-are-ok-12 "module m interface [opaque t y : int] body [type u = bool x = 3 type t = int y = 4] from m take y" int) (module-extra-types-are-ok-13 "module m interface [transparent t = int y : int] body [type u = bool x = 3 type t = int y = 4] from m take y" int 4) (modules-two-vals-bad-interface-14 "module m interface [v : int u : bool] body [v = zero?(0) u = 33] -(from m take u, from m take v)" error) (modules-check-let*-1 "module m interface [u : int v : int] body [u = 44 v = -(u,11)] -(from m take u, from m take v)" int 11) (modules-check-let*-2.0 "module m1 interface [u : int] body [u = 44] module m2 interface [v : int] body [v = -(from m1 take u,11)] -(from m1 take u, from m2 take v)" int 11) (modules-check-let*-2.05 "module m1 interface [u : int] body [u = 44] module m2 interface [v : int] body [v = -(from m1 take u,11)] 33" int 33) ; doesn't actually import anything (modules-check-let*-2.1 "module m1 interface [u : int] body [u = 44] module m2 interface [v : int] body [v = -(from m1 take u,11)] -(from m1 take u, from m2 take v)" int 11) (modules-check-let*-2.2 "module m2 interface [v : int] body [v = -(from m1 take u,11)] module m1 interface [u : int] body [u = 44] -(from m1 take u, from m2 take v)" error) (modules-check-parameterized-1 " module m1 interface ((m : [v : int]) => [w : int]) body module-proc (m : [v : int]) [w = -(from m take v, 1)] module m2 interface [v : int] body [v = 33] module m3 interface [w : int] body (m1 m2) from m3 take w" int 32) (modules-check-parameterized-bad-argument " module m1 interface ((m : [v : int]) => [w : int]) body module-proc (m : [v : int]) [w = from m take v] module m2 interface [u : int] body [u = 33] module m3 interface [w : int] body (m1 m2) from m3 take w" error) (modules-check-parameterized-bad-interface-1 " module m1 interface ((m : [v : int]) => [w : int]) body module-proc (m : [v : int]) [w = from m take v] module m2 interface [v : int] body [x = 33] % bad module m3 interface [w : int] body (m1 m2) from m3 take w" error) (modules-check-parameterized-2 " module m1 interface ((m : [v : int]) => [u : int]) body module-proc (m : [v : int]) [w = from m take v] module m2 interface [v : int] body [v = 33] module m3 interface [w : int] body (m1 m2) from m3 take w" error) (modules-export-abs-type-1 "module m1 interface [opaque t] body [type t = int] 33" int 33) (modules-take-from-ints-0.1 "module m1 interface [opaque t zero : t] body [type t = int zero = 0] 33" int 33) (modules-take-from-ints-0.1a "module m1 interface [opaque t zero : t] body [type t = int zero = 0] from m1 take zero" (from m1 take t) 0) (modules-take-from-ints-0.1.91 "module m1 interface [opaque t zero : t] body [type t = int zero = 0 foo = 3] let check = proc (x : from m1 take t) zero?(0) in (check from m1 take zero)" bool #t) (modules-take-from-ints-0.1.91a "module m1 interface [opaque t zero : t] body [type t = int zero = 0 foo = 3] let check = proc (x : from m1 take t ) zero?(0) in check" ((from m1 take t) -> bool)) (modules-take-from-ints-0.2 "module m1 interface [opaque t zero : t check : (t -> bool)] body [type t = int zero = 0 check = proc(x : t) zero?(x)] (from m1 take check from m1 take zero)" bool #t) (modules-mybool-1 "module mybool interface [opaque t true : t false : t and : (t -> (t -> t)) not : (t -> t) to-bool : (t -> bool)] body [type t = int true = 0 false = 1 and = proc (x : t) proc (y : t) if zero?(x) then y else false not = proc (x : t) if zero?(x) then false else true to-bool = proc (x : t) if zero?(x) then zero?(0) else zero?(1) ] (from mybool take to-bool from mybool take false) " bool #f) (modules-mybool-1a "module mybool interface [opaque t true : t false : t and : (t -> (t -> t)) not : (t -> t) to-bool : (t -> bool)] body [type t = int true = 0 false = 1 and = proc (x : t) proc (y : t) if zero?(x) then y else false not = proc (x : t) if zero?(x) then false else true to-bool = proc (x : t) if zero?(x) then zero?(0) else zero?(1) ] from mybool take to-bool" ((from mybool take t) -> bool)) (modules-mybool-1b "module mybool interface [opaque t true : t false : t and : (t -> (t -> t)) not : (t -> t) to-bool : (t -> bool)] body [type t = int true = 0 false = 1 and = proc (x : t) proc (y : t) if zero?(x) then y else false not = proc (x : t) if zero?(x) then false else true to-bool = proc (x : t) if zero?(x) then zero?(0) else zero?(1) ] from mybool take false " (from mybool take t) ) (modules-take-from-ints-1 "module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) check : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) check = proc(x : t) zero?(0)] let z = from ints-1 take zero in let s = from ints-1 take succ in let p = from ints-1 take pred in let check = from ints-1 take check in (check (s (s (p (s z)))))" bool #t) (modules-take-from-ints-1a "module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) check : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) check = proc(x : t) zero?(0)] let z = from ints-1 take zero in let s = from ints-1 take succ in let p = from ints-1 take pred in let check = from ints-1 take check in s" ((from ints-1 take t) -> (from ints-1 take t))) (modules-take-from-ints-1b "module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) check : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) check = proc(x : t) zero?(0)] let z = from ints-1 take zero in let s = from ints-1 take succ in let p = from ints-1 take pred in let check = from ints-1 take check in check" ((from ints-1 take t) -> bool)) (modules-take-from-ints-2 "module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) is-zero = proc (x : t) zero?(x)] let z = from ints-1 take zero in let s = from ints-1 take succ in let p = from ints-1 take pred in let z? = from ints-1 take is-zero in if (z? (s z)) then 22 else 33" int 33) (modules-take-from-ints-2-bad-1 "module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [zero = proc (x : t) x succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) is-zero = proc (x : t) zero?(x) ] let z = from ints-1 take zero in let s = from ints-1 take succ in let p = from ints-1 take pred in let z? = from ints-1 take is-zero in if (z? (s z)) then 22 else 33" error) (modules-take-from-ints-3 "module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> int)] body [zero = 0 succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) is-zero = proc (x : t) zero?(x)] let z = from ints-1 take zero in let s = from ints-1 take succ in let p = from ints-1 take pred in let z? = from ints-1 take is-zero in if (z? (s z)) then 22 else 33" error) (modules-check-polymorphism-1 " module m interface [opaque t f : (t -> t)] body [type t = int f = proc (x : t) x] from m take f" ((from m take t) -> (from m take t))) (modules-check-polymorphism-1a " module m interface [opaque t f : (t -> t)] body [type t = int f = proc (x : t) x] from m take f" ((from m take t) -> (from m take t))) (modules-check-polymorphism-1b " module m interface [opaque t f : (t -> t)] body [type t = int f = proc (x : t) -(x,1)] from m take f" ((from m take t) -> (from m take t))) (modules-check-shadowing-1 " module ints-1 interface [opaque t zero : t succ : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,-1) pred = proc(x : t) -(x,1) is-zero = proc (x : t) zero?(x)] module ints-2 interface [zero : from ints-1 take t succ : (from ints-1 take t -> from ints-1 take t) is-zero : (from ints-1 take t -> bool)] body [zero = from ints-1 take zero succ = from ints-1 take succ is-zero = from ints-1 take is-zero] let s = from ints-2 take succ in let z? = from ints-2 take is-zero in let z = from ints-2 take zero in (z? (s z))" bool #f) (modules-check-shadowing-1.8 " module ints-1 interface [opaque t zero : t] body [type t = int zero = 0] module ints-2 interface [foo : from ints-1 take t] body [foo = from ints-1 take zero] let v = from ints-2 take foo in 33 " int 33) (modules-check-shadowing-1.8a "module ints-1 interface [opaque t zero : t] body [type t = int zero = 0] module ints-2 interface [ foo : from ints-1 take t] body [foo = from ints-1 take zero] from ints-2 take foo " (from ints-1 take t)) ;; this test is bogus, because duplicate module names are not ;; allowed. ;; (modules-check-shadowing-1.9.1 ;; "module ints-1 interface [opaque t zero : t] ;; body [type t = int zero = 0] ;; module ints-1 interface [foo : from ints-1 take t] ;; body import ints-1 ;; [foo = from ints-1 take zero] ;; let v = from ints-1 take foo ;; in 33 ;; " int) ;; Once exercise 8.1 (reject duplicated module names) is done, the ;; test should be: ;; (modules-check-shadowing-1.9.2 ;; "module ints-1 interface [opaque t zero : t] ;; body [type t = int zero = 0] ;; module ints-1 interface [foo : from ints-1 take t] ;; body import ints-1 ;; [foo = from ints-1 take zero] ;; let v = from ints-1 take foo ;; in 33 ;; " error) ; <<<---- changed outcome. ;; This is bogus in yet another way. In the following example, v ;; has the type of from ints-1 take foo, which is from ints-1 take ;; t. But at the point where v is used, ints-1 has been rebound, ;; and doesn't even have a type component t. ;; (modules-check-shadowing-1.9.2 ;; "module ints-1 interface [opaque t zero : t] ;; body [type t = int zero = 0] ;; module ints-1 interface [foo : from ints-1 take t] ;; body import ints-1 ;; [foo = from ints-1 take zero] ;; let v = from ints-1 take foo ;; in v ;; " (from ints-1 take t)) ;; We can take advantage of this confusion to generate an unsound ;; program that type-checks: ;; (modules-check-shadowing-1.9.3 " ;; module ints-1 ;; interface [opaque t zero : t] ;; body [type t = int zero = 0] ;; module ints-1 ;; interface [zero : from ints-1 take t ;; opaque t ;; f : (t -> int)] ;; body [zero = from ints-1 take zero ;; type t = bool ;; f = proc (b : t) if b then 33 else 44] ;; (from ints-1 take f ;; from ints-1 take zero)" ;; int) ;; this code allows the application of ints-1.f because its type is ;; (ints-1.t -> int), and zero has type ints-1.t . But those are ;; two different modules both named ints-1. ;; In general, the solution is to rename the inner ints-1 to avoid ;; the conflict. Exercise: do this. When you do this, ;; modules-check-shadowing-1.9.3 should give back "error". ;; Aren't you sorry you asked? (modules-apply-param-module-0.1 "module copy-module interface ((m : [opaque t zero : t]) => [opaque t zero : t]) body module-proc (n : [opaque t zero : t]) [type t = from n take t zero = from n take zero] 33" int 33) (modules-apply-param-module-1 "module makeints interface ((m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) => [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) body module-proc (m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) [type t = from m take t zero = from m take zero succ = proc (x : t) (from m take succ (from m take succ x)) pred = proc (x : t) (from m take pred (from m take pred x)) is-zero = proc (x : t) (from m take is-zero x)] module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x)] module ints-2 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body (makeints ints-1) let check = proc (x : from ints-2 take t) zero?(0) in (check (from ints-2 take succ (from ints-2 take succ from ints-2 take zero)))" bool #t) (transparent-0 "module m1 interface [transparent t = int zero : t] body [type t = int zero = 0] -(from m1 take zero,1)" int) (transparent-1 "module m1 interface [opaque t zero : t] body [type t = int zero = 0] module m2 interface [transparent t = from m1 take t % don't know % what's in m1! one : t] body [type t = int one = 1] -(from m2 take one, from m1 take zero) " error) (transparent-2 "module m1 interface [transparent t = int zero : t] body [type t = int zero = 0] module m2 interface [transparent t = from m1 take t % now known to be int. one : t] body [type t = int one = 1] -(from m2 take one, from m1 take zero) " int 1) (modules-add-double-1 "module add-double interface ((m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) => [double : (from m take t -> from m take t)]) body module-proc (m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) [double = letrec from m take t double (x : from m take t) = 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 ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x) ] module ints-2 interface [double : (from ints-1 take t -> from ints-1 take t)] body (add-double ints-1) (from ints-1 take is-zero (from ints-2 take double (from ints-1 take succ from ints-1 take zero)))" bool #f ) ;; this example shows the need for substitution in types in a module ;; application. This also means you need to have the bound ;; variable in the type of a parameterized module. (diamond-1 " module maker1 interface ((m : [opaque t succ : (t -> t)]) => [transparent t = from m take t double : (t -> t)]) body module-proc (m : [opaque t succ : (t -> t)]) [type t = from m take t double = let s = from m take succ in proc (x : t) (s (s x))] module m0 interface [opaque t succ : (t -> t) zero : t] body [type t = int succ = proc(x : t)-(x,-1) zero = 0] module m2 interface [transparent t = from m0 take t double : (t -> t)] body (maker1 m0) let check = proc (x : from m0 take t) zero?(0) in (check (from m2 take double from m0 take zero)) " bool #t) (pass-around-ho-module-1 " module m1 interface ((m : [v : int]) => [u : int]) body module-proc (m : [v : int]) [u = from m take v] module m2 interface [v : int] body [v = 33] module m1a interface ((m : [v : int]) => [u : int]) body m1 module m2a interface [v : int] body m2 module m3 interface [u : int] body (m1a m2a) from m3 take u" int 33) (modules-myints-0.1 " module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,-2) pred = proc(x : t) -(x,2) is-zero = proc (x : t) zero?(x) ] let zero = from ints-1 take zero in let succ = from ints-1 take succ in let is-zero = from ints-1 take is-zero in (succ (succ zero))" (from ints-1 take t) 4) (modules-myints-0.20 " module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x) ] let zero = from ints-1 take zero in let succ = from ints-1 take succ in let is-zero = from ints-1 take is-zero in (succ (succ zero))" error -4) (modules-myints-0.2a " module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x) ] let zero = from ints-1 take zero in let succ = from ints-1 take succ in let is-zero = from ints-1 take is-zero in (succ (succ zero))" (from ints-1 take t) -4) (modules-apply-param-module-1 " module makeints interface ((m: [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) => [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) body module-proc (m: [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) [type t = from m take t zero = from m take zero succ = proc (x : t) (from m take succ (from m take succ x)) pred = proc (x : t) (from m take pred (from m take pred x)) is-zero = proc (x : t) (from m take is-zero x) ] module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x)] module ints-2 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body (makeints ints-1) (from ints-2 take succ (from ints-2 take succ from ints-2 take zero)) " (from ints-2 take t) -8) (modules-apply-param-module-3 "module makeints interface ((n : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) => [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) body module-proc (m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) [type t = from m take t zero = from m take zero succ = proc (x : t) (from m take succ (from m take succ x)) pred = proc (x : t) (from m take pred (from m take pred x)) is-zero = proc (x : t) (from m take is-zero x) ] module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x)] module ints-2 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body (makeints ints-1) let zero = from ints-2 take zero in let succ = from ints-2 take succ in let pred = from ints-2 take pred in let is-zero = from ints-2 take is-zero in letrec int to-int (n : from ints-2 take t) = if (is-zero n) then 0 else -( (to-int (pred n)), -1) in (to-int (succ (succ zero))) " int 2) (modules-apply-param-module-4 " module makeints interface ((m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) => [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) body module-proc (m : [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)]) [type t = from m take t zero = from m take zero succ = proc (x : t) (from m take succ (from m take succ x)) pred = proc (x : t) (from m take pred (from m take pred x)) is-zero = proc (x : t) (from m take is-zero x) ] module ints-1 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body [type t = int zero = 0 succ = proc(x : t) -(x,2) pred = proc(x : t) -(x,-2) is-zero = proc (x : t) zero?(x)] module ints-2 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body (makeints ints-1) module int3 interface [opaque t zero : t succ : (t -> t) pred : (t -> t) is-zero : (t -> bool)] body (makeints ints-2) (from int3 take succ (from int3 take succ from int3 take zero)) " (from int3 take t) -16) (lift-type-from-scope-0.01 " module m1 interface [transparent u = int transparent t = int] body [type u = int type t = u] module m2 interface [transparent u = int x : from m1 take t] body [type u = int x = 3] 33" int 33) (lift-type-from-scope-0.1 " module m1 interface [transparent u = int transparent t = u] body [type u = int type t = u] module m2 interface [transparent u = int x : from m1 take t] body [type u = int x = 3] 33" int 33) (lift-type-from-scope-1 " module m1 interface [opaque u transparent t = u] body [type u = bool type t = u] module m2 interface [transparent u = int x : from m1 take t] body [type u = int x = 3] 33" error 33) (lift-type-from-scope-2 " module m1 interface [opaque t1 f : (t1 -> t1)] body [type t1 = bool f = proc (x : t1) x] from m1 take f" ((from m1 take t1) -> (from m1 take t1)) ) (lift-type-from-scope-3 " module m1 interface [opaque t2 f : (t1 -> t1)] body [type t1 = bool f = proc (x : t1) x] from m1 take f" error ; this should die because t1 ; is unbound. ) (modules-14.1 " module m1 interface [transparent t = int z : t] body [type t = int z = 0] module m2 interface [foo : (from m1 take t -> int)] body [foo = proc (x : from m1 take t) x] (from m2 take foo 33)" int) (modules-14 " module m1 interface [transparent t = int z : t] body [type t = int z = 0] module m2 interface [foo : (from m1 take t -> int)] body [foo = proc (x : from m1 take t) x] from m2 take foo" (int -> int)) (modules-14b " module m1 interface [transparent t1 = int] body [type t1 = int] module m2 interface [foo : from m1 take t1] body [foo = 3] from m2 take foo" int) (modules-test-curry1 " module maker1 interface ((m1 : [opaque t s : (t -> t)]) => [transparent t = from m1 take t d : (t -> t)]) body module-proc (m1 : [opaque t s : (t -> t)]) [type t = from m1 take t d = proc (x : t) (from m1 take s (from m1 take s x))] module m0 interface [opaque t s : (t -> t)] body [type t = int s = proc (u : t) -(u, -1)] module m1 interface [opaque t d : (t -> t)] body (maker1 m0) 33" int 33) (modules-test-curry2 " module maker1 interface ((m1 : [opaque t s : (t -> t)]) => ((m2 : [transparent t = from m1 take t]) => [transparent t = from m1 take t d : (t -> t)])) body module-proc (p1 : [opaque t s : (t -> t)]) module-proc (p2 : [transparent t = from p1 take t]) [type t = from p1 take t d = proc (x : t) (from p1 take s (from p1 take s x))] module m0 interface [opaque t s : (t -> t)] body [type t = int s = proc (u : t) -(u, -1)] module m1 interface ((m2 : % [opaque t] [transparent t = from m0 take t]) => [transparent t = from m2 take t d : (t -> t)]) body (maker1 m0) module m2 interface [opaque t d : (t -> t)] body (m1 m0) 33" int 33) ;; I think these require smarter treatment of sharing-- see Leroy POPL 94. ;; (modules-curried-application-0 " ;; module curried-functor ;; interface ;; ((m1 : [opaque t]) ;; => ((m2 : [transparent t = from m1 take t]) ;; => [transparent t = from m1 take t])) ;; body ;; module-proc ;; (m1 : [opaque t]) ;; module-proc ;; (m2 : [transparent t = from m1 take t]) ;; [type t = from m1 take t] ;; module intx ;; interface ;; [opaque t ;; z : t] ;; body ;; [type t = bool ;; z = zero?(1)] ;; module app1 ;; interface ;; ((m2 : [opaque t]) ;; => [transparent t = from m1 take t]) ;; body ;; (curried-functor intx) ;; 33" ;; int 33) ;; (modules-curried-application-1 " ;; module curried-merge ;; interface ;; ((m1 : [opaque t ;; z : t ;; s : (t -> t)]) ;; => ((m2 : [transparent t = from m1 take t ;; d : (t -> t)]) ;; => [transparent t = from m1 take t ;; z : t ;; s : (t -> t) ;; d : (t -> t)])) ;; body ;; module-proc ;; (m1 : [opaque t ;; z : t ;; s : (t -> t)]) ;; module-proc ;; (m2 : [transparent t = from m1 take t ;; d : (t -> t)]) ;; [type t = from m1 take t ;; z = from m1 take z ;; s = from m1 take s ;; d = from m2 take d] ;; module ints-1 ;; interface ;; [opaque t ;; z : t ;; s : (t -> t)] ;; body ;; [type t = int ;; z = 3 ;; s = proc (x : int) -(x, -1)] ;; module double1 ;; interface ;; [transparent t = from ints-1 take t ;; d : (t -> t)] ;; body ;; [type t = from ints-1 take t ;; d = proc (x : t) (from ints-1 take s (from ints-1 take s x))] ;; module curry1 ;; interface ;; ((m2 : [opaque t ;; d : (t -> t)]) ;; => [transparent t = from m2 take t ;; z : t ;; s : (t -> t) ;; d : (t -> t)]) ;; body ;; (curried-merge ints-1) ;; module curry2 ;; interface ;; [opaque t ;; z : t ;; s : (t -> t) ;; d : (t -> t)] ;; body ;; (curry1 double1) ;; (from curry2 take d ;; from curry2 take z) ;; " ;; (from ints-1 take t) 5) ;; Here are some possible tests for named interfaces (Ex. 8.27) ;; (modules-named-interfaces-1 " ;; interface i1 = [u : int v: bool] ;; module m1 ;; interface i1 ;; body [u = 3 v = zero?(0)] ;; import m1 ;; from m1 take u" ;; int) ;; (modules-named-interfaces-2 " ;; interface i1 = [u : int v: bool] ;; module m1 ;; interface i1 ;; body [u = 3 v = zero?(0)] ;; module m2 ;; interface ((m3 : i1) => [u : int]) ;; body ;; module-proc (m4 : i1) [u = from m4 take u] ;; module builder ;; interface [u:int] ;; body ;; import m1 ;; import m2 ;; (m2 m1) ;; import builder ;; from builder take u" ;; int) ;; (modules-named-interfaces-3 " ;; interface i1 = [u : int v: bool] ;; interface i2 = ((m3 : i1) => [u : int]) ;; module m1 ;; interface i1 ;; body [u = 3 v = zero?(0)] ;; module m2 ;; interface i2 ;; body ;; module-proc (m4 : i1) [u = from m4 take u] ;; module builder ;; interface [u:int] ;; body ;; import m1 ;; import m2 ;; (m2 m1) ;; import builder ;; from builder take u" ;; int) )) (define tests-for-run (let loop ((lst the-test-suite)) (cond ((null? lst) '()) ((= (length (car lst)) 4) ;; (printf "creating item: ~s~%" (caar lst)) (cons (list (list-ref (car lst) 0) (list-ref (car lst) 1) (list-ref (car lst) 3)) (loop (cdr lst)))) (else (loop (cdr lst)))))) (define tests-for-parse (let loop ((lst the-test-suite)) (cond ((null? lst) '()) (else ;; (printf "creating item: ~s~%" (caar lst)) (cons (list (list-ref (car lst) 0) (list-ref (car lst) 1) #t) (loop (cdr lst))))))) ;; ok to have extra members in a test-item. (define tests-for-check the-test-suite) )