{"size": 2807, "ext": "scrbl", "max_stars_repo_path": "scribblings/signature.scrbl", "max_stars_repo_name": "thinkmoore/signature", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "scribblings/signature.scrbl", "max_issues_repo_name": "thinkmoore/signature", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "scribblings/signature.scrbl", "max_forks_repo_name": "thinkmoore/signature", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 36.9342105263, "max_line_length": 127, "alphanum_fraction": 0.6099038119}
#lang scribble/manual
@require[@for-label[signature
                    racket/base]]

@title{signature}
@author{Scott Moore}

@defmodule[signature]

Syntax classes and utilities for defining function signatures with contracts, including
an alternative syntax for indy-dependent contracts.

@defform*/subs[#:literals (: .. ->)
[(proc/c argument ... optional-rest -> result ...)]
([argument id+ctc
           (code:line keyword id+ctc)]
 [id+ctc   id-or-optional
           (id-or-optional : contract-expr)]
 [id-or-optional id
                 [id]]
 [optional-rest (code:line)
  (code:line .. id+ctc)]
 [result (id+ctc)])
]{

The @racket[proc/c] defines an indy-dependent contract like @racket[->i].  Unlike @racket[->i],
@racket[proc/c] does not require contract expressions to declare dependencies on other arguments.
Instead, it infers them automatically using the names of arguments and result values declared
in the signature. Warning: @racket[proc/c] is not currently as efficient as @racket[->i] and has a higher performance overhead.

For example, the contract:
@racketblock[(->i ([x number?]
                   [y (x) (>=/c x)])
                  [result (x y) (and/c number? (>=/c (+ x y)))])]
can be written as the following.
@racketblock[(proc/c (x : number?) (y : (>=/c x)) -> (result : (and/c number? (>=/c (+ x y)))))]

Unlike @racket[->i], mandatory and optional arguments are not specified separately.
The contract
@racketblock[(->i (#:x [x number?])
                  (#:y [y (x) (>=/c x)])
                  [result (x y) (and/c number? (>=/c (+ x y)))])]
can be written as the following.
@racketblock[(proc/c #:x (x : number?) #:y ([y] : (>=/c x)) -> (result : (and/c number? (>=/c (+ x y)))))]

Like @racket[->i], the contract expressions are not always evaluated in
order. If there are optional arguments that are not supplied, then
the corresponding variables will be bound to a special value
called @racket[the-unsupplied-arg] value.
}

@defform*/subs[#:literals (: ..)
[(define/sig (id argument ... optional-rest -> result ...)
   body ...)]
([argument id+ctc
           (code:line keyword id+ctc)]
 [id+ctc   id-or-optional/default
           (id-or-optional : contract-expr)]
 [id-or-optional/default id
                 [id default-expr]]
 [optional-rest (code:line)
  (code:line .. id+ctc)]
 [result (id+ctc)])
]{

Defines a procedure with the given signature and applies the corresponding contract.

For example,
@racketblock[(define/sig (add #:x (x : number?) #:y ([y x] : (>=/c x)) -> (result : (and/c number? (>=/c (+ x y)))))
               (+ x y))]
is equivalent to the following.
@racketblock[(define/contract (add #:x x #:y [y x])
               (proc/c (#:x (x : number?) #:y ([y] : (>=/c x))) -> (result : (and/c number? (>=/c (+ x y)))))
               (+ x y))]
}
