1 Untyped Utilities
1.1 Comparison Predicate Generation
See also typed/alexis/util/comparator for Typed Racket-compatible forms.
|maybe-adapter|| ||=|| |
| || ||||| ||#:adapter adapter-expr|
This provides a convenient macro for generating comparison predicates based on a "comparator"
function. The provided comparator-expr must evaluate to a function which takes two values and
produces either 0, 1, or -1. These values correspond to both parameters
being equal, the first parameter being greater, or the second parameter being greater, respectively.
Using this function, a set of functions is generated using predicate-base-id as a base
identifer to determine the names of the resulting definitions. This macro produces six functions,
their names acquired by appending =?, >?, <?, <>?, >=?,
and <=? to predicate-base-id.
If adapter-expr is provided, then it must evaluate to a function that takes a single
parameter and returns a single value. If specified, values will be threaded through
adapter-expr before being passed to comparator-expr. This allows values to
be mapped to other values before being provided to the comparator for additional processing or
|> (struct num-str (num str))|
|> (define (num-str-compare a b)|
| (if (= (num-str-num a) (num-str-num b))|
| (let ([a (num-str-str a)]|
| [b (num-str-str b)])|
| [(string>? a b) 1]|
| [(string<? a b) -1]|
| [else 0]))|
| (let ([a (num-str-num a)]|
| [b (num-str-num b)])|
| [(> a b) 1]|
| [(< a b) -1]|
| [else 0]))))|
|> (num-str=? '(123 . "abc") '(123 . "abc"))|
|> (num-str<? '(200 . "aaa") '(100 . "aaa"))|
1.2 Struct Utilities
1.2.1 Purely Functional Struct Updaters
Racket provides hash-set and hash-update as purely functional ways to modify
hashtables without mutation. This provides similar functionality for structures.
Given the name of a struct via struct-id, this form generates functional setter and updater
functions for each field of the struct. Functions are only generated for the non-inherited fields for
the provided struct; a supertype’s fields are ignored.
Two functions are generated for each field. Their names are generated by appending -set and
-update onto each of the accessor functions, and they are unhygienically introduced with the
lexical context of struct-id. Each setter function is of the type
(-> struct-id? any/c struct-id?). Each updater function is of the type
(-> struct-id? (-> any/c any/c) struct-id?). The generated functions have contracts attached
to them which ensure that the proper values are recieved.
1.2.2 Extracting struct accessors
Extracts the fields belonging to a struct, not including its supertypes. The first value returned
includes all accessors, the second value is just the struct’s fields.
This function is provided for-syntax.
1.3 Wrapping keyword procedures
It’s easy to "wrap" existing procedures in order to extend them with additional functionality. For
example, the following wraps + to additionally call add1 on the result:
This is much harder to do, however, if the procedure being wrapped can accept keyword arguments, since
they are not accepted in the "rest argument" syntax. Instead, make-keyword-procedure and
keyword-apply must be used. This module provides some macros to make wrapping these
Creates a new procedure that wraps original-proc-expr. Each application
of the resulting procedure calls original-proc-expr with the provided
arguments and binds result-id to the result, which is available to the
body-exprs. The return value of the resulting procedure is the result of
the final body-expr.
|> (check-duplicates+add1 #:key positive? '(1 1))|
|(define/wrapped name-id [result-id original-proc-expr]|
| body-expr ...+)|