This is an analysis of the R5RS provision that the full numeric tower may be subsetted. Four boolean feature settings characterize different kinds of numeric towers: exactness-preserving, ratios, inexact, and complex, which refer to the closure of exact numbers under rational operations (except /), exact non-integer values, inexact rationals, and non-real numbers, respectively. A priori, any combination of these features might be implemented, except that ratios makes no sense without exactness-preserving. I also assume that complex makes no sense without either ratios or inexact: Gaussian integers by themselves seem to be of little use.
So here are ten possible numeric towers. I use + if a feature is present and - if it is absent, and give a general description of the resulting tower.
exactness-preserving |
ratios |
inexact |
complex |
Description |
- |
- |
- |
- |
A "toy" tower with fixnums (bounded exact integers) only. Possibly appropriate where no numerical work will be done. SSCM, SigScheme provide this. |
- |
- |
+ |
- |
A Scheme where all numbers are real and all arithmetic happens in essentially constant time. Chicken provides this unless you import the numbers egg. Sixx, Sizzle provide this. Most non-Lisp languages are like this, except that their fixnums wrap on overflow instead of switching to flonums, producing grossly incorrect results. |
- |
- |
+ |
+ |
The complex-number equivalent of the preceding. Non-real numbers are typically inexact/inexact. Stalin provides this. |
+ |
- |
- |
- |
Unlimited-precision integers only. Possibly usable for crypto work. Fortunately, ratios are fairly cheap given bignums. |
+ |
- |
+ |
- |
A good all-round compromise, providing exact integers and inexact real numbers. ISLisp requires this. Bigloo, Chibi, Scheme 9 provide this. Many people seem to like this tower. |
+ |
- |
+ |
+ |
The same as the preceding, but with inexact/inexact non-real numbers as well. SCM provides this. |
+ |
+ |
- |
- |
Exact rational numbers only. Dream provides this. Reasonable for some purposes, but will often run very slowly without inexact support, so unsuitable for scientific-type work. |
+ |
- |
+ |
+ |
The same as the preceding, but with exact general complex numbers. Even less suitable for scientific-type work, given that in practice non-real numbers are usually inexact/inexact. |
+ |
+ |
+ |
- |
Full numeric tower for real numbers only. Psyche provides this. |
+ |
+ |
+ |
+ |
Full numeric tower. R6RS and CL require this. Racket, Gauche, MIT, Gambit, Chicken with the numbers egg, Scheme48/scsh, Kawa, Chez, STklos provide this. Guile, SISC provide this with inexact/inexact complex numbers only. Many people seem to like this tower. |
I'd prefer to couch my reply in terms of what data types are provided by an implementation. That maps pretty well onto John's four characteristics, but it seems easier for me to think about. I'll try to match my responses to John's ++-- strings.
Of the towers John lists, the following seem worth standardizing.
The others don't seem of much interest, even though some implementors have chosen among them.
Adding complex numbers to an implementation that doesn't support them can be done almost entirely as a library module, apart from issues such as read and write syntax. Similarly, adding ratios to an implementation that supports bignums again can be done almost entirely as a library module. (Proof: Chicken's numbers library, which John references.)
I therefore think that there are three defensible core towers, namely (a) ----, (b) --+-, and (c) +-+-, along with two library modules (ratios and complexes) that may or may not happen to be imported automatically. With careful design, it ought to be possible to provide reference implementations of these modules that would work on any implementation that supports bignums/ratios or inexact reals, respectively. This would allow the implementor to have his/her cake (smaller implementation, less work), and eat it (supporting a fuller tower).
I hope that the Report can be written in such a way that this smaller number of towers is either preferred or required. This maximizes code portability, while still making it possible to build small implementations. [That basically rules out bignums without flonums. --jcowan]
If the Report does allow multiple towers (which I think is a foregone conclusion), a built-in procedure with a name something like numeric-features should be required, this will allow portable code to verify that it is running on a sufficiently-capable system. numeric-features could return a list of tower criteria that the system supports. The criteria, and their symbol names, should be defined by the Report. [My proposal at CondExpandCowan provides this at compile time rather than run time. --jcowan]