For Development HEAD DRAFTSearch (procedure/syntax/module):

11.24 srfi.114 - Comparators

Module: srfi.114

This module is provided for the compatibility of code using SRFI-114. The new code should use SRFI-128, which is fully built-in.

Note that SRFI-114’s make-comparator has different interface from built-in (SRFI-128) make-comparator. If you simply say (use srfi.114) or (import (srfi 114)), it shadows the built-in one. If you need to use some of SRFI-114 procedures, it’s better to import them selectively.

Note that comparators created with SRFI-114 procedures are the same type as the ones created with SRFI-128 procedures and can be used interchangebly.

The following procedures are built-in. See Basic comparators, for the detailed documentation. Those are also exported from srfi.114 for the compatibility.

Predicates

comparator?,

Standard comparators

boolean-comparator, char-comparator, char-ci-comparator, string-comparator, string-ci-comparator, symbol-comparator, exact-integer-comparator, integer-comparator, rational-comparator, real-comparator, complex-comparator, number-comparator, pair-comparator, list-comparator, vector-comparator, bytevector-comparator, uvector-comparator

The default comparator

default-comparator

Wrapped equality predicates

eq-comparator, eqv-comparator, equal-comparator

Accessors

comparator-equality-predicate, comparator-comparison-procedure, comparator-hash-function

Primitive applicators

comparator-test-type, comparator-check-type, comparator-compare, comparator-hash

Comparison predicates

=?, <?, <=?, >?, >=?

Basic comparator interface

Function: make-comparator type-test equal compare hash :optional name

[SRFI-114+]{srfi.114} This is SRFI-114 style comparator constructor. The optional name argument is Gauche’s extension.

This is the same as built-in make-comparator/compare. See Basic comparators, for the details.

Do not confuse this with built-in (SRFI-128) make-comparator; if you (use srfi.114), this one shadows the built-in one.

Note that a comparator works for both SRFI-114 and SRFI-128 procedures, regardless of how it is constructed.

Function: comparator-comparison-procedure? c
Function: comparator-hash-function? c

[SRFI-114]{srfi.114} Returns true iff a comparator c can be used to order objects or to hash them, respectively. These are aliases of built-in comparator-ordered? and comparator-hashable?.

Function: comparator-type-test-procedure c

[SRFI-114]{srfi.114} Returns type test predicate of a comparator c. This is an alias of built-in comparator-type-test-predicate.

Function: comparator-equal? c a b

[SRFI-114]{srfi.114} Checks equality of a and b using the equality predicate of a comparator c. This can be also written in =?, which is built-in (see Comparator predicates and accessors).

(=? c a b)

Auxiliary comparator constructors

Function: make-inexact-real-comparator epsilon rounding nan-handling

[SRFI-114]{srfi.114} Returns a comparator for inexact real numbers, taking into account of errors and NaNs.

The basic idea is that we compare two finite real numbers after rounding them to epsilon interval, which must be a nonnegative real number. (Note that it’s not to compare two numbers “close enough”, as often being done to compare inexact numbers. “Close enough” scheme won’t be transitive.)

The rounding mode is specified by the rounding argument. It can be either one of the symbols round, ceiling, floor or truncate, or a procedure that takes two arguments, a real number and an epsilon, and returns the rounded result of the first argument according to the given epsilon.

The nan-handling argument determines how to handle the case to compare NaN and non-NaN numbers. (If both are NaNs, this comparator regards them as equal). It can be either one of the followings:

min

If it’s a symbol min, NaN is compared as smaller than all other real numbers, even than -inf.0.

max

If it’s a symbol min, NaN is compared as greater than all other real numbers, even than +inf.0.

error

If it’s a symbol error, an error is signaled.

a procedure taking one argument

The procedure is invoked with the real number which is not NaN. If it ever returns, it must return either 1, 0 or -1, for it’s used as the result of the comparison procedure of the comparator. However, since the procedure doesn’t know which argument is non-NaN, it’s hard to have consistent semantics; the best bet is to throw a custom error.

(define c (make-inexact-real-comparator 0.1 'round 'error))

(comparator-compare c 0.112 0.098) ⇒ 0
(comparator-compare c 0.131 0.172) ⇒ -1

Note: Rounding to the nearest epsilon interval would involve scaling inexact numbers, and that may reveal small difference between the actual number and its notation. For example, an inexact real number denoted as 0.15 is actually slightly smaller than 15/100, and rounding with epsilon 0.1 would result 0.1, not 0.2.

Function: make-car-comparator cmpr
Function: make-cdr-comparator cmpr

[SRFI-114]{srfi.114} Returns comparators that accept pairs, and compare them with their car or cdr by cmpr, respectively.

Using make-key-comparator, these cam be written as follows (see Combining comparators, for make-key-comparator).

(define (make-car-comparator cmpr)
  (make-key-comparator cmpr pair? car))

(define (make-cdr-comparator cmpr)
  (make-key-comparator cmpr pair? cdr))
Function: make-list-comparator element-comparator
Function: make-vector-comparator element-comparator
Function: make-bytevector-comparator element-comparator

[SRFI-114]{srfi.114} Returns a new comparator that compares lists, vectors and bytevectors element-wise using element-comparator, respectively. These are more general versions of list-comparator, vector-comparator and bytevector-comparator, which use default-comparator as element-comparator.

For a list comparator, it is an error to pass improper lists.

Note that comparing sequences of different lengths is slightly different between lists and vector/bytevectors. List comparator uses “dictionary” order, so (1 3) comes after (1 2 3), assuming elements are compared numerically. For vectors and bytevectors, shorter one always precedes the other, so #(1 3) comes before #(1 2 3).

