summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Daphne Preston-Kendal 2021-03-31 16:37:33 +0000
committerGravatar Daphne Preston-Kendal 2021-03-31 16:37:33 +0000
commit6786749cea12d1b93ed8210f8b82585ed6dac5c6 (patch)
treee17abb18d0c8a716a99aa12a7beaccf4940b9107
Initial commit
-rw-r--r--composing-comparators.md85
1 files changed, 85 insertions, 0 deletions
diff --git a/composing-comparators.md b/composing-comparators.md
new file mode 100644
index 0000000..530c8d5
--- /dev/null
+++ b/composing-comparators.md
@@ -0,0 +1,85 @@
+# Primitives for Composing Comparators
+
+## Specification
+
+### `(make-box-comparator type-test unboxer contents-comparator)` (Procedure)
+
+Returns a comparator which compares values satisfying the predicate `type-test` by first calling the given `unboxer` procedure on them, then comparing the output of that procedure with the given `contents-comparator.` The hash function of the box comparator returns the same value as the `contents-comparator` run on the unboxed value.
+
+### `(make-composed-comparator type-test comparator ...)` (Procedure)
+
+Returns a comparator which compares values satisfying the given predicate `type-test` by comparing them with each of the given comparators in turn, left to right, and returning the result of the first non-equal comparison. If all the given comparators consider two values equal, the composed comparator also considers them equal. The hash function of the composed comparator hashes together the results of all the given comparators in an implementation-defined way.
+
+### `(compose-comparator type-test (unboxer comparator) ...)` (Syntax)
+
+Expands to a form which returns a comparator which compares values satisfying the given predicate `type-test` by running in turn, left to right, box comparators made out of the given `unboxer` and `comparator`, according to the rules for `make-composed-comparator`. `comparator` may be omitted from each form, in which case the SERFI 128 default comparator is used.
+
+This is equivalent to using the procedural forms `make-composed-comparator` and `make-box-comparator` together, but can be slightly more efficient because it only needs to run the given `type-test` predicate once, whereas composing a number of `make-box-comparator`s would run each box comparator’s type test once for each comparator in the composed comparator.
+
+## Examples
+
+`make-pair-comparator` from SRFI 128 can be implemented in terms of this library as follows:
+
+```scheme
+(define (make-pair-comparator car-comparator cdr-comparator)
+ (compose-comparator pair? (car car-comparator) (cdr cdr-comparator)))
+```
+
+If one has defined a date record type consisting of year, month, and day fields such as:
+
+```scheme
+(define-record-type <date>
+ (make-date year month day)
+ date?
+ (year date-year)
+ (month date-month)
+ (day date-day))
+```
+
+these can be correctly compared by a comparator defined by:
+
+```scheme
+(compose-comparator date?
+ (date-year) ;; Equivalent to (date-year (make-default-comparator))
+ (date-month)
+ (date-day))
+```
+
+More advanced use is also possible, such as with SRFI 209 enums:
+
+```scheme
+(define flavours (make-enum-type '(vanilla chocolate strawberry)))
+(define toppings (make-enum-type '(golden-syrup
+ strawberry-syrup
+ chocolate-sprinkles
+ rainbow-sprinkles
+ fudge)))
+
+(define flavour-comparator (make-enum-comparator flavours))
+(define topping-comparator (make-enum-comparator toppings))
+
+(define-record-type <ice-cream>
+ (make-ice-cream flavour toppings price)
+ ice-cream?
+ (flavour ice-cream-flavour)
+ (toppings ice-cream-toppings)
+ (price ice-cream-price))
+
+;; e.g.
+(make-ice-cream (enum-name->enum 'strawberry)
+ (map enum-name->enum '(golden-syrup chocolate-sprinkles))
+ 4.50)
+
+;; Sorts ice creams by price, then by flavour, then by their list of toppings.
+(define ice-cream-comparator
+ (compose-comparator ice-cream?
+ (ice-cream-price)
+ (ice-cream-flavour flavour-comparator)
+ (ice-cream-toppings
+ (make-list-comparator
+ topping-comparator
+ (lambda (x) (and (list? x) (all enum? x)))
+ null? car cdr))))
+```
+
+(This perhaps shows that `make-list-comparator` could also do with some convenience wrapper for when the last three arguments are known to be `null?`, `car`, and `cdr`.)
> 2003-04-23add libtoolize to bootstrapGravatar ddennedy 1-1/+10 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@107 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-04-21added Dan Maas' rawiso docsGravatar ddennedy 1-32/+295 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@106 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-04-07new_handle_on_port() error path fix from Jim RadfordGravatar dmaas 1-1/+3 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@105 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-03-26add raw1394_new_handle_on_port() convenience functionGravatar dmaas 2-1/+41 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@104 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-02-22Updates for new rawiso ioctl interface.Gravatar bencollins 3-37/+125 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@103 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-01-15add iso_xmit_sync() and iso_xmit_write(); clean up iso handling a bitGravatar dmaas 5-39/+161 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@102 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-01-15implement tag matching for rawiso receptionGravatar dmaas 3-4/+12 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@101 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-01-06back out previous commit - don't drop the legacy API just yetGravatar dmaas 6-173/+130 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@100 53a565d1-3bb7-0310-b661-cf11e63c67ab 2003-01-05emulate legacy ISO reception API on top of new rawiso APIGravatar dmaas 7-131/+174 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@99 53a565d1-3bb7-0310-b661-cf11e63c67ab 2002-12-24update iso API for multi-channel reception and new packet buffer layoutGravatar dmaas 4-123/+236 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@98 53a565d1-3bb7-0310-b661-cf11e63c67ab 2002-12-20oops, irq_interval needs to be signedGravatar anonymous 1-1/+1 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@97 53a565d1-3bb7-0310-b661-cf11e63c67ab 2002-12-20dmaas - renamed exported arm definitions into the raw1394_ namespace; ↵Gravatar anonymous 3-124/+48 brought kernel-raw1394.h back in sync with the kernel version git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@96 53a565d1-3bb7-0310-b661-cf11e63c67ab 2002-12-16rawiso updates:Gravatar dmaas 3-18/+25 - changed return type of rawiso xmit/recv handlers from int to enum raw1394_iso_disposition - added an ioctl (RAW1394_ISO_QUEUE_ACTIVITY) to force an ISO_ACTIVITY event into the queue. This is needed for handling RAW1394_ISO_DEFER, to kick us out of the next read() instead of sleeping forever. - removed references to "8-byte" isochronous header - this is an OHCI-specific implementation detail git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@95 53a565d1-3bb7-0310-b661-cf11e63c67ab 2002-11-18fix cplusplus extern C blockGravatar ddennedy 1-4/+4 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@94 53a565d1-3bb7-0310-b661-cf11e63c67ab 2002-11-18merged rawiso branchGravatar ddennedy 7-6/+488 git-svn-id: svn://svn.linux1394.org/libraw1394/trunk@93 53a565d1-3bb7-0310-b661-cf11e63c67ab