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

Re: Common Lisp solved this problem 20 years ago



Taylor Campbell wrote:
Coercion to integers of a given modulus, for
example, from other integers, is accomplished with a procedure we
already have in R5RS, namely MODULO;

Not the same.  The coercion creates a value with a different run-time
type, such that the generic + operator uses modulo arithmetic.

   Neither: it's not the operations that change: It's the
   operand that changes.  The operation + is already defined so that
   if the operands are IEEE 64-bit *values* then we use 64-bit flonum
   flonum addition etc.  But's that's the way R5RS already works - we're
   just being more precise and allowing for more data types.

Why would it not be perfectly allowable for, say, the * procedure to
return a 128-bit flonum when given two 64-bit flonums?

Does that make any sense?  A more meaningful example would be
multiplying to 64-bit fixnum (modulo-64) integers to yield a 128-bit
result.

Similarly,
why would you not specify that you want IEEE 64-bit flonum arithmetic
using an explicit IEEE 64-bit flonum operation, like IEEE-FLO64*, to
clearly indicate this in the program?

First, its more verbose.  But more importantly, if you change the
representation of a variable then you have to check and possibly change
every place in the program that references the variable.  I.e. it's
more error-prone, hurts modularity, and hurts maintainance.

   The declarations coerce to an appropriate data type.
   I.e. you coerce an integer to a (modulo-int N), and arithmetic
   on the (modulo-int N) *type* is defined to be modular.

So are you saying that the 'type declaration' really *does* affect the
semantics of the operations on the integer objects?   I'm not quite
clear on how you can otherwise signify that some integer is 'modular'
in a way that the + operator can distinguish by run-time tag; integers
are integers.

Conceptually, there *is* a separate run-time tag.  We have an extensible
type system with records, so we're not limited to a finite set of tags.

I.e. a modulo-N value can be converted to/from integers, but it is not
a (regular-old) integer.

Now the compiler as an optimization can and should "unbox" the values
and generate machine arithmetic without tags.

Note I'm not saying my proposal is the "right" approach nor am I pushing
it for R6RS.  However, I think it is consistent, and has a number of
advantages: it is (at least partly) implemented, is fairly readable and
compact, generates good code using simple type-propagation, and is
useful for documentation and catching errors.
--
	--Per Bothner
per@xxxxxxxxxxx   http://per.bothner.com/