[racket-dev] [plt] Push #28823: master branch updated

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Sat May 31 10:06:14 EDT 2014

Could we please use the language of assertions here? 

We have worked hard to get people to see contracts as special
boundary-associated assertions. And it's not clear whether we
are succeeding. But if we don't use language properly, nobody
will. 






On May 30, 2014, at 10:06 PM, robby at racket-lang.org wrote:

> robby has updated `master' from 2eef2ce409 to ddb7477494.
>  http://git.racket-lang.org/plt/2eef2ce409..ddb7477494
> 
> =====[ One Commit ]=====================================================
> Directory summary:
>  70.1% pkgs/racket-pkgs/racket-doc/scribblings/reference/
>  25.1% racket/collects/racket/contract/private/
>   4.7% racket/collects/racket/contract/
> 
> ~~~~~~~~~~
> 
> ddb7477 Robby Findler <robby at racket-lang.org> 2014-05-30 21:01
> :
> | added invariant-contract
> |
> | Jay implemented this
> :
>  M racket/collects/racket/contract/private/base.rkt  | 15 ++++++--
>  M racket/collects/racket/contract/region.rkt        |  3 +-
>  M .../scribblings/reference/contracts.scrbl         | 38 ++++++++++++++++++--
> 
> =====[ Overall Diff ]===================================================
> 
> pkgs/racket-pkgs/racket-doc/scribblings/reference/contracts.scrbl
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/pkgs/racket-pkgs/racket-doc/scribblings/reference/contracts.scrbl
> +++ NEW/pkgs/racket-pkgs/racket-doc/scribblings/reference/contracts.scrbl
> @@ -6,7 +6,7 @@
> @(define contract-eval
>    (lambda ()
>      (let ([the-eval (make-base-eval)])
> -       (the-eval '(require racket/contract racket/contract/parametric))
> +       (the-eval '(require racket/contract racket/contract/parametric racket/list))
>        the-eval)))
> 
> @title[#:tag "contracts" #:style 'toc]{Contracts}
> @@ -1430,6 +1430,7 @@ inside the @racket[body] will be protected with contracts that
> blame the context of the @racket[with-contract] form for the positive
> positions and the @racket[with-contract] form for the negative ones.}
> 
> +@(define furlongs->feet-eval (contract-eval))
> @defform*[[(define/contract id contract-expr free-var-list init-value-expr)
>  (define/contract (head args) contract-expr free-var-list body ...+)]]{
> Works like @racket[define], except that the contract
> @@ -1437,7 +1438,7 @@ Works like @racket[define], except that the contract
> definition of @racket[head] and @racket[args], see @racket[define].
> For the definition of @racket[free-var-list], see @racket[with-contract].
> 
> - at examples[#:eval (contract-eval)
> + at examples[#:eval furlongs->feet-eval
>   (define/contract distance (>=/c 0) 43.52)
>   (define/contract (furlongs->feet fr)
>     (-> real? real?)
> @@ -1508,6 +1509,39 @@ The @racket[define-struct/contract] form only allows a subset of the
> (make-salmon #f 'pacific)
> ]}
> 
> + at defform[(invariant-contract contract-expr expr)]{
> +  Establishes an invariant of @racket[expr], determined by @racket[contract-expr].
> +                   
> +  Unlike other ways to attach contracts to values, an
> +  @racket[invariant-contract] does not establish a boundary
> +  between two parties. Instead, it simply puts the contract
> +  on the value, treating the module containing the 
> +  @racket[invariant-contract] expression as the party to be blamed
> +  for any violations of the contract.
> +  
> +  This means, for example, that the contract is checked on
> +  recursive calls, when an invariant is used on the right-hand
> +  side of a definition.
> +                              
> +  @examples[#:eval 
> +            furlongs->feet-eval
> +            (define furlongss->feets
> +              (invariant-contract
> +               (-> (listof real?) (listof real?))
> +               (λ (l)
> +                 (cond
> +                   [(empty? l) empty]
> +                   [else
> +                    (if (= 327 (car l))
> +                        (furlongss->feets (list "wha?"))
> +                        (cons (furlongs->feet (first l))
> +                              (furlongss->feets (rest l))))]))))
> +            
> +            (furlongss->feets (list 1 2 3))
> +            
> +            (furlongss->feets (list 1 327 3))]
> +}
> +
> @defidform[current-contract-region]{
>   Bound by @racket[define-syntax-parameter], this contains
>   information about the current contract region, used by
> 
> racket/collects/racket/contract/private/base.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/racket/collects/racket/contract/private/base.rkt
> +++ NEW/racket/collects/racket/contract/private/base.rkt
> @@ -2,9 +2,10 @@
> 
> (provide contract
>          (rename-out [-recursive-contract recursive-contract])
> -         current-contract-region)
> +         current-contract-region
> +         invariant-contract)
> 
> -(require (for-syntax racket/base syntax/name)
> +(require (for-syntax racket/base syntax/name syntax/srcloc)
>          racket/stxparam
>          syntax/srcloc
>          syntax/location
> @@ -88,6 +89,16 @@
>           (procedure-rename new-val vs-name)])]
>       [else new-val])))
> 
> +(define-syntax (invariant-contract stx)
> +  (syntax-case stx ()
> +    [(_ ctc e)
> +     (quasisyntax/loc stx
> +       (let ([me (quote-module-name)])
> +         (contract ctc e
> +                   me me
> +                   '#,(syntax-local-infer-name stx)
> +                   '#,(build-source-location-vector #'ctc))))]))
> +
> (define-syntax (-recursive-contract stx)
>   (define (do-recursive-contract arg type name)
>     (define local-name (syntax-local-infer-name stx))
> 
> racket/collects/racket/contract/region.rkt
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> --- OLD/racket/collects/racket/contract/region.rkt
> +++ NEW/racket/collects/racket/contract/region.rkt
> @@ -3,7 +3,8 @@
> (provide define-struct/contract
>          define/contract
>          with-contract
> -         current-contract-region)
> +         current-contract-region
> +         invariant-contract)
> 
> (require (for-syntax racket/base
>                      racket/struct-info



Posted on the dev mailing list.