extended or/c to support multiple higher-order contracts

svn: r3606
This commit is contained in:
Robby Findler 2006-07-06 02:08:12 +00:00
parent 8fa40a972a
commit 79ae279b79
7 changed files with 778 additions and 286 deletions

View File

@ -9,5 +9,7 @@
(all-from "private/contract-ds.ss")
(all-from "private/contract-arrow.ss")
(all-from-except "private/contract-guts.ss"
build-compound-type-name)
build-compound-type-name
first-order-prop
first-order-get)
(all-from "private/contract.ss")))

View File

@ -32,10 +32,10 @@
(raise-syntax-error 'any "Use any out of an arrow contract" stx))
;; FIXME: need to pass in the name of the contract combinator.
(define (build--> doms doms-rest rngs rng-any? func)
(let ([doms/c (map (λ (dom) (coerce-contract -> dom)) doms)]
[rngs/c (map (λ (rng) (coerce-contract -> rng)) rngs)]
[doms-rest/c (and doms-rest (coerce-contract -> doms-rest))])
(define (build--> name doms doms-rest rngs rng-any? func)
(let ([doms/c (map (λ (dom) (coerce-contract name dom)) doms)]
[rngs/c (map (λ (rng) (coerce-contract name rng)) rngs)]
[doms-rest/c (and doms-rest (coerce-contract name doms-rest))])
(make--> rng-any? doms/c doms-rest/c rngs/c func)))
(define-struct/prop -> (rng-any? doms dom-rest rngs func)
@ -79,6 +79,16 @@
(->-dom-rest ctc)
(->-rng-any? ctc)
(->-rngs ctc))))
(first-order-prop
(λ (ctc)
(let ([l (length (->-doms ctc))])
(if (->-dom-rest ctc)
(λ (x)
(and (procedure? x)
(procedure-accepts-and-more? x l)))
(λ (x)
(and (procedure? x)
(procedure-arity-includes? x l)))))))
(stronger-prop
(λ (this that)
(and (->? that)
@ -137,7 +147,8 @@
(chk val)
inner-lambda)))])
(values
(syntax (build--> (list dom-ctcs ...)
(syntax (build--> '->
(list dom-ctcs ...)
#f
(list rng-ctcs ...)
use-any?
@ -213,7 +224,8 @@
(lambda (val)
(chk val)
inner-lambda)))])
(values (syntax (build--> (list doms ...)
(values (syntax (build--> '->*
(list doms ...)
rst
(list rngs ...)
#f
@ -238,7 +250,8 @@
(lambda (val)
(chk val)
inner-lambda)))])
(values (syntax (build--> (list doms ...)
(values (syntax (build--> '->*
(list doms ...)
rst
(list any/c)
#t
@ -246,6 +259,9 @@
inner-args/body
(syntax (dom-x ... rst-x)))))))])))
(define empty-case-lambda/c
(flat-named-contract '(case->)
(λ (x) (and (procedure? x) (null? (procedure-arity x))))))
(define-syntax-set (->/real ->*/real ->d ->d* ->r ->pp ->pp-rest case-> object-contract opt-> opt->*)
@ -278,7 +294,10 @@
;; syntax
;; -> (syntax -> syntax)
(define (make-/proc method-proc? /h stx)
(let-values ([(arguments-check build-pos-proj build-neg-proj check-val pos-wrapper neg-wrapper) (/h method-proc? stx)])
(let-values ([(arguments-check build-pos-proj build-neg-proj
check-val first-order-check
pos-wrapper neg-wrapper)
(/h method-proc? stx)])
(let ([outer-args (syntax (val blame src-info orig-str name-id))])
(with-syntax ([inner-check (check-val outer-args)]
[(val blame src-info orig-str name-id) outer-args]
@ -302,7 +321,8 @@
(lambda (val)
inner-neg-lambda))])
(with-syntax ([pos-proj-code (build-pos-proj outer-args inner-pos-lambda-w/err-check)]
[neg-proj-code (build-neg-proj outer-args inner-neg-lambda)])
[neg-proj-code (build-neg-proj outer-args inner-neg-lambda)]
[first-order-check first-order-check])
(arguments-check
outer-args
(syntax/loc stx
@ -311,16 +331,22 @@
(lambda (blame src-info orig-str)
pos-proj-code)
(lambda (blame src-info orig-str)
neg-proj-code)))))))))))
neg-proj-code)
first-order-check))))))))))
(define (make-case->/proc method-proc? stx inferred-name-stx)
(syntax-case stx ()
;; if there are no cases, this contract should only accept the "empty" case-lambda.
[(_) (syntax empty-case-lambda/c)]
;; if there is only a single case, just skip it.
[(_ case) (syntax case)]
[(_ cases ...)
(let-values ([(arguments-check build-pos-projs build-neg-projs check-val pos-wrapper neg-wrapper)
(let-values ([(arguments-check build-pos-projs build-neg-projs
check-val first-order-check
pos-wrapper neg-wrapper)
(case->/h method-proc? stx (syntax->list (syntax (cases ...))))])
(let ([outer-args (syntax (val blame src-info orig-str name-id))])
(with-syntax ([(inner-check ...) (check-val outer-args)]
@ -342,7 +368,8 @@
inner-pos-lambda))]
[inner-neg-lambda (syntax (lambda (val) inner-neg-lambda))])
(with-syntax ([pos-proj-code (build-pos-projs outer-args inner-pos-lambda-w/err-check)]
[neg-proj-code (build-neg-projs outer-args inner-neg-lambda)])
[neg-proj-code (build-neg-projs outer-args inner-neg-lambda)]
[first-order-check first-order-check])
(arguments-check
outer-args
(syntax/loc stx
@ -351,7 +378,8 @@
(lambda (blame src-info orig-str)
pos-proj-code)
(lambda (blame src-info orig-str)
neg-proj-code))))))))))]))
neg-proj-code)
first-order-check)))))))))]))
(define (make-opt->/proc method-proc? stx)
(syntax-case stx (any)
@ -506,14 +534,19 @@
(lambda (x y) y)
(lambda (x y) y)
(lambda (args) (syntax ()))
(syntax (lambda (x) #t))
(lambda (args) (syntax ()))
(lambda (args) (syntax ())))]
[else
(let ([/h (select/h (car cases) 'case-> orig-stx)]
[new-id (car (generate-temporaries (syntax (case->name-id))))])
(let-values ([(arguments-checks build-pos-projs build-neg-projs check-vals pos-wrappers neg-wrappers)
(let-values ([(arguments-checks build-pos-projs build-neg-projs
check-vals first-order-checks
pos-wrappers neg-wrappers)
(loop (cdr cases) (cons new-id name-ids))]
[(arguments-check build-pos-proj build-neg-proj check-val pos-wrapper neg-wrapper)
[(arguments-check build-pos-proj build-neg-proj
check-val first-order-check
pos-wrapper neg-wrapper)
(/h method-proc? (car cases))])
(values
(lambda (outer-args x)
@ -530,6 +563,9 @@
(with-syntax ([checks (check-vals args)]
[check (check-val args)])
(syntax (check . checks))))
(with-syntax ([checks first-order-checks]
[check first-order-check])
(syntax (lambda (x) (and (checks x) (check x)))))
(lambda (args)
(with-syntax ([case (pos-wrapper args)]
[cases (pos-wrappers args)])
@ -820,7 +856,7 @@
(syntax
(let ([method-ctc-var method-ctc-stx]
...
[field-ctc-var (coerce-contract object-contract field-ctc-stx)]
[field-ctc-var (coerce-contract 'object-contract field-ctc-stx)]
...)
(let ([method-pos-var (contract-pos-proc method-ctc-var)]
...
@ -877,7 +913,8 @@
val
(method/app-var (vector-ref vtable (hash-table-get method-ht 'method-name))) ...
(field/app-var (get-field field-name val)) ...
)))))))))))))]))
))))))
#f)))))))]))
;; ensure-no-duplicates : syntax (listof syntax[identifier]) -> void
(define (ensure-no-duplicates stx form-name names)
@ -933,6 +970,9 @@
;; - [check-val]
;; code that does error checking on the contract'd value itself
;; (is it a function of the right arity?)
;; - [first-order-check]
;; predicate function that does the first order check and returns a boolean
;; (is it a function of the right arity?)
;; - [pos-wrapper]
;; a piece of syntax that has the arguments to the wrapper
;; and the body of the wrapper.
@ -982,7 +1022,7 @@
(with-syntax ([body body]
[(val blame src-info orig-str name-id) outer-args])
(syntax
(let ([dom-contract-x (coerce-contract -> dom)] ...)
(let ([dom-contract-x (coerce-contract '-> dom)] ...)
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)] ...)
@ -1009,7 +1049,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure val dom-length src-info blame orig-str))))
(syntax (check-procedure? dom-length))
wrap
wrap))]
[(values rng ...)
@ -1034,9 +1074,9 @@
(with-syntax ([body body]
[(val blame src-info orig-str name-id) outer-args])
(syntax
(let ([dom-contract-x (coerce-contract -> dom)]
(let ([dom-contract-x (coerce-contract '-> dom)]
...
[rng-contract-x (coerce-contract -> rng)] ...)
[rng-contract-x (coerce-contract '-> rng)] ...)
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)]
@ -1075,7 +1115,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure val dom-length src-info blame orig-str))))
(syntax (check-procedure? dom-length))
wrap
wrap)))]
[rng
@ -1097,9 +1137,9 @@
(with-syntax ([body body]
[(val blame src-info orig-str name-id) outer-args])
(syntax
(let ([dom-contract-x (coerce-contract -> dom)]
(let ([dom-contract-x (coerce-contract '-> dom)]
...
[rng-contract-x (coerce-contract -> rng)])
[rng-contract-x (coerce-contract '-> rng)])
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)]
@ -1133,7 +1173,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure val dom-length src-info blame orig-str))))
(syntax (check-procedure? dom-length))
wrap
wrap)))])))]))
@ -1188,9 +1228,10 @@
(syntax (dom-contract-x ...))))
(syntax (dom-contract-x ...)))])
(syntax
(let ([dom-contract-x (coerce-contract ->* dom)] ...
[dom-rest-contract-x (coerce-contract ->* rest)]
[rng-contract-x (coerce-contract ->* rng)] ...)
(let ([dom-contract-x (coerce-contract '->* dom)]
...
[dom-rest-contract-x (coerce-contract '->* rest)]
[rng-contract-x (coerce-contract '->* rng)] ...)
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)]
@ -1234,7 +1275,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure/more val dom-length src-info blame orig-str))))
(syntax (check-procedure/more? dom-length))
wrap
wrap)))]
[(_ (dom ...) rest any)
@ -1273,9 +1314,9 @@
(syntax (dom-contract-x ...))))
(syntax (dom-contract-x ...)))])
(syntax
(let ([dom-contract-x (coerce-contract ->* dom)]
(let ([dom-contract-x (coerce-contract '->* dom)]
...
[dom-rest-contract-x (coerce-contract ->* rest)])
[dom-rest-contract-x (coerce-contract '->* rest)])
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)]
@ -1312,6 +1353,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure/more val dom-length src-info blame orig-str))))
(syntax (check-procedure/more? dom-length))
wrap
wrap)))]))
@ -1338,7 +1380,7 @@
(syntax (dom-contract-x ...))))
(syntax (dom-contract-x ...)))])
(syntax
(let ([dom-contract-x (coerce-contract ->d dom)] ...)
(let ([dom-contract-x (coerce-contract '->d dom)] ...)
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)] ...
@ -1368,6 +1410,8 @@
(syntax
(check-procedure val arity src-info blame orig-str))))
(syntax (check-procedure? arity))
;; pos
(lambda (outer-args)
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
@ -1375,7 +1419,7 @@
((arg-x ...)
(let ([arg-x (dom-projection-x arg-x)] ...)
(let ([rng-contract (rng-x arg-x ...)])
(((contract-pos-proc (coerce-contract ->d rng-contract))
(((contract-pos-proc (coerce-contract '->d rng-contract))
blame
src-info
orig-str)
@ -1388,7 +1432,7 @@
((arg-x ...)
(let ([arg-x (dom-projection-x arg-x)] ...)
(let ([rng-contract (rng-x arg-x ...)])
(((contract-neg-proc (coerce-contract ->d rng-contract))
(((contract-neg-proc (coerce-contract '->d rng-contract))
blame
src-info
orig-str)
@ -1423,7 +1467,7 @@
(apply
values
(map (lambda (rng-contract result)
(((extract-proc (coerce-contract ->d* rng-contract))
(((extract-proc (coerce-contract '->d* rng-contract))
blame
src-info
orig-str)
@ -1441,7 +1485,7 @@
(syntax (dom-contract-x ...))))
(syntax (dom-contract-x ...)))])
(syntax
(let ([dom-contract-x (coerce-contract ->d* dom)] ...)
(let ([dom-contract-x (coerce-contract '->d* dom)] ...)
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)] ...
@ -1473,7 +1517,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure val dom-length src-info blame orig-str))))
(syntax (check-procedure? dom-length))
(mk-wrap (syntax contract-pos-proc))
(mk-wrap (syntax contract-neg-proc)))))]
[(_ (dom ...) rest rng-mk)
@ -1510,7 +1554,7 @@
(apply
values
(map (lambda (rng-contract result)
(((extract-proj (coerce-contract ->d* rng-contract))
(((extract-proj (coerce-contract '->d* rng-contract))
blame
src-info
orig-str)
@ -1528,9 +1572,9 @@
(syntax (dom-contract-x ...))))
(syntax (dom-contract-x ...)))])
(syntax
(let ([dom-contract-x (coerce-contract ->d* dom)]
(let ([dom-contract-x (coerce-contract '->d* dom)]
...
[dom-rest-contract-x (coerce-contract ->d* rest)])
[dom-rest-contract-x (coerce-contract '->d* rest)])
(let ([dom-pos-x (contract-pos-proc dom-contract-x)]
...
[dom-neg-x (contract-neg-proc dom-contract-x)] ...
@ -1569,6 +1613,7 @@
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
(syntax
(check-procedure/more val arity src-info blame orig-str))))
(syntax (check-procedure/more? arity))
(mk-wrap (syntax contract-pos-proc))
(mk-wrap (syntax contract-neg-proc)))))]))
@ -1633,6 +1678,9 @@
(syntax
(begin
(check-procedure/kind val arity 'kind-of-thing src-info blame orig-str)))))
(syntax (check-procedure? arity))
;; pos
(lambda (outer-args)
(with-syntax ([(val blame src-info orig-str name-id) outer-args])
@ -1640,7 +1688,7 @@
[(any)
(syntax
((x ...)
(let ([dom-id ((contract-neg-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-neg-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...)
(val (dom-id x) ...))))]
[((values (rng-ids rng-ctc) ...) post-expr)
@ -1650,11 +1698,11 @@
(syntax
((x ...)
(begin
(let ([dom-id ((contract-neg-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-neg-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...)
(let-values ([(rng-ids ...) (val (dom-id x) ...)])
(check-post-expr->pp/h val post-expr src-info blame orig-str)
(let ([rng-ids-x ((contract-pos-proc (coerce-contract stx-name rng-ctc))
(let ([rng-ids-x ((contract-pos-proc (coerce-contract 'stx-name rng-ctc))
blame src-info orig-str)] ...)
(values (rng-ids-x rng-ids) ...))))))))]
[((values (rng-ids rng-ctc) ...) post-expr)
@ -1671,9 +1719,9 @@
[(rng res-id post-expr)
(syntax
((x ...)
(let ([dom-id ((contract-neg-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-neg-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rng-id ((contract-pos-proc (coerce-contract stx-name rng)) blame src-info orig-str)])
[rng-id ((contract-pos-proc (coerce-contract 'stx-name rng)) blame src-info orig-str)])
(let ([res-id (rng-id (val (dom-id x) ...))])
(check-post-expr->pp/h val post-expr src-info blame orig-str)
res-id))))]
@ -1689,7 +1737,7 @@
((x ...)
(begin
(check-pre-expr->pp/h val pre-expr src-info blame orig-str)
(let ([dom-id ((contract-pos-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-pos-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...)
(val (dom-id x) ...)))))]
[((values (rng-ids rng-ctc) ...) post-expr)
@ -1700,10 +1748,10 @@
((x ...)
(begin
(check-pre-expr->pp/h val pre-expr src-info blame orig-str)
(let ([dom-id ((contract-pos-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-pos-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...)
(let-values ([(rng-ids ...) (val (dom-id x) ...)])
(let ([rng-ids-x ((contract-neg-proc (coerce-contract stx-name rng-ctc))
(let ([rng-ids-x ((contract-neg-proc (coerce-contract 'stx-name rng-ctc))
blame src-info orig-str)] ...)
(values (rng-ids-x rng-ids) ...))))))))]
[((values (rng-ids rng-ctc) ...) post-expr)
@ -1722,9 +1770,9 @@
((x ...)
(begin
(check-pre-expr->pp/h val pre-expr src-info blame orig-str)
(let ([dom-id ((contract-pos-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-pos-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rng-id ((contract-neg-proc (coerce-contract stx-name rng)) blame src-info orig-str)])
[rng-id ((contract-neg-proc (coerce-contract 'stx-name rng)) blame src-info orig-str)])
(rng-id (val (dom-id x) ...))))))]
[_
(raise-syntax-error name "unknown result specification" stx (syntax result-stuff))]))))))]
@ -1785,6 +1833,7 @@
(syntax
(begin
(check-procedure/more/kind val arity 'kind-of-thing src-info blame orig-str)))))
(syntax (check-procedure/more? arity))
;; pos
(lambda (outer-args)
@ -1793,9 +1842,9 @@
[(any)
(syntax
((x ... . rest-x)
(let ([dom-id ((contract-neg-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-neg-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rest-id ((contract-neg-proc (coerce-contract stx-name rest-dom)) blame src-info orig-str)])
[rest-id ((contract-neg-proc (coerce-contract 'stx-name rest-dom)) blame src-info orig-str)])
(apply val (dom-id x) ... (rest-id rest-x)))))]
[(any . x)
(raise-syntax-error name "cannot have anything after any" stx (syntax result-stuff))]
@ -1805,12 +1854,12 @@
(with-syntax ([(rng-ids-x ...) (generate-temporaries (syntax (rng-ids ...)))])
(syntax
((x ... . rest-x)
(let ([dom-id ((contract-neg-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-neg-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rest-id ((contract-neg-proc (coerce-contract stx-name rest-dom)) blame src-info orig-str)])
[rest-id ((contract-neg-proc (coerce-contract 'stx-name rest-dom)) blame src-info orig-str)])
(let-values ([(rng-ids ...) (apply val (dom-id x) ... (rest-id rest-x))])
(check-post-expr->pp/h val post-expr src-info blame orig-str)
(let ([rng-ids-x ((contract-pos-proc (coerce-contract stx-name rng-ctc))
(let ([rng-ids-x ((contract-pos-proc (coerce-contract 'stx-name rng-ctc))
blame src-info orig-str)] ...)
(values (rng-ids-x rng-ids) ...)))))))]
[((values (rng-ids rng-ctc) ...) . whatever)
@ -1832,10 +1881,10 @@
(identifier? (syntax res-id))
(syntax
((x ... . rest-x)
(let ([dom-id ((contract-neg-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-neg-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rest-id ((contract-neg-proc (coerce-contract stx-name rest-dom)) blame src-info orig-str)]
[rng-id ((contract-pos-proc (coerce-contract stx-name rng)) blame src-info orig-str)])
[rest-id ((contract-neg-proc (coerce-contract 'stx-name rest-dom)) blame src-info orig-str)]
[rng-id ((contract-pos-proc (coerce-contract 'stx-name rng)) blame src-info orig-str)])
(let ([res-id (rng-id (apply val (dom-id x) ... (rest-id rest-x)))])
(check-post-expr->pp/h val post-expr src-info blame orig-str)
res-id))))]
@ -1854,9 +1903,9 @@
((x ... . rest-x)
(begin
(check-pre-expr->pp/h val pre-expr src-info blame orig-str)
(let ([dom-id ((contract-pos-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-pos-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rest-id ((contract-pos-proc (coerce-contract stx-name rest-dom)) blame src-info orig-str)])
[rest-id ((contract-pos-proc (coerce-contract 'stx-name rest-dom)) blame src-info orig-str)])
(apply val (dom-id x) ... (rest-id rest-x))))))]
[(any . x)
(raise-syntax-error name "cannot have anything after any" stx (syntax result-stuff))]
@ -1868,11 +1917,11 @@
((x ... . rest-x)
(begin
(check-pre-expr->pp/h val pre-expr src-info blame orig-str)
(let ([dom-id ((contract-pos-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-pos-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rest-id ((contract-pos-proc (coerce-contract stx-name rest-dom)) blame src-info orig-str)])
[rest-id ((contract-pos-proc (coerce-contract 'stx-name rest-dom)) blame src-info orig-str)])
(let-values ([(rng-ids ...) (apply val (dom-id x) ... (rest-id rest-x))])
(let ([rng-ids-x ((contract-neg-proc (coerce-contract stx-name rng-ctc))
(let ([rng-ids-x ((contract-neg-proc (coerce-contract 'stx-name rng-ctc))
blame src-info orig-str)] ...)
(values (rng-ids-x rng-ids) ...))))))))]
[((values (rng-ids rng-ctc) ...) . whatever)
@ -1896,10 +1945,10 @@
((x ... . rest-x)
(begin
(check-pre-expr->pp/h val pre-expr src-info blame orig-str)
(let ([dom-id ((contract-pos-proc (coerce-contract stx-name dom)) blame src-info orig-str)]
(let ([dom-id ((contract-pos-proc (coerce-contract 'stx-name dom)) blame src-info orig-str)]
...
[rest-id ((contract-pos-proc (coerce-contract stx-name rest-dom)) blame src-info orig-str)]
[rng-id ((contract-neg-proc (coerce-contract stx-name rng)) blame src-info orig-str)])
[rest-id ((contract-pos-proc (coerce-contract 'stx-name rest-dom)) blame src-info orig-str)]
[rng-id ((contract-neg-proc (coerce-contract 'stx-name rng)) blame src-info orig-str)])
(rng-id (apply val (dom-id x) ... (rest-id rest-x)))))))]
[(rng res-id post-expr)
(not (identifier? (syntax res-id)))
@ -2055,6 +2104,14 @@
dom-length
val)))
(define ((check-procedure? arity) val)
(and (procedure? val)
(procedure-arity-includes? val arity)))
(define ((check-procedure/more? arity) val)
(and (procedure? val)
(procedure-accepts-and-more? val arity)))
(define (check-procedure/kind val arity kind-of-thing src-info blame orig-str)
(unless (procedure? val)
(raise-contract-error val

View File

@ -67,7 +67,7 @@ which are then called when the contract's fields are explored
(syntax (x ...))
field-names)
#,(defeat-inlining
#`(#,coerce-contract #,name ctc-exp)))])
#`(#,coerce-contract '#,name ctc-exp)))])
(loop (cdr clauses)
(cdr ac-ids)
(cons (car ac-ids) prior-ac-ids)
@ -84,7 +84,7 @@ which are then called when the contract's fields are explored
(loop (cdr clauses)
(cdr ac-ids)
(cons (car ac-ids) prior-ac-ids)
(cons #`(#,coerce-contract #,name ctc-exp) maker-args))]
(cons #`(#,coerce-contract '#,name ctc-exp) maker-args))]
[(id ctc-exp)
(raise-syntax-error name "expected identifier" stx (syntax id))]))]))))

View File

@ -193,7 +193,7 @@ it around flattened out.
#f]))
(define (struct/c ctc-x ...)
(let ([ctc-x (coerce-contract struct/c ctc-x)] ...)
(let ([ctc-x (coerce-contract 'struct/c ctc-x)] ...)
(contract-maker ctc-x ...)))
(define (selectors x) (burrow-in x 'selectors selector-indicies)) ...
@ -233,6 +233,7 @@ it around flattened out.
(list (cons pos-proj-prop lazy-contract-pos-proj)
(cons neg-proj-prop lazy-contract-neg-proj)
(cons name-prop lazy-contract-name)
(cons first-order-prop (λ (ctc) predicate))
(cons stronger-prop stronger-lazy-contract?)))))))]))
(define-struct contract/info (contract pos neg src-info orig-str))

View File

@ -8,7 +8,6 @@
(provide raise-contract-error
contract-violation->string
coerce-contract
coerce/select-contract
flat-contract/predicate?
flat-contract?
@ -20,6 +19,8 @@
and/c
any/c
none/c
make-none/c
contract?
contract-name
@ -33,6 +34,8 @@
contract-stronger?
contract-first-order-passes?
proj-pred? proj-get
pos-proj-prop pos-proj-pred? pos-proj-get
neg-proj-prop neg-proj-pred? neg-proj-get
@ -40,7 +43,10 @@
stronger-prop stronger-pred? stronger-get
flat-prop flat-pred? flat-get
any-curried-proj
flat-pos-proj)
flat-pos-proj
first-order-prop
first-order-get)
;; define-struct/prop is a define-struct-like macro that
@ -95,11 +101,25 @@
(define-values (flat-prop flat-pred? flat-get)
(make-struct-type-property 'contract-flat))
(define-values (first-order-prop first-order-pred? first-order-get)
(make-struct-type-property 'contract-first-order))
(define-values (pos-proj-prop pos-proj-pred? pos-proj-get)
(make-struct-type-property 'contract-positive-projection))
(define-values (neg-proj-prop neg-proj-pred? neg-proj-get)
(make-struct-type-property 'contract-negative-projection))
(define (contract-first-order-passes? c v)
(cond
[(first-order-pred? c) (((first-order-get c) c) v)]
[(and (procedure? c)
(procedure-arity-includes? c 1))
;; flat contract as a predicate
(c v)]
[(flat-pred? c) (((flat-get c) c) v)]
[else (error 'contract-first-order-passes?
"expected a contract as first argument, got ~e, other arg ~e" c v)]))
(define (proj-get ctc)
(cond
[(proj-pred? ctc)
@ -120,40 +140,16 @@
;; indicates if one contract is stronger (ie, likes fewer values) than another
;; this is not a total order.
(define (contract-stronger? a b)
(let ([a-ctc (coerce-contract contract-stronger? a)]
[b-ctc (coerce-contract contract-stronger? b)])
(let ([a-ctc (coerce-contract 'contract-stronger? a)]
[b-ctc (coerce-contract 'contract-stronger? b)])
((stronger-get a-ctc) a-ctc b-ctc)))
;; coerce/select-contract : id (union contract? procedure-arity-1) -> contract-proc
;; contract-proc = sym sym stx -> alpha -> alpha
;; returns the procedure for the contract after extracting it from the
;; struct. Coerces the argument to a flat contract if it is procedure, but first.
(define-syntax (coerce/select-contract stx)
(syntax-case stx ()
[(_ name val)
(syntax (coerce/select-contract/proc 'name val))]))
(define (coerce/select-contract/proc name x)
(cond
[(contract? x)
(contract-proc x)]
[(and (procedure? x) (procedure-arity-includes? x 1))
(contract-proc (flat-contract x))]
[else
(error name
"expected contract or procedure of arity 1, got ~e"
x)]))
;; coerce-contract : id (union contract? procedure-arity-1) -> contract
;; contract-proc = sym sym stx -> alpha -> alpha
;; returns the procedure for the contract after extracting it from the
;; struct. Coerces the argument to a flat contract if it is procedure, but first.
(define-syntax (coerce-contract stx)
(syntax-case stx ()
[(_ name val)
(syntax (coerce-contract/proc 'name val))]))
(define (coerce-contract/proc name x)
(define (coerce-contract name x)
(cond
[(contract? x) x]
[(and (procedure? x) (procedure-arity-includes? x 1))
@ -307,10 +303,12 @@
(define-values (make-flat-contract
make-pair-proj-contract)
(let ()
(define-struct/prop pair-proj-contract (the-name pos-proc neg-proc)
(define-struct/prop pair-proj-contract (the-name pos-proc neg-proc first-order-proc)
((pos-proj-prop (λ (ctc) (pair-proj-contract-pos-proc ctc)))
(neg-proj-prop (λ (ctc) (pair-proj-contract-neg-proc ctc)))
(name-prop (λ (ctc) (pair-proj-contract-the-name ctc)))
(first-order-prop (λ (ctc) (or (pair-proj-contract-first-order-proc ctc)
(λ (x) #t))))
(stronger-prop (λ (this that)
(and (pair-proj-contract? that)
(procedure-closure-contents-eq?
@ -376,6 +374,37 @@
`(,mk-sub-name ,@(loop (cdr subs))))]
[else `(,sub ,@(loop (cdr subs)))]))])))
(define (make-and-proj proj-get)
(λ (ctc)
(let ([mk-pos-projs (map (λ (x) ((proj-get x) x)) (and/c-ctcs ctc))])
(lambda (pos src-info orig-str)
(let ([projs (map (λ (c) (c pos src-info orig-str)) mk-pos-projs)])
(let loop ([projs (cdr projs)]
[proj (car projs)])
(cond
[(null? projs) proj]
[else (loop (cdr projs)
(let ([f (car projs)])
(λ (v) (proj (f v)))))])))))))
(define-struct/prop and/c (ctcs)
((pos-proj-prop (make-and-proj pos-proj-get))
(neg-proj-prop (make-and-proj neg-proj-get))
(name-prop (λ (ctc) (apply build-compound-type-name 'and/c (and/c-ctcs ctc))))
(first-order-prop (λ (ctc)
(let ([tests (map (λ (x) ((first-order-get x) x)) (and/c-ctcs ctc))])
(λ (x)
(andmap (λ (f) (f x)) tests)))))
(stronger-prop
(λ (this that)
(and (and/c? that)
(let ([this-ctcs (and/c-ctcs this)]
[that-ctcs (and/c-ctcs that)])
(and (= (length this-ctcs) (length that-ctcs))
(andmap contract-stronger?
this-ctcs
that-ctcs))))))))
(define (and/c . fs)
(for-each
(lambda (x)
@ -405,43 +434,41 @@
(cdr preds)))]))])
(flat-named-contract (apply build-compound-type-name 'and/c contracts) pred))]
[else
(let* ([contracts (map (lambda (x) (if (contract? x) x (flat-contract x))) fs)]
[pos-contract/procs (map contract-pos-proc contracts)]
[neg-contract/procs (map contract-neg-proc contracts)])
(make-pair-proj-contract
(apply build-compound-type-name 'and/c contracts)
(lambda (blame src-info orig-str)
(let ([partial-contracts (map (lambda (contract/proc) (contract/proc blame src-info orig-str))
pos-contract/procs)])
(let loop ([ctct (car partial-contracts)]
[rest (cdr partial-contracts)])
(cond
[(null? rest) ctct]
[else
(let ([fst (car rest)])
(loop (lambda (x) (fst (ctct x)))
(cdr rest)))]))))
(lambda (blame src-info orig-str)
(let ([partial-contracts (map (lambda (contract/proc) (contract/proc blame src-info orig-str))
neg-contract/procs)])
(let loop ([ctct (car partial-contracts)]
[rest (cdr partial-contracts)])
(cond
[(null? rest) ctct]
[else
(let ([fst (car rest)])
(loop (lambda (x) (fst (ctct x)))
(cdr rest)))]))))))]))
(let ([contracts (map (lambda (x) (if (contract? x) x (flat-contract x))) fs)])
(make-and/c contracts))]))
(define-struct/prop any/c ()
((pos-proj-prop any-curried-proj)
(neg-proj-prop any-curried-proj)
(stronger-prop (λ (this that) (any/c? that)))
(name-prop (λ (ctc) 'any/c))
(first-order-prop (λ (ctc) (λ (val) #t)))
(flat-prop (λ (ctc) (λ (x) #t)))))
(define any/c (make-any/c))
(define (none-curried-proj ctc)
(λ (pos src-info orig-str)
(λ (val)
(raise-contract-error
val
src-info
pos
orig-str
"~s accepts no values, given: ~e"
(none/c-name ctc)
val))))
(define-struct/prop none/c (name)
((pos-proj-prop none-curried-proj)
(neg-proj-prop none-curried-proj)
(stronger-prop (λ (this that) #t))
(name-prop (λ (ctc) (none/c-name ctc)))
(first-order-prop (λ (ctc) (λ (val) #f)))
(flat-prop (λ (ctc) (λ (x) #f)))))
(define none/c (make-none/c 'none/c))
(define (flat-contract/predicate? pred)
(or (flat-contract? pred)
(and (procedure? pred)

View File

@ -53,7 +53,7 @@ add struct contracts for immutable structs?
(define-for-syntax (make-define/contract-transformer contract-id id)
(make-set!-transformer
(lambda (stx)
(λ (stx)
(with-syntax ([neg-blame-str (or (a:build-src-loc-string stx) "")]
[contract-id contract-id]
[id id])
@ -83,7 +83,7 @@ add struct contracts for immutable structs?
(define-for-syntax (make-provide/contract-transformer contract-id id pos-module-source)
(make-set!-transformer
(lambda (stx)
(λ (stx)
(with-syntax ([neg-stx (datum->syntax-object stx 'here)]
[contract-id contract-id]
[id id]
@ -215,7 +215,7 @@ add struct contracts for immutable structs?
provide-stx
(syntax name))]
[(struct name (fields ...))
(for-each (lambda (field)
(for-each (λ (field)
(syntax-case field ()
[(x y)
(identifier? (syntax x))
@ -291,7 +291,7 @@ add struct contracts for immutable structs?
provide-stx
struct-name)]
[else (length fields)]))))]
[field-contract-ids (map (lambda (field-name)
[field-contract-ids (map (λ (field-name)
(a:mangle-id provide-stx
"provide/contract-field-contract"
field-name
@ -305,7 +305,13 @@ add struct contracts for immutable structs?
"struct:"
(symbol->string (syntax-e struct-name)))))]
[-struct:struct-name
(datum->syntax-object
struct-name
(string->symbol
(string-append
"-struct:"
(symbol->string (syntax-e struct-name)))))]
[is-new-id?
(λ (index)
@ -313,14 +319,14 @@ add struct contracts for immutable structs?
(parent-struct-count . <= . index)))])
(let ([unknown-info
(lambda (what names)
(λ (what names)
(raise-syntax-error
'provide/contract
(format "cannot determine ~a, found ~s" what names)
provide-stx
struct-name))]
[is-id-ok?
(lambda (id i)
(λ (id i)
(if (or (not parent-struct-count)
(parent-struct-count . <= . i))
id
@ -330,13 +336,13 @@ add struct contracts for immutable structs?
(unless predicate-id (unknown-info "predicate" predicate-id))
(unless (andmap/count is-id-ok? selector-ids)
(unknown-info "selectors"
(map (lambda (x) (if (syntax? x)
(map (λ (x) (if (syntax? x)
(syntax-object->datum x)
x))
selector-ids)))
(unless (andmap/count is-id-ok? mutator-ids)
(unknown-info "mutators"
(map (lambda (x) (if (syntax? x)
(map (λ (x) (if (syntax? x)
(syntax-object->datum x)
x))
mutator-ids))))
@ -360,8 +366,8 @@ add struct contracts for immutable structs?
(with-syntax ([((selector-codes selector-new-names) ...)
(filter
(lambda (x) x)
(map/count (lambda (selector-id field-contract-id index)
(λ (x) x)
(map/count (λ (selector-id field-contract-id index)
(if (is-new-id? index)
(code-for-one-id/new-name
stx
@ -376,16 +382,16 @@ add struct contracts for immutable structs?
[(rev-selector-old-names ...)
(reverse
(filter
(lambda (x) x)
(map/count (lambda (selector-id index)
(λ (x) x)
(map/count (λ (selector-id index)
(if (not (is-new-id? index))
selector-id
#f))
selector-ids)))]
[((mutator-codes mutator-new-names) ...)
(filter
(lambda (x) x)
(map/count (lambda (mutator-id field-contract-id index)
(λ (x) x)
(map/count (λ (mutator-id field-contract-id index)
(if (is-new-id? index)
(code-for-one-id/new-name stx
mutator-id
@ -399,8 +405,8 @@ add struct contracts for immutable structs?
[(rev-mutator-old-names ...)
(reverse
(filter
(lambda (x) x)
(map/count (lambda (mutator-id index)
(λ (x) x)
(map/count (λ (mutator-id index)
(if (not (is-new-id? index))
mutator-id
#f))
@ -424,7 +430,7 @@ add struct contracts for immutable structs?
"provide/contract-struct-expandsion-info-id"
struct-name)]
[struct-name struct-name]
[struct:struct-name struct:struct-name]
[-struct:struct-name -struct:struct-name]
[super-id (if (boolean? super-id)
super-id
(with-syntax ([super-id super-id])
@ -432,7 +438,7 @@ add struct contracts for immutable structs?
(syntax (begin
(provide (rename id-rename struct-name))
(define-syntax id-rename
(list-immutable ((syntax-local-certifier) #'struct:struct-name)
(list-immutable ((syntax-local-certifier) #'-struct:struct-name)
((syntax-local-certifier) #'constructor-new-name)
((syntax-local-certifier) #'predicate-new-name)
(list-immutable ((syntax-local-certifier) #'rev-selector-new-names) ...
@ -440,7 +446,10 @@ add struct contracts for immutable structs?
(list-immutable ((syntax-local-certifier) #'rev-mutator-new-names) ...
((syntax-local-certifier) #'rev-mutator-old-names) ...)
super-id)))))]
[struct:struct-name struct:struct-name])
[struct:struct-name struct:struct-name]
[-struct:struct-name -struct:struct-name]
[struct-name struct-name]
[(selector-ids ...) selector-ids])
(syntax/loc stx
(begin
struct-code
@ -449,7 +458,23 @@ add struct contracts for immutable structs?
mutator-codes ...
predicate-code
constructor-code
(provide struct:struct-name))))))))
(define -struct:struct-name
(let-values ([(struct:struct-name _make _pred _get _set)
(make-struct-type 'struct-name
struct:struct-name
0 ;; init
0 ;; auto
#f ;; auto-v
'() ;; props
#f ;; inspector
#f ;; proc-spec
'
() ;; immutable-k-list
(λ (selector-ids ... ignore)
(values (-contract field-contract-ids selector-ids 'guess1 'guess2)
...)))])
struct:struct-name))
(provide (rename -struct:struct-name struct:struct-name)))))))))
;; map/count : (X Y int -> Z) (listof X) (listof Y) -> (listof Z)
#;
@ -491,7 +516,7 @@ add struct contracts for immutable structs?
[(a b)
(syntax-local-value
(syntax b)
(lambda ()
(λ ()
(raise-syntax-error 'provide/contract
"expected a struct name"
provide-stx
@ -505,7 +530,7 @@ add struct contracts for immutable structs?
[_ stx])])
(syntax-local-value
id
(lambda ()
(λ ()
(raise-syntax-error 'provide/contract
"expected a struct name"
provide-stx
@ -519,14 +544,14 @@ add struct contracts for immutable structs?
(field-contract-ids
...
. -> .
(let ([predicate-id (lambda (x) (predicate-id x))]) predicate-id)))))
(let ([predicate-id (λ (x) (predicate-id x))]) predicate-id)))))
;; build-selector-contract : syntax syntax -> syntax
;; constructs the contract for a selector
(define (build-selector-contract struct-name predicate-id field-contract-id)
(with-syntax ([field-contract-id field-contract-id]
[predicate-id predicate-id])
(syntax ((let ([predicate-id (lambda (x) (predicate-id x))]) predicate-id)
(syntax ((let ([predicate-id (λ (x) (predicate-id x))]) predicate-id)
. -> .
field-contract-id))))
@ -535,7 +560,7 @@ add struct contracts for immutable structs?
(define (build-mutator-contract struct-name predicate-id field-contract-id)
(with-syntax ([field-contract-id field-contract-id]
[predicate-id predicate-id])
(syntax ((let ([predicate-id (lambda (x) (predicate-id x))]) predicate-id)
(syntax ((let ([predicate-id (λ (x) (predicate-id x))]) predicate-id)
field-contract-id
. -> .
void?))))
@ -696,7 +721,8 @@ add struct contracts for immutable structs?
(λ (blame src str)
(let ([proc (contract-neg-proc arg)])
(λ (val)
((proc blame src str) val))))))]))
((proc blame src str) val))))
#f))]))
(define (check-contract ctc)
(unless (contract? ctc)
@ -751,15 +777,15 @@ add struct contracts for immutable structs?
(with-syntax ([(ctc-id ...) (generate-temporaries (syntax (ctc ...)))]
[(pred-id ...) (generate-temporaries (syntax (ctc ...)))])
(syntax
(let* ([pred (lambda (x) (error 'flat-rec-contract "applied too soon"))]
[name (flat-contract (let ([name (lambda (x) (pred x))]) name))])
(let ([ctc-id (coerce-contract flat-rec-contract ctc)] ...)
(let* ([pred (λ (x) (error 'flat-rec-contract "applied too soon"))]
[name (flat-contract (let ([name (λ (x) (pred x))]) name))])
(let ([ctc-id (coerce-contract 'flat-rec-contract ctc)] ...)
(unless (flat-contract? ctc-id)
(error 'flat-rec-contract "expected flat contracts as arguments, got ~e" ctc-id))
...
(set! pred
(let ([pred-id (flat-contract-predicate ctc-id)] ...)
(lambda (x)
(λ (x)
(or (pred-id x) ...))))
name))))]
[(_ name ctc ...)
@ -775,9 +801,9 @@ add struct contracts for immutable structs?
[((pred-arm-id ...) ...) (map generate-temporaries
(syntax->list (syntax ((ctc ...) ...))))])
(syntax
(let* ([pred-id (lambda (x) (error 'flat-murec-contract "applied too soon"))] ...
[name (flat-contract (let ([name (lambda (x) (pred-id x))]) name))] ...)
(let-values ([(ctc-id ...) (values (coerce-contract flat-rec-contract ctc) ...)] ...)
(let* ([pred-id (λ (x) (error 'flat-murec-contract "applied too soon"))] ...
[name (flat-contract (let ([name (λ (x) (pred-id x))]) name))] ...)
(let-values ([(ctc-id ...) (values (coerce-contract 'flat-rec-contract ctc) ...)] ...)
(begin
(void)
(unless (flat-contract? ctc-id)
@ -785,12 +811,12 @@ add struct contracts for immutable structs?
...) ...
(set! pred-id
(let ([pred-arm-id (flat-contract-predicate ctc-id)] ...)
(lambda (x)
(λ (x)
(or (pred-arm-id x) ...)))) ...
body1
body ...))))]
[(_ ([name ctc ...] ...) body1 body ...)
(for-each (lambda (name)
(for-each (λ (name)
(unless (identifier? name)
(raise-syntax-error 'flat-rec-contract
"expected an identifier" stx name)))
@ -815,51 +841,53 @@ add struct contracts for immutable structs?
[(_ args ...) (syntax (or/c args ...))]
[id (syntax or/c)])))
(define (or/c . args)
(define or/c
(case-lambda
[() (make-none/c '(or/c))]
[args
(for-each
(lambda (x)
(λ (x)
(unless (or (contract? x)
(and (procedure? x)
(procedure-arity-includes? x 1)))
(error 'or/c "expected procedures of arity 1 or contracts, given: ~e" x)))
args)
(let-values ([(contract fc/predicates)
(let loop ([contract #f]
(let-values ([(ho-contracts fc/predicates)
(let loop ([ho-contracts '()]
[fc/predicates null]
[args args])
(cond
[(null? args) (values contract (reverse fc/predicates))]
[(null? args) (values ho-contracts (reverse fc/predicates))]
[else
(let ([arg (car args)])
(cond
[(or (flat-contract? arg)
(not (contract? arg)))
(loop contract (cons arg fc/predicates) (cdr args))]
[contract
(error 'or/c "expected at most one non-flat contract, given ~e and ~e"
contract
arg)]
[else (loop arg fc/predicates (cdr args))]))]))])
(let ([flat-contracts (map (lambda (x) (if (flat-contract? x)
[(and (contract? arg)
(not (flat-contract? arg)))
(loop (cons arg ho-contracts) fc/predicates (cdr args))]
[else
(loop ho-contracts (cons arg fc/predicates) (cdr args))]))]))])
(let ([flat-contracts (map (λ (x) (if (flat-contract? x)
x
(flat-contract x)))
fc/predicates)])
(cond
[contract
(make-or/c flat-contracts contract)]
[(null? ho-contracts)
(make-flat-or/c flat-contracts)]
[(null? (cdr ho-contracts))
(make-or/c flat-contracts (car ho-contracts))]
[else
(make-flat-or/c flat-contracts)]))))
(make-multi-or/c flat-contracts ho-contracts)])))]))
(define-struct/prop or/c (flat-ctcs ho-ctc)
((pos-proj-prop (λ (ctc)
(let ([c-proc ((pos-proj-get (or/c-ho-ctc ctc)) (or/c-ho-ctc ctc))]
[predicates (map (λ (x) ((flat-get x) x))
(or/c-flat-ctcs ctc))])
(lambda (pos src-info orig-str)
(λ (pos src-info orig-str)
(let ([partial-contract (c-proc pos src-info orig-str)])
(lambda (val)
(λ (val)
(cond
[(ormap (lambda (pred) (pred val)) predicates)
[(ormap (λ (pred) (pred val)) predicates)
val]
[else
(partial-contract val)])))))))
@ -868,11 +896,11 @@ add struct contracts for immutable structs?
(let ([c-proc ((neg-proj-get (or/c-ho-ctc ctc)) (or/c-ho-ctc ctc))]
[predicates (map (λ (x) ((flat-get x) x))
(or/c-flat-ctcs ctc))])
(lambda (pos src-info orig-str)
(λ (pos src-info orig-str)
(let ([partial-contract (c-proc pos src-info orig-str)])
(lambda (val)
(λ (val)
(cond
[(ormap (lambda (pred) (pred val)) predicates)
[(ormap (λ (pred) (pred val)) predicates)
val]
[else
(partial-contract val)])))))))
@ -882,17 +910,100 @@ add struct contracts for immutable structs?
'or/c
(or/c-ho-ctc ctc)
(or/c-flat-ctcs ctc))))
(first-order-prop
(λ (ctc)
(let ([flats (map (λ (x) ((flat-get x) x)) (or/c-flat-ctcs ctc))]
[ho ((first-order-get (or/c-ho-ctc ctc)) (or/c-ho-ctc ctc))])
(λ (x)
(or (ho x)
(ormap (λ (f) (f x)) flats))))))
(stronger-prop
(λ (this that)
(and (or/c? that)
(and
(contract-stronger? (or/c-ho-ctc this) (or/c-ho-ctc that))
(let ([this-ctcs (or/c-flat-ctcs this)]
[that-ctcs (or/c-flat-ctcs that)])
(and (= (length this-ctcs) (length that-ctcs))
(andmap contract-stronger?
this-ctcs
that-ctcs)))))))))
that-ctcs))))))))
(define (make-multi-or/c-proj pos-proj-get)
(λ (ctc)
(let* ([ho-contracts (multi-or/c-ho-ctcs ctc)]
[c-procs (map (λ (x) ((pos-proj-get x) x)) ho-contracts)]
[first-order-checks (map (λ (x) ((first-order-get x) x)) ho-contracts)]
[predicates (map (λ (x) ((flat-get x) x))
(multi-or/c-flat-ctcs ctc))])
(λ (pos src-info orig-str)
(let ([partial-contracts (map (λ (c-proc) (c-proc pos src-info orig-str)) c-procs)])
(λ (val)
(cond
[(ormap (λ (pred) (pred val)) predicates)
val]
[else
(let loop ([checks first-order-checks]
[procs partial-contracts]
[contracts ho-contracts]
[candidate-proc #f]
[candidate-contract #f])
(cond
[(null? checks)
(if candidate-proc
(candidate-proc val)
(raise-contract-error val src-info pos orig-str
"none of the branches of the or/c matched"))]
[((car checks) val)
(if candidate-proc
(error 'or/c "two arguments, ~s and ~s, might both match ~s"
(contract-name candidate-contract)
(contract-name (car contracts))
val)
(loop (cdr checks)
(cdr procs)
(cdr contracts)
(car procs)
(car contracts)))]
[else
(loop (cdr checks)
(cdr procs)
(cdr contracts)
candidate-proc
candidate-contract)]))])))))))
(define-struct/prop multi-or/c (flat-ctcs ho-ctcs)
((pos-proj-prop (make-multi-or/c-proj pos-proj-get))
(neg-proj-prop (make-multi-or/c-proj neg-proj-get))
(name-prop (λ (ctc)
(apply build-compound-type-name
'or/c
(append
(multi-or/c-ho-ctcs ctc)
(multi-or/c-flat-ctcs ctc)))))
(first-order-prop
(λ (ctc)
(let ([flats (map (λ (x) ((flat-get x) x)) (multi-or/c-flat-ctcs ctc))]
[hos (map (λ (x) ((first-order-get x) x)) (multi-or/c-ho-ctcs ctc))])
(λ (x)
(or (ormap (λ (f) (f x)) hos)
(ormap (λ (f) (f x)) flats))))))
(stronger-prop
(λ (this that)
(and (multi-or/c? that)
(let ([this-ctcs (multi-or/c-ho-ctcs this)]
[that-ctcs (multi-or/c-ho-ctcs that)])
(and (= (length this-ctcs) (length that-ctcs))
(andmap contract-stronger?
this-ctcs
that-ctcs)))
(let ([this-ctcs (multi-or/c-flat-ctcs this)]
[that-ctcs (multi-or/c-flat-ctcs that)])
(and (= (length this-ctcs) (length that-ctcs))
(andmap contract-stronger?
this-ctcs
that-ctcs))))))))
(define-struct/prop flat-or/c (flat-ctcs)
((pos-proj-prop flat-pos-proj)
@ -919,14 +1030,14 @@ add struct contracts for immutable structs?
(define false/c
(flat-named-contract
'false/c
(lambda (x) (not x))))
(λ (x) (not x))))
(define (string/len n)
(unless (number? n)
(error 'string/len "expected a number as argument, got ~e" n))
(flat-named-contract
`(string/len ,n)
(lambda (x)
(λ (x)
(and (string? x)
((string-length x) . < . n)))))
@ -935,7 +1046,7 @@ add struct contracts for immutable structs?
(error 'symbols "expected at least one argument"))
(unless (andmap symbol? ss)
(error 'symbols "expected symbols as arguments, given: ~a"
(apply string-append (map (lambda (x) (format "~e " x)) ss))))
(apply string-append (map (λ (x) (format "~e " x)) ss))))
(make-one-of/c ss))
(define atomic-value?
@ -979,7 +1090,7 @@ add struct contracts for immutable structs?
(define printable/c
(flat-named-contract
'printable/c
(lambda (x)
(λ (x)
(let printable? ([x x])
(or (symbol? x)
(string? x)
@ -1027,16 +1138,16 @@ add struct contracts for immutable structs?
(define (</c x)
(flat-named-contract
`(</c ,x)
(lambda (y) (and (number? y) (< y x)))))
(λ (y) (and (number? y) (< y x)))))
(define (>/c x)
(flat-named-contract
`(>/c ,x)
(lambda (y) (and (number? y) (> y x)))))
(λ (y) (and (number? y) (> y x)))))
(define natural-number/c
(flat-named-contract
'natural-number/c
(lambda (x)
(λ (x)
(and (number? x)
(integer? x)
(x . >= . 0)))))
@ -1047,7 +1158,7 @@ add struct contracts for immutable structs?
(error 'integer-in "expected two integers as arguments, got ~e and ~e" start end))
(flat-named-contract
`(integer-in ,start ,end)
(lambda (x)
(λ (x)
(and (integer? x)
(<= start x end)))))
@ -1059,7 +1170,7 @@ add struct contracts for immutable structs?
(error 'integer-in "expected two exact integers as arguments, got ~e and ~e" start end))
(flat-named-contract
`(exact-integer-in ,start ,end)
(lambda (x)
(λ (x)
(and (integer? x)
(exact? x)
(<= start x end)))))
@ -1070,7 +1181,7 @@ add struct contracts for immutable structs?
(error 'real-in "expected two real numbers as arguments, got ~e and ~e" start end))
(flat-named-contract
`(real-in ,start ,end)
(lambda (x)
(λ (x)
(and (real? x)
(<= start x end)))))
@ -1079,34 +1190,34 @@ add struct contracts for immutable structs?
(error 'not/c "expected a procedure of arity 1 or <flat-named-contract>, given: ~e" f))
(build-flat-contract
(build-compound-type-name 'not/c (proc/ctc->ctc f))
(lambda (x) (not (test-proc/flat-contract f x)))))
(λ (x) (not (test-proc/flat-contract f x)))))
(define (listof p)
(unless (flat-contract/predicate? p)
(error 'listof "expected a flat contract or procedure of arity 1 as argument, got: ~e" p))
(build-flat-contract
(build-compound-type-name 'listof (proc/ctc->ctc p))
(lambda (v)
(λ (v)
(and (list? v)
(andmap (lambda (ele) (test-proc/flat-contract p ele))
(andmap (λ (ele) (test-proc/flat-contract p ele))
v)))))
(define-syntax (*-immutableof stx)
(syntax-case stx ()
[(_ predicate? fill type-name name)
(identifier? (syntax predicate?))
(syntax
(let ([predicate?-name predicate?]
[fill-name fill])
(lambda (input)
(let* ([ctc (coerce-contract name input)]
(let ([fill-name fill])
(λ (input)
(let* ([ctc (coerce-contract 'name input)]
[p-proj (contract-pos-proc ctc)]
[n-proj (contract-neg-proc ctc)])
(make-pair-proj-contract
(build-compound-type-name 'name ctc)
(lambda (blame src-info orig-str)
(λ (blame src-info orig-str)
(let ([p-app (p-proj blame src-info orig-str)])
(lambda (val)
(unless (predicate?-name val)
(λ (val)
(unless (predicate? val)
(raise-contract-error
val
src-info
@ -1116,10 +1227,11 @@ add struct contracts for immutable structs?
'type-name
val))
(fill-name p-app val))))
(lambda (blame src-info orig-str)
(λ (blame src-info orig-str)
(let ([n-app (n-proj blame src-info orig-str)])
(lambda (val)
(fill-name n-app val)))))))))]))
(λ (val)
(fill-name n-app val))))
predicate?)))))]))
(define (map-immutable f lst)
(let loop ([lst lst])
@ -1129,20 +1241,21 @@ add struct contracts for immutable structs?
(loop (cdr lst)))]
[(null? lst) null])))
(define (immutable-list? lst)
(cond
[(and (pair? lst)
(immutable? lst))
(immutable-list? (cdr lst))]
[(null? lst) #t]
[else #f]))
(define (immutable-list? val)
(let loop ([v val])
(or (and (pair? v)
(immutable? v)
(loop (cdr v)))
(null? v))))
(define list-immutableof
(*-immutableof immutable-list? map-immutable immutable-list list-immutableof))
(define (immutable-vector? val) (and (immutable? val) (vector? val)))
(define vector-immutableof
(*-immutableof (lambda (x) (and (vector? x) (immutable? x)))
(lambda (f v) (apply vector-immutable (map f (vector->list v))))
(*-immutableof immutable-vector?
(λ (f v) (apply vector-immutable (map f (vector->list v))))
immutable-vector
vector-immutableof))
@ -1151,9 +1264,9 @@ add struct contracts for immutable structs?
(error 'vectorof "expected a flat contract or procedure of arity 1 as argument, got: ~e" p))
(build-flat-contract
(build-compound-type-name 'vectorof (proc/ctc->ctc p))
(lambda (v)
(λ (v)
(and (vector? v)
(andmap (lambda (ele) (test-proc/flat-contract p ele))
(andmap (λ (ele) (test-proc/flat-contract p ele))
(vector->list v))))))
(define (vector/c . args)
@ -1169,7 +1282,7 @@ add struct contracts for immutable structs?
(let ([largs (length args)])
(build-flat-contract
(apply build-compound-type-name 'vector/c (map proc/ctc->ctc args))
(lambda (v)
(λ (v)
(and (vector? v)
(= (vector-length v) largs)
(andmap test-proc/flat-contract
@ -1181,7 +1294,7 @@ add struct contracts for immutable structs?
(error 'box/c "expected a flat contract or a procedure of arity 1, got: ~e" pred))
(build-flat-contract
(build-compound-type-name 'box/c (proc/ctc->ctc pred))
(lambda (x)
(λ (x)
(and (box? x)
(test-proc/flat-contract pred (unbox x))))))
@ -1191,7 +1304,7 @@ add struct contracts for immutable structs?
(error 'cons/c "expected two flat contracts or procedures of arity 1, got: ~e and ~e" hdp tlp))
(build-flat-contract
(build-compound-type-name 'cons/c (proc/ctc->ctc hdp) (proc/ctc->ctc tlp))
(lambda (x)
(λ (x)
(and (pair? x)
(test-proc/flat-contract hdp (car x))
(test-proc/flat-contract tlp (cdr x))))))
@ -1210,16 +1323,16 @@ add struct contracts for immutable structs?
(let ([predicate?-name predicate?]
[constructor-name constructor]
[selector-names selectors] ...)
(lambda (params ...)
(let ([ctc-x (coerce-contract name params)] ...)
(λ (params ...)
(let ([ctc-x (coerce-contract 'name params)] ...)
(let ([pos-procs (contract-pos-proc ctc-x)]
...
[neg-procs (contract-neg-proc ctc-x)] ...)
(make-pair-proj-contract
(build-compound-type-name 'name (proc/ctc->ctc params) ...)
(lambda (blame src-info orig-str)
(λ (blame src-info orig-str)
(let ([p-apps (pos-procs blame src-info orig-str)] ...)
(lambda (v)
(λ (v)
(if (and (immutable? v)
(predicate?-name v))
(constructor-name (p-apps (selector-names v)) ...)
@ -1231,26 +1344,27 @@ add struct contracts for immutable structs?
"expected <~a>, given: ~e"
'type-name
v)))))
(lambda (blame src-info orig-str)
(λ (blame src-info orig-str)
(let ([p-apps (neg-procs blame src-info orig-str)] ...)
(lambda (v)
(constructor-name (p-apps (selector-names v)) ...)))))))))))]
(λ (v)
(constructor-name (p-apps (selector-names v)) ...))))
#f)))))))]
[(_ predicate? constructor (arb? selector) correct-size type-name name)
(eq? #t (syntax-object->datum (syntax arb?)))
(syntax
(let ([predicate?-name predicate?]
[constructor-name constructor]
[selector-name selector])
(lambda params
(let ([ctcs (map (lambda (param) (coerce-contract name param)) params)])
(λ params
(let ([ctcs (map (λ (param) (coerce-contract 'name param)) params)])
(let ([pos-procs (map contract-pos-proc ctcs)]
[neg-procs (map contract-neg-proc ctcs)])
(make-pair-proj-contract
(apply build-compound-type-name 'name (map proc/ctc->ctc params))
(lambda (blame src-info orig-str)
(let ([p-apps (map (lambda (proc) (proc blame src-info orig-str)) pos-procs)]
(λ (blame src-info orig-str)
(let ([p-apps (map (λ (proc) (proc blame src-info orig-str)) pos-procs)]
[count (length params)])
(lambda (v)
(λ (v)
(if (and (immutable? v)
(predicate?-name v)
(correct-size count v))
@ -1270,9 +1384,9 @@ add struct contracts for immutable structs?
"expected <~a>, given: ~e"
'type-name
v)))))
(lambda (blame src-info orig-str)
(let ([p-apps (map (lambda (proc) (proc blame src-info orig-str)) neg-procs)])
(lambda (v)
(λ (blame src-info orig-str)
(let ([p-apps (map (λ (proc) (proc blame src-info orig-str)) neg-procs)])
(λ (v)
(apply constructor-name
(let loop ([p-apps p-apps]
[i 0])
@ -1280,14 +1394,15 @@ add struct contracts for immutable structs?
[(null? p-apps) null]
[else (let ([p-app (car p-apps)])
(cons (p-app (selector-name v i))
(loop (cdr p-apps) (+ i 1))))]))))))))))))]))
(loop (cdr p-apps) (+ i 1))))]))))))
#f))))))]))
(define cons-immutable/c (*-immutable/c pair? cons-immutable (#f car cdr) immutable-cons cons-immutable/c))
(define box-immutable/c (*-immutable/c box? box-immutable (#f unbox) immutable-box box-immutable/c))
(define vector-immutable/c (*-immutable/c vector?
vector-immutable
(#t (lambda (v i) (vector-ref v i)))
(lambda (n v) (= n (vector-length v)))
(#t (λ (v i) (vector-ref v i)))
(λ (n v) (= n (vector-length v)))
immutable-vector
vector-immutable/c))
@ -1307,7 +1422,7 @@ add struct contracts for immutable structs?
[else (cons/c (car args) (loop (cdr args)))])))
(define (list-immutable/c . args)
(unless (andmap (lambda (x) (or (contract? x)
(unless (andmap (λ (x) (or (contract? x)
(and (procedure? x)
(procedure-arity-includes? x 1))))
args)
@ -1325,24 +1440,24 @@ add struct contracts for immutable structs?
[else (cons-immutable/c (car args) (loop (cdr args)))])))
(define (syntax/c ctc-in)
(let ([ctc (coerce-contract syntax/c ctc-in)])
(let ([ctc (coerce-contract 'syntax/c ctc-in)])
(build-flat-contract
(build-compound-type-name 'syntax/c ctc)
(let ([pred (flat-contract-predicate ctc)])
(lambda (val)
(λ (val)
(and (syntax? val)
(pred (syntax-e val))))))))
(define promise/c
(lambda (ctc-in)
(let* ([ctc (coerce-contract promise/c ctc-in)]
(λ (ctc-in)
(let* ([ctc (coerce-contract 'promise/c ctc-in)]
[pos-ctc-proc (contract-pos-proc ctc)]
[neg-ctc-proc (contract-neg-proc ctc)])
(make-pair-proj-contract
(build-compound-type-name 'promise/c ctc)
(lambda (blame src-info orig-str)
(λ (blame src-info orig-str)
(let ([p-app (pos-ctc-proc blame src-info orig-str)])
(lambda (val)
(λ (val)
(unless (promise? val)
(raise-contract-error
val
@ -1353,10 +1468,11 @@ add struct contracts for immutable structs?
"expected <promise>, given: ~e"
val))
(delay (p-app (force val))))))
(lambda (blame src-info orig-str)
(λ (blame src-info orig-str)
(let ([p-app (neg-ctc-proc blame src-info orig-str)])
(lambda (val)
(delay (p-app (force val))))))))))
(λ (val)
(delay (p-app (force val))))))
promise?))))
#|
as with copy-struct in struct.ss, this first begin0
@ -1372,7 +1488,7 @@ add struct contracts for immutable structs?
(syntax-case stx ()
[(_ struct-name args ...)
(and (identifier? (syntax struct-name))
(syntax-local-value (syntax struct-name) (lambda () #f)))
(syntax-local-value (syntax struct-name) (λ () #f)))
(with-syntax ([(ctc-x ...) (generate-temporaries (syntax (args ...)))]
[(ctc-name-x ...) (generate-temporaries (syntax (args ...)))]
[(ctc-pred-x ...) (generate-temporaries (syntax (args ...)))]
@ -1392,7 +1508,7 @@ add struct contracts for immutable structs?
(syntax-local-value (syntax struct-name))])
(with-syntax ([(selector-id ...) (reverse (syntax->list (syntax (rev-selector-id ...))))])
(syntax
(let ([ctc-x (coerce-contract struct/c args)] ...)
(let ([ctc-x (coerce-contract 'struct/c args)] ...)
(unless predicate-id
(error 'struct/c "could not determine predicate for ~s" 'struct-name))

View File

@ -128,6 +128,9 @@
(test/no-error '(listof any/c))
(test/no-error '(listof (lambda (x) #t)))
(test/spec-passed/result 'any/c '(contract any/c 1 'pos 'neg) 1)
(test/pos-blame 'none/c '(contract none/c 1 'pos 'neg))
(test/spec-passed
'contract-arrow-star0a
'(contract (->* (integer?) (integer?))
@ -1134,6 +1137,34 @@
'neg)
1))
(test/pos-blame
'contract-case->0a
'(contract (case->)
(lambda (x) x)
'pos
'neg))
(test/pos-blame
'contract-case->0b
'(contract (case->)
(lambda () 1)
'pos
'neg))
(test/pos-blame
'contract-case->0c
'(contract (case->)
1
'pos
'neg))
(test/spec-passed
'contract-case->0d
'(contract (case->)
(case-lambda)
'pos
'neg))
(test/pos-blame
'contract-case->1
'(contract (case-> (integer? integer? . -> . integer?) (integer? . -> . integer?))
@ -1335,6 +1366,47 @@
#f)
#f)
(test/spec-passed/result
'or/c9
'((contract (or/c (-> string?) (-> integer? integer?))
(λ () "x")
'pos
'neg))
"x")
(test/spec-passed/result
'or/c10
'((contract (or/c (-> string?) (-> integer? integer?))
(λ (x) x)
'pos
'neg)
1)
1)
(test/pos-blame
'or/c11
'(contract (or/c (-> string?) (-> integer? integer?))
1
'pos
'neg))
(test/pos-blame
'or/c12
'((contract (or/c (-> string?) (-> integer? integer?))
1
'pos
'neg)
'x))
(test 1 'or/c-not-error-early
(begin (or/c (-> integer? integer?) (-> boolean? boolean?))
1))
(error-test #'(contract (or/c (-> integer? integer?) (-> boolean? boolean?))
(λ (x) x)
'pos
'neg)
exn:fail?)
(test
'(1 2)
'or/c-ordering
@ -1365,6 +1437,20 @@
'neg)
x))
(test
(reverse '(1 3 4 2))
'ho-and/c-ordering
(let ([x '()])
((contract (and/c (-> (lambda (y) (set! x (cons 1 x)) #t)
(lambda (y) (set! x (cons 2 x)) #t))
(-> (lambda (y) (set! x (cons 3 x)) #t)
(lambda (y) (set! x (cons 4 x)) #t)))
(λ (x) x)
'pos
'neg)
1)
x))
(test/spec-passed
'define/contract1
'(let ()
@ -3964,6 +4050,7 @@
(-> integer? integer? integer?))
(case-> (->r ((x number?) (y boolean?) (z pair?)) number?)
(-> integer? integer? integer?)))
(test-name '(case->) (case->))
(test-name '(case-> (-> integer? integer?) (-> integer? integer? integer?))
(case-> (-> integer? integer?) (-> integer? integer? integer?)))
@ -4151,6 +4238,28 @@
(test #f contract-stronger? (symbols 'z 'x 'y) (symbols 'x 'y))
(test #t contract-stronger? (one-of/c (expt 2 100)) (one-of/c (expt 2 100) 12))
(test #t contract-stronger?
(or/c (-> (>=/c 3) (>=/c 3)) (-> string?))
(or/c (-> (>=/c 4) (>=/c 3)) (-> string?)))
(test #f contract-stronger?
(or/c (-> string?) (-> integer? integer?))
(or/c (-> string?) (-> any/c integer?)))
(test #f contract-stronger?
(or/c (-> string?) (-> any/c integer?))
(or/c (-> string?) (-> integer? integer?)))
(test #t contract-stronger?
(or/c (-> string?) (-> integer? integer?) integer? boolean?)
(or/c (-> string?) (-> integer? integer?) integer? boolean?))
(test #f contract-stronger?
(or/c (-> string?) (-> integer? integer?) integer? char?)
(or/c (-> string?) (-> integer? integer?) integer? boolean?))
(test #f contract-stronger?
(or/c (-> string?) (-> integer? integer?) integer?)
(or/c (-> string?) (-> integer? integer?) integer? boolean?))
(test #f contract-stronger?
(or/c (-> string?) (-> integer? integer?) integer?)
(or/c (-> integer? integer?) integer?))
(let ()
(define-contract-struct couple (hd tl))
(define (non-zero? x) (not (zero? x)))
@ -4194,5 +4303,185 @@
(test #t contract-stronger? (sorted-list/less-than 4) (sorted-list/less-than 5))
(test #f contract-stronger? (sorted-list/less-than 5) (sorted-list/less-than 4)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; first-order tests
;;
(test #t contract-first-order-passes? (flat-contract integer?) 1)
(test #f contract-first-order-passes? (flat-contract integer?) 'x)
(test #t contract-first-order-passes? (flat-contract boolean?) #t)
(test #f contract-first-order-passes? (flat-contract boolean?) 'x)
(test #t contract-first-order-passes? any/c 1)
(test #t contract-first-order-passes? any/c #t)
(test #t contract-first-order-passes? (-> integer? integer?) (λ (x) #t))
(test #f contract-first-order-passes? (-> integer? integer?) (λ (x y) #t))
(test #f contract-first-order-passes? (-> integer? integer?) 'x)
(test #t contract-first-order-passes? (-> integer? boolean? integer?) (λ (x y) #t))
(test #f contract-first-order-passes? (-> integer? boolean? integer?) (λ (x) #t))
(test #f contract-first-order-passes? (-> integer? boolean? integer?) (λ (x y z) #t))
(test #t contract-first-order-passes? (->* (integer?) boolean? (char? any/c)) (λ (x . y) #f))
(test #f contract-first-order-passes? (->* (integer?) boolean? (char? any/c)) (λ (x y . z) #f))
(test #f contract-first-order-passes? (->* (integer?) boolean? (char? any/c)) (λ (x) #f))
(test #t contract-first-order-passes? (->* (integer?) boolean? (char? any/c)) (λ x #f))
(test #t contract-first-order-passes? (->d integer? boolean? (lambda (x y) char?)) (λ (x y) x))
(test #f contract-first-order-passes? (->d integer? boolean? (lambda (x y) char?)) (λ (x) x))
(test #f contract-first-order-passes? (->d integer? boolean? (lambda (x y) char?)) (λ (x y z) x))
(test #t contract-first-order-passes? (list-immutableof integer?) (list-immutable 1))
(test #f contract-first-order-passes? (list-immutableof integer?) (list 1))
(test #f contract-first-order-passes? (list-immutableof integer?) #f)
(test #t contract-first-order-passes? (vector-immutableof integer?) (vector->immutable-vector (vector 1)))
(test #f contract-first-order-passes? (vector-immutableof integer?) 'x)
(test #f contract-first-order-passes? (vector-immutableof integer?) '())
(test #t contract-first-order-passes? (promise/c integer?) (delay 1))
(test #f contract-first-order-passes? (promise/c integer?) 1)
(test #t contract-first-order-passes? (->d* (integer? boolean?) (lambda (x y) char?)) (λ (x y) #t))
(test #f contract-first-order-passes? (->d* (integer? boolean?) (lambda (x y) char?)) (λ (x) #t))
(test #f contract-first-order-passes? (->d* (integer? boolean?) (lambda (x y) char?)) (λ (x y z) #t))
(test #t contract-first-order-passes?
(->d* (integer? boolean?) any/c (lambda (x y . z) char?))
(λ (x y . z) z))
(test #t contract-first-order-passes?
(->d* (integer? boolean?) any/c (lambda (x y . z) char?))
(λ (y . z) z))
(test #t contract-first-order-passes?
(->d* (integer? boolean?) any/c (lambda (x y . z) char?))
(λ z z))
(test #f contract-first-order-passes?
(->d* (integer? boolean?) any/c (lambda (x y . z) char?))
(λ (x y z . w) 1))
(test #f contract-first-order-passes?
(->d* (integer? boolean?) any/c (lambda (x y . z) char?))
(λ (x y) 1))
(test #t contract-first-order-passes? (->r ((x number?)) number?) (λ (x) 1))
(test #f contract-first-order-passes? (->r ((x number?)) number?) (λ (x y) 1))
(test #f contract-first-order-passes? (->r ((x number?)) number?) (λ () 1))
(test #t contract-first-order-passes? (->r ((x number?)) number?) (λ args 1))
(test #t contract-first-order-passes? (->pp ((x number?)) #t number? blech #t) (λ (x) 1))
(test #f contract-first-order-passes? (->pp ((x number?)) #t number? blech #t) (λ () 1))
(test #t contract-first-order-passes? (->pp ((x number?)) #t number? blech #t) (λ (x . y) 1))
(test #f contract-first-order-passes?
(case-> (-> integer? integer?)
(-> integer? integer? integer?))
(λ () 1))
(test #f contract-first-order-passes?
(case-> (-> integer? integer?)
(-> integer? integer? integer?))
(λ (x) 1))
(test #f contract-first-order-passes?
(case-> (-> integer? integer?)
(-> integer? integer? integer?))
(λ (x y) 1))
(test #f contract-first-order-passes?
(case->)
1)
(test #t contract-first-order-passes?
(case->)
(case-lambda))
(test #t contract-first-order-passes?
(case-> (-> integer? integer?)
(-> integer? integer? integer?))
(case-lambda [(x) x] [(x y) x]))
(test #t contract-first-order-passes?
(case-> (-> integer? integer?)
(-> integer? integer? integer?))
(case-lambda [() 1] [(x) x] [(x y) x]))
(test #t contract-first-order-passes?
(case-> (-> integer? integer?)
(-> integer? integer? integer?))
(case-lambda [() 1] [(x) x] [(x y) x] [(x y z) x]))
(test #t contract-first-order-passes? (and/c (-> positive? positive?) (-> integer? integer?)) (λ (x) x))
(test #t contract-first-order-passes? (and/c (-> positive? positive?) (-> integer? integer?)) values)
(test #f contract-first-order-passes? (and/c (-> integer?) (-> integer? integer?)) (λ (x) x))
(test #t contract-first-order-passes?
(cons-immutable/c boolean? (-> integer? integer?))
(list*-immutable #t (λ (x) x)))
(test #t contract-first-order-passes?
(cons-immutable/c boolean? (-> integer? integer?))
(list*-immutable 1 2))
(test #f contract-first-order-passes? (flat-rec-contract the-name) 1)
(test #t contract-first-order-passes?
(object-contract (m (-> integer? integer?)))
(new object%))
(test #t contract-first-order-passes?
(object-contract (m (-> integer? integer?)))
1)
(let ()
(define-contract-struct couple (hd tl))
(test #t contract-first-order-passes?
(couple/c any/c any/c)
(make-couple 1 2))
(test #f contract-first-order-passes?
(couple/c any/c any/c)
2)
(test #t contract-first-order-passes?
(couple/dc [hd any/c] [tl any/c])
(make-couple 1 2))
(test #f contract-first-order-passes?
(couple/dc [hd any/c] [tl any/c])
1)
(test #t contract-first-order-passes?
(couple/dc [hd any/c] [tl (hd) any/c])
(make-couple 1 2))
(test #f contract-first-order-passes?
(couple/dc [hd any/c] [tl (hd) any/c])
1))
(test #t contract-first-order-passes? (or/c (-> (>=/c 5) (>=/c 5)) boolean?) #t)
(test #t contract-first-order-passes? (or/c (-> (>=/c 5) (>=/c 5)) boolean?) (λ (x) x))
(test #f contract-first-order-passes? (or/c (-> (>=/c 5) (>=/c 5)) boolean?) 'x)
(test #t contract-first-order-passes?
(or/c (-> integer? integer? integer?)
(-> integer? integer?))
(λ (x) x))
(test #t contract-first-order-passes?
(or/c (-> integer? integer? integer?)
(-> integer? integer?))
(λ (x y) x))
(test #f contract-first-order-passes?
(or/c (-> integer? integer? integer?)
(-> integer? integer?))
(λ () x))
(test #f contract-first-order-passes?
(or/c (-> integer? integer? integer?)
(-> integer? integer?))
1)
(test-name '(or/c) (or/c))
(test-name '(or/c integer? gt0?) (or/c integer? (let ([gt0? (lambda (x) (> x 0))]) gt0?)))
(test-name '(or/c integer? boolean?)
(or/c (flat-contract integer?)
(flat-contract boolean?)))
(test-name '(or/c (-> (>=/c 5) (>=/c 5)) boolean?)
(or/c (-> (>=/c 5) (>=/c 5)) boolean?))
(test-name '(or/c (-> (>=/c 5) (>=/c 5)) boolean?)
(or/c boolean? (-> (>=/c 5) (>=/c 5))))
))
(report-errs)