[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

number syntax and exactness



I have been moderately concerned for some time that Scheme's external
representation for numbers was "gratuitously incompatible" with that
of Common Lisp.  My worry was that people attempting to use both
languages would trip over minor differences.  This might be a small
annoyance when interacting directly with the user at the keyboard but
possibly a major problem when trying to share files containing numeric
data.

In retrospect, I have decided that the problem is probably not as bad
as I feared.  Many incompatibilities, like the representation of
complex numbers, can be handled by suitably extending the reader for
each language to understand the other's syntax.  And I'm persuaded
that 3+4i is a worthwhile improvement over #c(3 4).

I still feel that we should talk through the differences between the
two, however, and see if we can iron out some of them.  Rather than
make a specific proposal, this message outlines the differences I'm
aware of and suggests possible actions we could take.  I'll plan to
make a proposal for discussion at the meeting, but first I want to
hear your reactions to these thoughts.

    (1) Complex numbers in Scheme look like 3+4i; in Common Lisp they
	look like #c(3 4).

Neither notation causes an ambiguity in the standard reader for either
language, so I'm amenable to leaving it as an optional extension in
each language to support the syntax of the other.

    (2) The + or - sign in Scheme precedes everything else in a real
	number; in Common Lisp the sign may be preceded by a radix indicator.
	Common Lisp does not have the #D (decimal) indicator but has a
	general purpose #nnR indicator.

Allowing the radix indicator and sign to appear in either order seems
to be a reasonable extension for both languages.

#D and #nnR do not cause ambiguities, so each could be considered an
extension to the language of the other.

    (3) Scheme separates the concept of exactness from type; Common
	Lisp does not.

This is an advantage for Scheme, although the full ramifications
haven't been felt yet.  I don't understand how to make exactness
orthogonal to precision, however (see point 4).  What does
#e#s123456789 mean if an implementation can't represent the value
123456789 exactly in a short FLONUM?

    (4) Scheme specifies the precision of a real number using #S
	(short) or #L (long); Common Lisp specifies the precision of a
	floating point number with an <exponent-marker> of S, F, D, or
	L (for Short, Single, Double, and Long).  The Scheme syntax in
	7.1.1 allows a precision specification for rational numbers;
	Common Lisp does not.

In Common Lisp, precision is an attribute of (inexact) FLONUMs only.
The last paragraph of 6.5.3 of R3RS says essentially the same thing,
clarifying the syntax in 7.1.1.  This seems inconsistent to me,
though, since it relates "precision" to the FLONUM representation type
whereas I see "precision" as an attribute of "inexactness."  If we can
speak of inexact integers, then we should perhaps be able to speak of
short or long ones without requiring that they be implemented as
FLONUMs.

What might be meant in Scheme by a "short integer" like #s123456789?
Surely we don't mean that the number is to be arbitrarily truncated to
a machine-specific fixnum, since that may produce a result which loses
all significance in the number.  The only interpretation that makes
sense to me is that #S and #L specify that the number is inexact and
may be stored in a fixed number of bits in a way that preserves the
significant digits as well as it can.  Floating point is one such
representation but others exist and may be more suitable for those
implementations not blessed (?) by good FLONUM support.

I see two alternatives.  We could tie the specification of precision
to FLONUMs only, as we do now, or we could relate precision to exactness.
I prefer the latter.

One way would be to merge the productions for <precision> and <exactness> in
7.1.1 to give

    <precision> --> <empty> | #E | #S | #L | #I

where #E specifies an exact number, #I an inexact number of default
precision, #S and #L inexact numbers of (possibly) differing
precision, and <empty> leaving the exactness to the discretion of the
implementation, except that integers expressed without decimal points
or exponent notation are assumed exact.

This is an upwardly compatible liberalization of R3RS.

Another way, which I prefer, is to kill three birds with one stone and
use the exponent marker to indicate exactness and precision as well as
scale.  Suppose we took Common Lisp's S (short), F (single), D
(double) and L (long) exponent markers and interpreted them
essentially as Common Lisp does.  That is, all denote inexactness as
well as specifying precision.  However, Scheme does not require
numbers written with exponent notation to be FLONUMs as Common Lisp
does, so we are free to represent 7.5s3 as the inexact integer 7500 if
we want.

Common Lisp uses the E exponent marker for the default FLONUM
precision.  We could do the same but it would be incompatible with
R3RS for E to imply inexactness.  We could instead use E to specify
exact numbers, at the expense of compatibility with Common Lisp.

    (5) #S denotes a short precision number in Scheme and a structure
	object in Common Lisp.

This can be lived with.  However, it is the only conflict I can think
of between the two languages in the use of dispatching macro characters.

If we were to choose to allow precision to be specified via exponent
markers, the #S notation would no longer be needed in Scheme.

    (6) Scheme specifies that `#' is printed rather than a digit when
	the format calls for more digits than are internally represented.  
	Common Lisp does not address this issue, although some
	implementations use the digit `0' in this case.

This seems to be a relatively harmless discrepancy, although I can
imagine a Common Lisp reader choking up a bit.

    (7) Scheme allows ratios to have exponents; Common Lisp does not.

It's their loss, I guess.

----

Summary: Let's clean up the exactness/precision problem and try to
free up #S.

--db--