moved unstable/poly-c to racket/contract/parametric
This commit is contained in:
parent
937c5ea442
commit
f49412add8
|
@ -1,14 +1,7 @@
|
|||
#lang racket/base
|
||||
|
||||
(require racket/bool racket/contract)
|
||||
|
||||
(provide poly/c parametric/c opaque/c memory/c)
|
||||
|
||||
(define-syntax-rule (poly/c [x ...] c)
|
||||
(make-polymorphic-contract 'poly/c
|
||||
memory/c
|
||||
'(x ...)
|
||||
(lambda (x ...) c)))
|
||||
(require racket/bool
|
||||
racket/contract)
|
||||
(provide parametric/c)
|
||||
|
||||
(define-syntax-rule (parametric/c [x ...] c)
|
||||
(make-polymorphic-contract 'parametric/c
|
||||
|
@ -57,13 +50,6 @@
|
|||
[(a b c d e f g h) ((wrap p) a b c d e f g h)]
|
||||
[args (apply (wrap p) args)])))))))
|
||||
|
||||
(define (memory/c positive? name)
|
||||
(define memory (make-weak-hasheq))
|
||||
(define (make x) (hash-set! memory x #t) x)
|
||||
(define (pred x) (hash-has-key? memory x))
|
||||
(define (get x) x)
|
||||
(make-barrier-contract name positive? make pred get))
|
||||
|
||||
(define (opaque/c positive? name)
|
||||
(define-values [ type make pred getter setter ]
|
||||
(make-struct-type name #f 1 0))
|
|
@ -1,11 +1,12 @@
|
|||
#lang scribble/doc
|
||||
@(require "mz.rkt")
|
||||
@(require (for-label syntax/modcollapse))
|
||||
@(require (for-label syntax/modcollapse
|
||||
racket/contract/parametric))
|
||||
|
||||
@(define contract-eval
|
||||
(lambda ()
|
||||
(let ([the-eval (make-base-eval)])
|
||||
(the-eval '(require racket/contract))
|
||||
(the-eval '(require racket/contract racket/contract/parametric))
|
||||
the-eval)))
|
||||
|
||||
@title[#:tag "contracts" #:style 'toc]{Contracts}
|
||||
|
@ -785,6 +786,38 @@ be blamed using the above contract:
|
|||
@racket[the-unsupplied-arg].
|
||||
}
|
||||
|
||||
|
||||
@subsection[#:tag "parametric-contracts"]{Parametric Contracts}
|
||||
|
||||
@defmodule[racket/contract/parametric]
|
||||
|
||||
@defform[(parametric/c (x ...) c)]{
|
||||
|
||||
Creates a contract for parametric polymorphic functions. Each function is
|
||||
protected by @racket[c], where each @racket[x] is bound in @racket[c] and refers
|
||||
to a polymorphic type that is instantiated each time the function is applied.
|
||||
|
||||
At each application of a function, the @racket[parametric/c] contract constructs
|
||||
a new opaque wrapper for each @racket[x]; values flowing into the polymorphic
|
||||
function (i.e. values protected by some @racket[x] in negative position with
|
||||
respect to @racket[parametric/c]) are wrapped in the corresponding opaque
|
||||
wrapper. Values flowing out of the polymorphic function (i.e. values protected
|
||||
by some @racket[x] in positive position with respect to @racket[parametric/c])
|
||||
are checked for the appropriate wrapper. If they have it, they are unwrapped;
|
||||
if they do not, a contract violation is signalled.
|
||||
|
||||
@examples[#:eval (contract-eval)
|
||||
(define/contract (check x y) (parametric/c [X] (boolean? X . -> . X))
|
||||
(if (or (not x) (equal? y 'surprise))
|
||||
'invalid
|
||||
y))
|
||||
(check #t 'ok)
|
||||
(check #f 'ignored)
|
||||
(check #t 'surprise)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@; ------------------------------------------------------------------------
|
||||
|
||||
@section{Lazy Data-structure Contracts}
|
||||
|
@ -1840,4 +1873,3 @@ defines the @racket[bst/c] contract that checks the binary
|
|||
search tree invariant. Removing the @racket[-opt/c] also
|
||||
makes a binary search tree contract, but one that is
|
||||
(approximately) 20 times slower.}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
(private parse-type)
|
||||
racket/match unstable/match syntax/struct syntax/stx mzlib/trace racket/syntax scheme/list
|
||||
(only-in scheme/contract -> ->* case-> cons/c flat-rec-contract provide/contract any/c)
|
||||
(for-template scheme/base scheme/contract unstable/poly-c (utils any-wrap)
|
||||
(for-template scheme/base scheme/contract racket/contract/parametric (utils any-wrap)
|
||||
(only-in scheme/class object% is-a?/c subclass?/c object-contract class/c init object/c class?)))
|
||||
|
||||
(define (define/fixup-contract? stx)
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
#lang scribble/manual
|
||||
@(require scribble/eval
|
||||
"utils.rkt"
|
||||
(for-label unstable/poly-c
|
||||
racket/contract
|
||||
racket/base))
|
||||
|
||||
@title[#:tag "poly-c"]{Polymorphic Contracts}
|
||||
|
||||
@(define (build-eval)
|
||||
(let* ([e (make-base-eval)])
|
||||
(e '(require unstable/poly-c racket/contract))
|
||||
e))
|
||||
|
||||
@defmodule[unstable/poly-c]
|
||||
|
||||
@unstable[@author+email["Sam Tobin-Hochstadt" "samth@ccs.neu.edu"]
|
||||
@author+email["Carl Eastlund" "cce@ccs.neu.edu"]]
|
||||
|
||||
@defform[(poly/c (x ...) c)]{
|
||||
|
||||
Creates a contract for polymorphic functions that may inspect their arguments.
|
||||
Each function is protected by @racket[c], where each @racket[x] is bound in
|
||||
@racket[c] and refers to a polymorphic type that is instantiated each time the
|
||||
function is applied.
|
||||
|
||||
At each application of a function, the @racket[poly/c] contract constructs a new
|
||||
weak, @racket[eq?]-based hash table for each @racket[x]. Values flowing into
|
||||
the polymorphic function (i.e. values protected by some @racket[x] in negative
|
||||
position with respect to @racket[poly/c]) are stored in the hash table. Values
|
||||
flowing out of the polymorphic function (i.e. protected by some @racket[x] in
|
||||
positive position with respect to @racket[poly/c]) are checked for their
|
||||
presence in the hash table. If they are present, they are returned; otherwise,
|
||||
a contract violation is signalled.
|
||||
|
||||
@examples[#:eval (build-eval)
|
||||
(define/contract (check x y) (poly/c [X] (boolean? X . -> . X))
|
||||
(if (or (not x) (equal? y 'surprise))
|
||||
'invalid
|
||||
y))
|
||||
(check #t 'ok)
|
||||
(check #f 'ignored)
|
||||
(check #t 'surprise)
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@defform[(parametric/c (x ...) c)]{
|
||||
|
||||
Creates a contract for parametric polymorphic functions. Each function is
|
||||
protected by @racket[c], where each @racket[x] is bound in @racket[c] and refers
|
||||
to a polymorphic type that is instantiated each time the function is applied.
|
||||
|
||||
At each application of a function, the @racket[parametric/c] contract constructs
|
||||
a new opaque wrapper for each @racket[x]; values flowing into the polymorphic
|
||||
function (i.e. values protected by some @racket[x] in negative position with
|
||||
respect to @racket[parametric/c]) are wrapped in the corresponding opaque
|
||||
wrapper. Values flowing out of the polymorphic function (i.e. values protected
|
||||
by some @racket[x] in positive position with respect to @racket[parametric/c])
|
||||
are checked for the appropriate wrapper. If they have it, they are unwrapped;
|
||||
if they do not, a contract violation is signalled.
|
||||
|
||||
@examples[#:eval (build-eval)
|
||||
(define/contract (check x y) (parametric/c [X] (boolean? X . -> . X))
|
||||
(if (or (not x) (equal? y 'surprise))
|
||||
'invalid
|
||||
y))
|
||||
(check #t 'ok)
|
||||
(check #f 'ignored)
|
||||
(check #t 'surprise)
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
@defproc[(memory/c [positive? boolean?] [name any/c]) contract?]{
|
||||
|
||||
This function constructs a contract that records values flowing in one direction
|
||||
in a fresh, weak hash table, and looks up values flowing in the other direction,
|
||||
signalling a contract violation if those values are not in the table.
|
||||
|
||||
If @racket[positive?] is true, values in positive position get stored and values
|
||||
in negative position are checked. Otherwise, the reverse happens.
|
||||
|
||||
}
|
||||
|
||||
@defproc[(opaque/c [positive? boolean?] [name any/c]) contract?]{
|
||||
|
||||
This function constructs a contract that wraps values flowing in one direction
|
||||
in a unique, opaque wrapper, and unwraps values flowing in the other direction,
|
||||
signalling a contract violation if those values are not wrapped.
|
||||
|
||||
If @racket[positive?] is true, values in positive position get wrapped and
|
||||
values in negative position get unwrapped. Otherwise, the reverse happens.
|
||||
|
||||
}
|
|
@ -97,7 +97,6 @@ Keep documentation and tests up to date.
|
|||
@include-section["text.scrbl"]
|
||||
@include-section["values.scrbl"]
|
||||
@include-section["web.scrbl"]
|
||||
@include-section["poly-c.scrbl"]
|
||||
@include-section["mutated-vars.scrbl"]
|
||||
@include-section["find.scrbl"]
|
||||
@include-section["class-iop.scrbl"]
|
||||
|
|
Loading…
Reference in New Issue
Block a user