c(a|d)ⁿr
car, cdr, caaaaddddr, and everything in between.
(require cadnr) | package: cadnr |
This module extends a number of built-in Racket functions that have obvious arbitrary extensions.
For instance, the caaaar–cddddr family of functions are defined for all combinations of a-s and d-s, but only up to four! The obvious extension is to allow for an arbitrary number of each, and to simply generate them on the fly when they are referred to.
With this module required, it’s possible to use these functions just by naming them:
> (caddddddddddr '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)) 11
> (succcccc 1) 6
> (sub1234 5678) 4444
> twenty-million-six-hundred-and-forty-one-thousand-six-hundred-and-ninety 20641690
syntax
(#%top . id)
Pattern matches id to see if it matches one of the c(a|d)ⁿr patterns below. If one of them matches, the expression expands to an expression as described, otherwise it expands to the #%top from racket/base.
The patterns are as follows:
#px"c([ad]+)r" (e.g. caaaaaaddddr, cdaddadar)
Extensions of the built-in caaaar–cddddr family, to an arbitrary number of as and ds.
Each new a or d corresponds to another car or cdr respectively, in composition order (so the last a or d is applied first, then the others from right to left).
Examples:> (cadaaaaar '(((((((1) 2) 3) 4) 5) 6) 7)) 2
> (cadaddr '((a b) (c d) (e f) (g h))) 'f
#px"([frn]*)(first|rest|next)" (e.g. fffirst, frest, nfnext)
Analogous to the previous pattern, but uses first and rest instead of car and cdr, so that these can only be used with proper lists.
The naming of these is inspired by the similar family of functions in Clojure.
Examples:> (fnfffffirst '(((((((1) 2) 3) 4) 5) 6) 7)) 2
> (fnfnnext '((a b) (c d) (e f) (g h))) 'f
#px"suc(c*)" (e.g. suc, succ, succcccccc)
Extensions of the successor function (called add1 in Racket).
Each c adds one more to the number, starting at 0 with just one (so suc is the identity on numbers, and succ is equivalent to add1).
Examples:> (suc 10) 10
> (succccccccc 1) 9
#px"pre(d+)" (e.g. pred, predddd)
Extensions of the predecessor function (called sub1 in Racket).
Each d subtracts one more from the number, starting at 1 with just one (so pred is equivalent to sub1).
Examples:> (pred 10) 9
> (predddddddd 100) 92
#px"add(\\d+)" (e.g. add123, add37949)
Extensions of add1, but for any natural number.
Examples:> (add256 10) 266
> (map add64 '(1 2 5 10 32)) '(65 66 69 74 96)
#px"sub(\\d+)" (e.g. sub123, sub37949)
Extensions of sub1, but for any natural number.
Examples:> (sub256 500) 244
> (map sub64 '(1 2 5 10 32)) '(-63 -62 -59 -54 -32)
number (e.g. five, five-hundred-and-twelve)
An English-language number.
The syntax includes English numbers from zero to one thousand, as well as large numbers in short-scale up to the centillions. Furthermore, you can write the names of years out in words too, in either British or American English.
Examples:number? (e.g. five?, nine-hundred-and-ninety-nine?)
Extensions of zero?.
Examples:numberth (e.g. twentieth, fifty-fifth)
Extensions of first–fifteenth, finally future-proofing RacketCon.
Examples:> (twentieth RacketCon) '(RacketCon 2030)
> (nine-hundred-and-ninety-ninth RacketCon) '(RacketCon 3009)
> (define letters (string->list "abcdefghijklmnopqrstuvwxyz")) > (twenty-third letters) #\w
type-numberth, type-last, type-empty? non-empty-type? (e.g. flvector-fifteenth)
Extensions of racket/list and non-empty-string? for arbitrary container types.
These work by referencing bindings derived from type. As such, a binding for type? must be in scope, in addition to:
For type-numberth: type-ref
For type-last: type-ref and type-length
For type-empty? and non-empty-type?: type-length
Examples:> (sequence-twenty-second (in-naturals 1)) 22
> (sequence-sixty-fifth (sequence-map integer->char (in-naturals 1))) #\A
> (string-tenth "abcdefghijklmnopqrstuvwxyz") #\j
> (vector-last (vector 1 2 3)) 3
> (non-empty-list? null) #f
> stream-fifth stream-fifth: undefined;
cannot reference an identifier before its definition
in module: top-level
> (require racket/stream) > (stream-fifth (stream 1 2 3 4 5 6)) 5
> (require racket/flonum) > (flvector-empty? (flvector)) #t
1 Composable c(a|d)ⁿr
(require cadnr/defaults) | package: cadnr |
syntax
(define-default-cadnr-top new-top old-top)
This is included for composability reasons, so as not to introduce conflicts with other modules that override the binding of #%top the way cadnr does.