Function: make-listwise-comparator type-test element-comparator empty? head tail

[SRFI-114]{srfi.114} More general version of make-list-comparator. Returns a comparator that compares structures which can be traversed using three procedures, empty?, head and tail. Each of those procedure receives a structure to be compared, and empty? must return #t iff the structure is empty, head must return the first element in the structure, and tail must return the same type of structure containing all the elements but the head. The type-test predicate checks if the arguments passed to the comparator to be a suitable structure.

That is, make-list-comparator can be written in make-listwise-comparator as follows.

(make-list-compartator element-comparator)
  ≡
  (make-listwise-comparator list? element-comparator null? car cdr)

This can be used to compare list-like structures. For example, the following call returns a comparator that compares elements of two lazy streams (see util.stream - Stream library).

(make-listwise-comparator stream?
                          element-comparator
                          stream-null?
                          stream-car
                          stream-cdr)
Function: make-vectorwise-comparator type-test element-comparator length ref

[SRFI-114]{srfi.114} More general version of make-vector-comparator. Returns a comparator that compares structures which can be traversed using two procedures, length and ref. The length procedure must return the number of elements in the structure. The ref procedure receives a structure and a nonnegative exact integer index k, and must return k-th element of the structure.

That is, the following equivalence holds:

(make-vector-comparator element-comparator)
  ≡
  (make-vectorwise-comparator vector? element-comparator
                              vector-length vector-ref)

(make-bytevector-comparator element-comparator)
  ≡
  (make-vectorwise-comparator u8vector? element-comparator
                              u8vector-length u8vector-ref)
Function: make-pair-comparator car-comparator cdr-comparator

[SRFI-114]{srfi.114} Creates a comparator that compares pairs, with their cars by car-comparator and their cdrs by cdr-comparator.

Function: make-improper-list-comparator element-comparator

[SRFI-114]{srfi.114} This may be understood as recursive pair comparator; if objects to be compared are pairs, we recurse their cars then their cdrs. If objects to be compared are not pairs, we use element-comparator to compare them.

Function: make-selecting-comparator comparator1 comparator2 …

[SRFI-114]{srfi.114} This creates a comparator that works any one of the given comparators; the objects to be compared are type-tested with each of the comparators in order, and the first comparator that accepts all objects will be used.

Function: make-refining-comparator comparator1 comparator2 …

[SRFI-114]{srfi.114} This is similar to make-selecting-comparator, except that if the first comparator that accepts given objects to compare finds they are equal (or 0 by the comparison procedure), it tries other comparators down the list, if any.

Function: make-reverse-comparator comparator

[SRFI-114]{srfi.114} Returns a comparator that just reverses the comparison order of comparator.

Function: make-debug-comparator comparator

[SRFI-114]{srfi.114}

Comparison procedure constructors

Function: make-comparison< lt-pred
Function: make-comparison> gt-pred
Function: make-comparison<= le-pred
Function: make-comparison>= ge-pred
Function: make-comparison=/< eq-pred lt-pred
Function: make-comparison=/> eq-pred gt-pred

[SRFI-114]{srfi.114} Utility procedures to create a comparison procedure (the one returns -1, 0, or 1) from the given predicate. For example, make-comparison< can be defined as follows:

(define (make-comparison< pred)
  (^[a b] (cond [(pred a b) -1]
                [(pred b a) 1]
                [else 0])))

Comparison syntax

Macro: if3 expr less equal greater

[SRFI-114]{srfi.114} Three-way if: Evaluates expr, and then evaluates either one of less, equal, or greater, depending on the value of expr is either less than zero, equal to zero, or greater than zero, respectively.

Macro: if=? expr consequent :optional alternate
Macro: if<? expr consequent :optional alternate
Macro: if>? expr consequent :optional alternate
Macro: if<=? expr consequent :optional alternate
Macro: if>=? expr consequent :optional alternate
Macro: if-not=? expr consequent :optional alternate

[SRFI-114]{srfi.114} Conditional evaluation according to comparison expression expr; that is, ifOP? evaluates consequent if (OP expr 0) is true, otherwise it evaluates alternate when provided.

(if<? (compare 10 20) 'yes)      ⇒ yes
(if>=? (compare 10 20) 'yes 'no) ⇒ no

Comparison predicate constructors

Function: make=? comparator
Function: make<? comparator
Function: make>? comparator
Function: make<=? comparator
Function: make>=? comparator

[SRFI-114]{srfi.114}

((make=? comparator) obj1 obj2 obj3 ...)
  ≡ (=? comparator obj1 obj2 obj3 ...)

Interval comparison predicates

Function: in-open-interval? [comparator] obj1 obj2 obj3
Function: in-closed-interval? [comparator] obj1 obj2 obj3
Function: in-open-closed-interval? [comparator] obj1 obj2 obj3
Function: in-closed-open-interval? [comparator] obj1 obj2 obj3

[SRFI-114]{srfi.114} Check if obj1, obj2 and obj3 has the following relationships:

(and (op1 obj1 obj2) (op2 obj2 obj3))

Where each of op1 and op2 can be (make<? comparator) (if that end is open), or (make<=? comparator) (if that end is closed).

When comparator is omitted, the default comparator is used.

(use srfi.42)
(list-ec (: x 0 5) (list x (in-closed-open-interval? 1 x 3)))
  ⇒ ((0 #f) (1 #t) (2 #t) (3 #f) (4 #f))

Min/max comparison procedures

comparator-min and comparator-max are the same as srfi.162. See srfi.162 - Comparator sublibrary.



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT