/racket-5-0-2-bin-i386-osx-mac-dmg/collects/unstable/scribblings/poly-c.scrbl

http://github.com/smorin/f4f.arc · Racket · 95 lines · 73 code · 22 blank · 0 comment · 5 complexity · 19aabc6a2b28de4a8934a70ba0ebc83e MD5 · raw file

  1. #lang scribble/manual
  2. @(require scribble/eval
  3. "utils.rkt"
  4. (for-label unstable/poly-c
  5. racket/contract
  6. racket/base))
  7. @title[#:tag "poly-c"]{Polymorphic Contracts}
  8. @(define (build-eval)
  9. (let* ([e (make-base-eval)])
  10. (e '(require unstable/poly-c racket/contract))
  11. e))
  12. @defmodule[unstable/poly-c]
  13. @unstable[@author+email["Sam Tobin-Hochstadt" "samth@ccs.neu.edu"]
  14. @author+email["Carl Eastlund" "cce@ccs.neu.edu"]]
  15. @defform[(poly/c (x ...) c)]{
  16. Creates a contract for polymorphic functions that may inspect their arguments.
  17. Each function is protected by @racket[c], where each @racket[x] is bound in
  18. @racket[c] and refers to a polymorphic type that is instantiated each time the
  19. function is applied.
  20. At each application of a function, the @racket[poly/c] contract constructs a new
  21. weak, @racket[eq?]-based hash table for each @racket[x]. Values flowing into
  22. the polymorphic function (i.e. values protected by some @racket[x] in negative
  23. position with respect to @racket[poly/c]) are stored in the hash table. Values
  24. flowing out of the polymorphic function (i.e. protected by some @racket[x] in
  25. positive position with respect to @racket[poly/c]) are checked for their
  26. presence in the hash table. If they are present, they are returned; otherwise,
  27. a contract violation is signalled.
  28. @examples[#:eval (build-eval)
  29. (define/contract (check x y) (poly/c [X] (boolean? X . -> . X))
  30. (if (or (not x) (equal? y 'surprise))
  31. 'invalid
  32. y))
  33. (check #t 'ok)
  34. (check #f 'ignored)
  35. (check #t 'surprise)
  36. ]
  37. }
  38. @defform[(parametric/c (x ...) c)]{
  39. Creates a contract for parametric polymorphic functions. Each function is
  40. protected by @racket[c], where each @racket[x] is bound in @racket[c] and refers
  41. to a polymorphic type that is instantiated each time the function is applied.
  42. At each application of a function, the @racket[parametric/c] contract constructs
  43. a new opaque wrapper for each @racket[x]; values flowing into the polymorphic
  44. function (i.e. values protected by some @racket[x] in negative position with
  45. respect to @racket[parametric/c]) are wrapped in the corresponding opaque
  46. wrapper. Values flowing out of the polymorphic function (i.e. values protected
  47. by some @racket[x] in positive position with respect to @racket[parametric/c])
  48. are checked for the appropriate wrapper. If they have it, they are unwrapped;
  49. if they do not, a contract violation is signalled.
  50. @examples[#:eval (build-eval)
  51. (define/contract (check x y) (parametric/c [X] (boolean? X . -> . X))
  52. (if (or (not x) (equal? y 'surprise))
  53. 'invalid
  54. y))
  55. (check #t 'ok)
  56. (check #f 'ignored)
  57. (check #t 'surprise)
  58. ]
  59. }
  60. @defproc[(memory/c [positive? boolean?] [name any/c]) contract?]{
  61. This function constructs a contract that records values flowing in one direction
  62. in a fresh, weak hash table, and looks up values flowing in the other direction,
  63. signalling a contract violation if those values are not in the table.
  64. If @racket[positive?] is true, values in positive position get stored and values
  65. in negative position are checked. Otherwise, the reverse happens.
  66. }
  67. @defproc[(opaque/c [positive? boolean?] [name any/c]) contract?]{
  68. This function constructs a contract that wraps values flowing in one direction
  69. in a unique, opaque wrapper, and unwraps values flowing in the other direction,
  70. signalling a contract violation if those values are not wrapped.
  71. If @racket[positive?] is true, values in positive position get wrapped and
  72. values in negative position get unwrapped. Otherwise, the reverse happens.
  73. }