arity+keywords.scrbl (6433B)
1 #lang scribble/manual 2 @(require kw-utils/arity+keywords 3 racket/base 4 scribble/eval 5 (for-label kw-utils/arity+keywords 6 kw-utils/arity+keywords/syntax 7 racket/base 8 racket/contract/base 9 racket/function 10 )) 11 12 @title[#:tag "arity+keywords.scrbl"]{arity+keywords} 13 14 @section{Procedure arities with keywords} 15 16 @defmodule[kw-utils/arity+keywords] 17 18 @defstruct*[arity+keywords ([arity procedure-arity?] 19 [required-kws (listof keyword?)] 20 [allowed-kws (or/c (listof keyword?) #f)]) 21 #:transparent]{ 22 represents a procedure's arity including the keywords required and keywords allowed. 23 24 The @racket[arity] field represents the arity produced by @racket[procedure-arity]. 25 26 The next 2 fields (@racket[required-kws] and @racket[allowed-kws]) represent the 2 values produced by 27 @racket[procedure-keywords]. 28 29 A @racket[#f] value for @racket[allowed-kws] means that it accepts all keywords. 30 31 The guard procedure also sorts the keyword lists for you. 32 } 33 34 @defproc[(procedure-arity+keywords [proc procedure?]) arity+keywords?]{ 35 returns an @racket[arity+keywords] instance representing the arity and keyword-arity of @racket[proc]. 36 37 It is defined like this: 38 @(racketblock 39 (define (procedure-arity+keywords proc) 40 (define arity (procedure-arity proc)) 41 (define-values (req-kws allowed-kws) 42 (procedure-keywords proc)) 43 (arity+keywords arity req-kws allowed-kws))) 44 45 @examples[ 46 (require kw-utils/arity+keywords) 47 (define proc (make-keyword-procedure void)) 48 (procedure-arity+keywords proc) 49 (procedure-arity+keywords (procedure-reduce-arity proc 5)) 50 (procedure-arity+keywords 51 (procedure-reduce-keyword-arity/sort proc 3 '(#:kw #:other-kw) '(#:kw #:other-kw #:optional-kw))) 52 ]} 53 54 @defproc[(procedure-reduce-arity+keywords [proc procedure?] [arity+kws arity+keywords?]) procedure?]{ 55 like @racket[procedure-reduce-arity], except that it accepts an @racket[arity+keywords] and handles 56 the keyword-arity as well. 57 58 It is defined like this: 59 @(racketblock 60 (define (procedure-reduce-arity+keywords proc a) 61 (procedure-reduce-keyword-arity 62 proc 63 (arity+keywords-arity a) 64 (arity+keywords-required-kws a) 65 (arity+keywords-allowed-kws a)))) 66 67 @examples[ 68 (require kw-utils/arity+keywords) 69 (define proc (make-keyword-procedure void)) 70 (procedure-arity proc) 71 (procedure-keywords proc) 72 (define proc-with-arity 73 (procedure-reduce-arity+keywords 74 proc 75 (arity+keywords 5 '(#:kw #:other-kw) '(#:kw #:other-kw #:optional-kw)))) 76 (procedure-arity proc-with-arity) 77 (procedure-keywords proc-with-arity) 78 ]} 79 80 @defproc[(procedure-reduce-keyword-arity/sort [proc procedure?] 81 [arity procedure-arity?] 82 [required-kws (listof keyword?)] 83 [allowed-kws (or/c (listof keyword?) #f)]) 84 procedure?]{ 85 like @racket[procedure-reduce-keyword-arity], but without the constraint that the keywords in 86 @racket[required-kws] or @racket[allowed-kws] must be sorted. 87 88 It is equivalent to 89 @racket[(procedure-reduce-arity+keywords proc (arity+keywords arity required-kws allowed-kws))]. 90 } 91 92 @defproc[(arity+keywords-matches? [arity+kws arity+keywords?] 93 [n natural-number/c] 94 [kws (listof keyword?)]) 95 boolean?]{ 96 determines whether the given @racket[arity+kws] accepts the @racket[n] by-position arguments and the 97 keywords in @racket[kws]. 98 } 99 100 @defproc[(procedure-arity+keywords-matches? [proc procedure?] 101 [n natural-number/c] 102 [kws (listof keyword?)]) 103 boolean?]{ 104 equivalent to @racket[(arity+keywords-matches? (procedure-arity+keywords proc) n kws)]. 105 } 106 107 @defproc[(procedure-arity+keywords-matches?/c [n natural-number/c] 108 [kws (listof keyword?)]) 109 flat-contract?]{ 110 produces a flat contract (also a predicate) that accepts procedures that accept @racket[n] by-position 111 arguments and accepts the keywords in @racket[kws]. 112 } 113 114 @defproc[(arity+keywords-includes? [a1 arity+keywords?] [a2 arity+keywords?]) boolean?]{ 115 like @racket[arity-includes?], but for @racket[arity+keywords] instances. But most of the time when 116 when you would use @racket[arity-includes?], you really want @racket[arity+keywords-matches?]. 117 } 118 119 @defproc[(arity+keywords-combine/or [arity+kws arity+keywords?] ...) arity+keywords?]{ 120 combines the @racket[arity+kws]es into one @racket[arity+keywords] instance in an or-like way. 121 122 @examples[ 123 (require kw-utils/arity+keywords) 124 (arity+keywords-combine/or (arity+keywords 1 '(#:a) '(#:a #:b #:c)) 125 (arity+keywords 2 '(#:a #:b) '(#:a #:b #:d))) 126 ]} 127 128 @defproc[(arity+keywords-combine/and [arity+kws arity+keywords?] ...) arity+keywords?]{ 129 combines the @racket[arity+kws]es into one @racket[arity+keywords] instance in an and-like way. 130 131 @examples[ 132 (require kw-utils/arity+keywords) 133 (arity+keywords-combine/and (arity+keywords '(1 2) '(#:a) '(#:a #:b #:c #:d)) 134 (arity+keywords '(2 3) '(#:b) '(#:a #:b #:c #:e))) 135 ]} 136 137 @section{Getting the arity from function arguments syntax} 138 139 @defmodule[kw-utils/arity+keywords/syntax] 140 141 @defproc[(kw-formals->arity+keywords [fmls-stx syntax?]) arity+keywords?]{ 142 Given the @racket[args] in @racket[(lambda args body)], returns an 143 @racket[arity+keywords] value representing the arity and keywords of 144 the function. 145 146 @examples[ 147 (require kw-utils/arity+keywords/syntax) 148 (kw-formals->arity+keywords #'()) 149 (kw-formals->arity+keywords #'(a b c)) 150 (kw-formals->arity+keywords #'(a b [c 2])) 151 (kw-formals->arity+keywords #'(a b . rst)) 152 (kw-formals->arity+keywords #'(a #:b b)) 153 (kw-formals->arity+keywords #'(a #:b [b 1])) 154 (kw-formals->arity+keywords #'(#:a a . rst)) 155 ]} 156 157 @deftogether[[ 158 @defproc[(kw-formals->arity [fmls-stx syntax?]) normalized-arity?] 159 @defproc[(kw-formals->required-kws [fmls-stx syntax?]) (listof keyword?)] 160 @defproc[(kw-formals->allowed-kws [fmls-stx syntax?]) (listof keyword?)] 161 ]]{ 162 Like @racket[kw-formals->arity+keywords], but just for the positional-argument 163 arity, required keywords, and allowed keywords. 164 } 165