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

fixnumXXX and fxXXX names, and other things

This page is part of the web mail archives of SRFI 77 from before July 7th, 2015. The new archives for SRFI 77 contain all messages, not just those from before July 7th, 2015.



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