[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
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
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.