;; (parse '(1 . (2 . 3)))
;; (parse '((1 . 2) . (1 . 1))))))
(test-equal '(1 . 1)
- (t '() '(lambda x x)))
+ (t '() '(λc x x)))
(test-equal '((3 . 4) . ((2 . 3) . (2 . 4)))
- (t '() '(lambda g (lambda f (lambda x (g (f x)))))))
+ (t '() '(λc g (λc f (λc x (g (f x)))))))
(test-equal 0
- (t '() '((lambda x x) #t)))
+ (t '() '((λc x x) #t)))
(let ((bindings `((id . ,(parse '(1 . 1)))
(∘ . ,(parse '((2 . 3) . ((1 . 2) . (1 . 3)))))
(⊙ . ,(parse '((1 . 2) . ((2 . 3) . (1 . 3)))))
(test-equal 0
(t bindings '((∘ (⊙ (+ 1)) +) 2 3)))
)
+
+;;; interaction between typed and untyped (regular) scheme
+
+;; Untyped scheme produces untyped return.
+(test-assert (not (t '() '(+ 1 2 3))))
+
+(let ((bindings `((* . ,(parse '(0 . (0 . 0)))))))
+ ;; Typed Scheme can be used by untyped Scheme...
+ (test-assert (not (t bindings '(+ 1 (* 2 3) 4))))
+
+ ;; ... although, sometimes, with terrible runtime consequences!
+ (test-assert (not (t bindings '(+ 1 (* 2) 3))))
+
+ ;; On the other hand, typed Scheme expects typed Scheme.
+ (test-error (t bindings '(* 1 (+ 2 3))))
+ )
+
(test-end "curry")
#:use-module (srfi srfi-64)
#:use-module (vdc misc)
#:replace
- ((vdc:define . define)
- (vdc:primitive-eval . primitive-eval))
+ (;(vdc:define . define)
+ ;(vdc:primitive-eval . primitive-eval)
+ )
#:export
(curry
parse
(1 . INCOMPATIBLE)
(2 . BAD-INPUT)
(3 . BAD-APPLICATION)
- (4 . UNBOUND-SYMBOL))))
+ (4 . UNBOUND-SYMBOL)
+ (5 . TYPE-EXPECT-TYPES))))
(apply error "type error" (assoc-ref errors n) args)))
(define (zo? x)
(match expr
(('quote x)
(make-node 0))
- (('lambda (? symbol? var) body)
+ (('λc (? symbol? var) body)
(let ((var-node (make-node #f)))
(let ((nbody (t% (sym-set symtab var var-node)
body)))
+ (unless nbody
+ (type-error 5 "in body of" `(λc ,var ,body)))
(populate-tvs! var-node)
(make-node
(cons var-node nbody)))))
(('letrecc1 ((? symbol? name) expr) body)
(type-error 0 'letrecc1 name expr body))
((f)
- (type-error 3 expr))
+ (if (t% symtab f)
+ (type-error 3 expr)
+ #f))
((f as ..1)
- (fold
- (lambda (a prev)
- (apply-1 prev (t% symtab a)))
- (t% symtab f)
- as))
+ (if-let (ft (t% symtab f))
+ (fold
+ (lambda (a prev)
+ (apply-1 prev (or (t% symtab a) (type-error 5 f a))))
+ ft as)
+ (begin
+ (for-each
+ (lambda (a)
+ (t% symtab a))
+ as)
+ #f)))
(x
(if (symbol? x)
- (or (sym-ref symtab x)
- (type-error 4 x))
+ (sym-ref symtab x)
(make-node 0)))))
-(define (bare-t node)
- (let ((x (node-content node)))
- (cond
- ((pair? x)
- (cons (bare-t (car x)) (bare-t (cdr x))))
- (else x))))
+(define (bare-t x)
+ (and=>
+ x
+ (lambda (node)
+ (let ((x (node-content node)))
+ (cond
+ ((pair? x)
+ (cons (bare-t (car x)) (bare-t (cdr x))))
+ (else x))))))
(define (pt node)
(format
(define (curry x)
(match x
(('quote x) (quote x))
- (('lambda (? symbol? var) body)
+ (('λc (? symbol? var) body)
`(lambda (,var) ,(curry body)))
;; (('letrecc1 ((? symbol? name) expr) body)
;; `(letrecc1 (,name ,(curry expr)) ,(curry body)))