=(3scm)

πŸ“¦ version 0-unstable-2024-02, in nixpkgs unstable

🌈 = & the comparison besties ((3scm)) β€” straight from the Scheme Programmer's Manual 🌈

okay bestie, gather round πŸ’– this is the manual page for the whole number-comparing squad. You want to know if numbers are equal, going up, going down, or just vibing in a monotonic direction? This is the page. It’s giving β€œtiny predicates, huge main character energy” ✨

πŸ“› NAME πŸ“›

These are the number-comparison besties, all together: =, <, >, <=, >=, fl=?, fl<?, fl>?, fl<=?, fl>=?, fx=?, fx<?, fx>?, fx<=?, fx>=? β€” and their whole job is to compare numbers πŸ’…

πŸ“š LIBRARY πŸ“š

Import them from whichever Scheme flavor you’re living in:

(import (rnrs))                     ;R6RS
(import (rnrs base))                ;R6RS
(import (scheme r5rs))              ;R7RS
(import (scheme base))              ;R7RS
(import (rnrs arithmetic fixnums))  ;R6RS
(import (rnrs arithmetic flonums))  ;R6RS

No cap, that’s the exact import list from the page 🫢

✨ SYNOPSIS ✨

Here’s the whole call-signature lineup, character-for-character:

(= z1 z2 z3 ...)
(< x1 x2 x3 ...)
(> x1 x2 x3 ...)
(<= x1 x2 x3 ...)
(>= x1 x2 x3 ...)
(fl=? fl1 fl2 fl3 ...)
(fl<? fl1 fl2 fl3 ...)
(fl>? fl1 fl2 fl3 ...)
(fl<=? fl1 fl2 fl3 ...)
(fl>=? fl1 fl2 fl3 ...)
(fx=? fx1 fx2 fx3 ...)
(fx<? fx1 fx2 fx3 ...)
(fx>? fx1 fx2 fx3 ...)
(fx<=? fx1 fx2 fx3 ...)
(fx>=? fx1 fx2 fx3 ...)

πŸ’– DESCRIPTION πŸ’–

These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, and #f otherwise. These predicates are transitive. Translation: they don’t do messy little zigzags β€” the order has to keep the same direction, periodt πŸ’…

♾️ Infinities ♾️

Infinities are equal to themselves, bestie:

(= +inf.0 +inf.0)  =>  #t
(= -inf.0 +inf.0)  =>  #f
(= -inf.0 -inf.0)  =>  #t

For any real number object x that is neither infinite nor NaN:

(< -inf.0 x +inf.0)  =>  #t
(> +inf.0 x -inf.0)  =>  #t

🌸 NaNs 🌸

For any number object z:

(= +nan.0 z)  =>  #f

For any real number object x:

(< +nan.0 x)  =>  #f
(> +nan.0 x)  =>  #f

NaN is not out here making friends, okay 😭

🧊 Negative zero 🧊

IEEE 754 binary floating point numbers always have a sign bit. This also applies to NaNs and zero, so there is a negative zero. For the purpose of these predicates the negative zero is equal to zero.

(= 0.0 -0.0)  =>  #t
(< 0.0 -0.0)  =>  #f

Negative zero can be distinguished with eqv?(3scm). Implementations are not required to use IEEE 754 and are not required to support negative zero. So yeah β€” cute, but optional πŸŽ€

πŸ“ Inexact numbers πŸ“

While it is possible to compare inexact number objects using these predicates, the results may be unreliable because a small inaccuracy may affect the result; this is especially true of = and zero?(3cm).

Quoting the Scheme reports: β€œWhen in doubt, consult a numerical analyst.” Truly iconic advice, no notes πŸ”₯

πŸ¦‹ Flonum and fixnum variants πŸ¦‹

The flonum and fixnum variants of these predicates only operate on these types of objects. That’s it β€” they’re specialists, not generalists πŸ’…

πŸ› οΈ IMPLEMENTATION NOTES πŸ› οΈ

The traditional implementations of these predicates in Lisp-like languages are not transitive. Quoting from R7RS:

The implementation approach of converting all arguments to
inexact numbers if any argument is inexact is not transitive.
For example, let big be (expt 2 1000), and assume that big is
exact and that inexact numbers are represented by 64-bit IEEE
binary floating point numbers.  Then (= (- big 1) (inexact big))
and (= (inexact big) (+ big 1)) would both be true with this
approach, because of the limitations of IEEE representations of
large integers, whereas (= (- big 1) (+ big 1)) is false.
Converting inexact values to exact numbers that are the same (in
the sense of =) to them will avoid this problem, though special
care must be taken with infinities.

So like… the chaotic approach can lie to you. Read the quote, bestie πŸ™ˆ

🎁 RETURN VALUES 🎁

These procedures return a single value; a boolean. One value, one vibe check: #t or #f πŸ’–

🌟 EXAMPLES 🌟

(> 5 4)  =>  #t

Ate. No crumbs πŸ‘‘

πŸ”Œ COMPATIBILITY πŸ”Œ

These predicates are present in all Schemes. There are variations in which numbers are supported and what happens when they are called with bad arguments. R7RS does not require support for the whole numeric tower and R6RS does not actually require that implementations use IEEE 754, even though that is the most common implementation choice. So yes: universal squad, but the details are implementation-dependent 🌈

πŸ’€ ERRORS πŸ’€

This procedure can raise exceptions with the following condition types:

  • &assertion (R6RS) β€” the wrong number of arguments was passed or an argument was outside its domain.
  • R7RS β€” the assertions described above are errors. Implementations may signal an error, extend the procedure’s domain of definition to include such arguments, or fail catastrophically.

β€œFail catastrophically” is giving final boss energy, honestly 😭

πŸ‘€ SEE ALSO πŸ‘€

zero?(3scm), max(3scm), equal?(3scm) β€” go give those pages a little kiss too πŸ’‹

πŸ‘‘ STANDARDS πŸ‘‘

R4RS, IEEE Scheme, R5RS, R6RS, R7RS

πŸ•°οΈ HISTORY πŸ•°οΈ

These procedures only took two arguments in R3RS and did not explicitly require them to be transitive.

R2RS specified additional redundant names ending with ?, e.g., <=? in order to β€œmake all user populations happy”.

R2RS mentions that some implementations allowed many arguments like in Common Lisp, although Scheme before R2RS that ran on MacLISP also had predicates that worked like this. MacLISP’s greaterp, and lessp accepted two or more arguments. On the other hand, MacLISP also had the procedures =, >, and < that only accepted two arguments and required that the arguments are both fixnums or both flonums.

LISP 1.5 had the subroutines equal, greaterp, and lessp. The first one was the same as kind of predicate as equal?(3scm) while the latter were subroutines of two arguments that compared numbers.

History really said β€œwe’ve been comparing numbers since forever” πŸ’…

🫢 AUTHORS 🫢

This page is part of the scheme-manpages project. It includes materials from the RnRS documents. More information can be found at https://github.com/schemedoc/manpages/.


and that’s the whole page, bestie πŸ’– this little masterpiece is from the <b>Scheme Programmer’s Manual</b>, dated <b>2023-02-15</b>. Go compare responsibly 🧚✨

πŸ“¦ where this page comes from