SRFI 77 specifies two classes of operations on fixnums: operations
which perform modulo arithmetic (with fixnumXXX names), and those
which signal an error on overflow (with fxXXX names). This naming
convention is obscure because nothing in the name helps distinguish
the two classes of operations. Why not be explicit and say
(fxring+ x y) for the version which implement arithmetic on a
quotient ring of the integers,
and
(fx+ x y) for the version which returns the same result as (+ x
y) as long as x, y and x+y are fixnums.
There is a high degree of duplication of functionality among the
fixnum operations. Take for example,
(fixnum= X Y Z) which is identical to (fx= X Y Z)
There is also duplication in
fx<, fx>, fx<=, fx>=, fxzero?, fxpositive?, fxnegative?, fxodd?,
fxeven?, fxmax, fxmin, fxnot, fxif, and so on...
What is the rationale for all this duplication? Is there some subtle
difference in semantics I'm missing? When should the fixnumXXX
version be preferred over the fxXXX version?
There are relatively few fixnum operations where it makes sense to
have a version which implements arithmetic on a quotient ring of the
integers (mainly +, -, *, quotient, modulo, remainder). So I expect
few fxringXXX procedures and many fxXXX procedures.
I find it odd that some fixnum operations return multiple values
(fxdiv+mod, fixnum+/carry, fixnum*/carry, ...). The main motivation
for fixnum specific operations is that they are much faster than
generic arithmetic. But in many implementations of Scheme multiple
values are rather slow because the values are packaged up in a vector
that is allocated on the heap, this vector must then be accessed to
get to the values. Moreover the main use of the XXX/carry operations
is to implement bignum arithmetic, but this will not be practical if
these operations are slow. I'm sure if you take the time to
benchmark this on some of the main implementations of Scheme you will
see that it is considerably faster to perform two independent
operations (for example use calls to fxdiv and fxmod instead of a
call to fxdiv-mod). Have you analyzed performance on current Scheme
systems, and if so, on which implementations of Scheme is the
multiple values API faster and by how much?
Finally, I haven't counted the number of procedures defined in this
SRFI, but it is clearly very high. Do you realistically think that
current implementations of Scheme will be updated to implement all
these procedures efficiently? If for expediency implementors decide
to use the portable implementation, I'm afraid that "portability" of
arithmetic code will only have a theoretical meaning. Can we expect
a portable and reasonably efficient implementation of this SRFI to be
written as the reference implementation? That would greatly help its
acceptance.
Marc