Ivory: Numbers In Scheme

    ┌─┐ ┌──┐ ┌─┐
    │ └─┘  └─┘ │
    │ integer  │
    ├──────────┤
    │ rational │
    ├──────────┤
    │   real   │
    ├──────────┤
    │ complex  │
    ├──────────┤
    │  number  │
────┴──────────┴────
Scheme’s standard numerical tower.

Scheme uses the asterisk * for multiplication, since it’s easy to type on a standard US keyboard. I prefer the usual × symbol, for clarity. Hence we’ll define × to be *, so that both symbols will mean multiplication:

(define × *)

Numbers in Scheme can be exact or inexact. Ivory is only concerned with exact numbers, so we’ll ignore the latter. Scheme arranges its types in a “numerical tower”, where each level is a super-set of the ones above, including:

These are cumulative, so an integer like -42 is also a rational (e.g. you can think of it like -42/1), a real and a complex (like -42+0i, if you know what that means).

This basic framework is the inspiration for Ivory.

Numbers in Racket

        ┌─┐ ┌──┐ ┌─┐
        │ └─┘  └─┘ │
        │   zero   │
       ┌┴──────────┴┐
       │  natural   │
      ┌┴────────────┴┐
      │   integer    │
     ┌┴──────────────┴┐
     │    rational    │
     ├────────────────┤
     │      real      │
    ┌┴────────────────┴┐
    │     complex      │
    ├──────────────────┤
    │      number      │
────┴──────────────────┴────
Racket’s numerical tower (somewhat simplified): complex is another name for number, and real is another name for rational (for exact numbers, at least).

Racket already extends Scheme’s standard numerical tower, and pins-down some details that Scheme leaves open. In particular:

Racket does add some “attic levels”, which are strict subsets of integer:

Even more fine-grained structure is described in the Typed Racket documentation (e.g. byte is a subset of natural between 0 and 255) but Ivory does not make such size-based distinctions.

Code

This post defines Racket code, including a RackCheck test suite to check the claims we make on this page. Here’s a URI containing all of the generated code:

DOWNLOAD RACKET CODE

Test results
raco test: (submod "num.rkt" test)
  ✓ property ×-matches-* passed 100 tests.
  ✓ property integer?-implies-rational? passed 100 tests.
  ✓ property rational?-implies-number? passed 100 tests.
  ✓ property natural?-implies-integer? passed 100 tests.
  ✓ property natural-is-closed passed 100 tests.
26 tests passed