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.
Marc Feeley wrote: > The rationale for the two sets of names is wrong. > Adding redundant procedures adds confusion. Your opinion is contrary to mine. When I use the fixnum or fx primitives, I first decide whether I want the quotient ring (with results that may depend upon the implementation-dependent precision) or the more errorful primitives (that raise an exception rather than return a result that might depend upon the precision). Having made that decision, I find it less confusing to use the appropriate prefix consistently than to mix prefixes. Indeed, I find it hard to remember which pairs of primitives behave exactly the same, as the differences that do exist are often subtle. If I use the same prefix consistently, however, I know the operations I use will behave consistently. > I didn't make this up. It is the only rationale > for fixnums in the SRFI 77 rationale: > > Fixnum/flonum arithmetic is already supported by > many systems, mainly for efficiency. Standardization > of fixnum/flonum arithmetic would increase the portability > of code that uses it, but we cannot standardize the > precision of fixnum/flonum arithmetic without making > it inefficient on some systems, which would defeat its > purpose. You overlooked the word "portability", not only in the paragraph you quoted but in the paragraphs that precede it. Note also the word "portable" in those paragraphs. Furthermore the first rationale given in the section on fixnums explains that *the* rationale for the fx operations is a specific issue of portability. > By using a multiple values API for some fixnum operations, > you are limiting the practical portability of those operations. > This is inconsistent with the rationale. Your argument, Marc, is that multiple values are slow in some systems, so portable code shouldn't use them. That's like arguing that procedure calls are slow in some systems, so portable code shouldn't use procedure calls. The proper solution is to improve the implementations, and to count on users being smart enough to avoid slow implementations when efficiency is a major concern. > I repeat: in which implementations of Scheme will the > multiple values API be faster than the equivalent pair > of operations which return single values? Implementors are an unpredictable bunch, and efficiency is not an issue that lends itself to simple answers in any case. In Larceny and Petit Larceny, however, I would expect the fixnum-div+mod, fixnum-div0+mod0, fxdiv+mod, fxdiv0+mod0, fldiv+mod, fldiv0+mod0, fixnum+/carry, fixnum-/carry, and fixnum*/carry procedures to be faster than the corresponding series of calls to single-result procedures. I would not expect them to be a great deal faster, however, because inlining followed by common subexpression elimination would reduce the duplication these multiple-values-returning procedures were designed to prevent. In my opinion, their performance advantages will be most evident in interpreted systems that support multiple values efficiently; MzScheme is one such system. > I believe that efficient implementations of multiple > values based on Ashley and Dybvig's method...will not > gain with the MV API because they need to return the > multiple values using a function call, and the overhead > of the function call will drown the few machine cycles > saved by the combined operation. You lost me there. I don't know the instruction-level details of how multiple values are returned in Chez Scheme, but I do know you are arguing that two closed calls (to the separate procedures you favor) and two returns are faster than one closed call (to the SRFI 77 procedure), a tail call to values (which will probably be inlined, and consist of just a few machine instructions), and the return from the values procedure. Your argument doesn't add up. > The choice of a MV API for these operations is poor engineering. Your conclusion is unsupported. I agree with your earlier argument that many systems are using poorly engineered implementations of multiple values, but the responsibility for fixing that problem lies with implementors, not with Scheme programmers in general. > Can you quantify what you mean by "reasonably efficient" > for the fixnum operations? To some extent, but it should be obvious that the efficiency will vary greatly from one implementation to another, and also from operation to operation. > Do you mean as fast as the equivalent operation in C? Since C is an unsafe language, it would seem that the proper comparison would be with implementations of Scheme that will implement the unsafe mode mentioned in SRFI 77. In unsafe mode, on most architectures, the fixnum and fx comparisons and basic arithmetic operations should compile into a single machine instruction, the same as in C. Even in safe code, and even for generic operations such as +, some compilers can, in some circumstances, compile the call to + into a single machine instruction. My Twobit compiler does that sometimes, even today. With the proposed R6RS library system, that will happen more often. (That, by the way, is my response to one of Per Bothner's points.) As for the worst case, in safe code, with generic arithmetic, inlining the usual procedures (which I expect to be justified by the R6RS library system), a call to + with two arguments that turn out to be fixnums, whose sum is a fixnum, currently takes somewhere between three (Sparc) and seven (IA32) dynamic instructions. > I fear that unless the fixnum operations are inlined, the > procedure call to the definition in the reference implementation > will slow down the operation by a factor of 10 or more, rendering > it useless in practice for writing efficient code. I assume that, in compiled implementations that aspire to efficiency, the fixnum comparisons and basic arithmetic operations (e.g. fixnum+) will be inlined. Most of those implementations already inline the fixnum case for generic arithmetic, and most already inline their own idiosyncratic extensions for fixnum-specific arithmetic. The potential standardization represented by SRFI 77 won't make efficient implementations less efficient, and it won't make inefficient implementations more efficient. What it will accomplish is to make Scheme programs more portable. Programmers won't have to worry about implementations that convert to inexact numbers because they don't support exact rational arithmetic of unlimited precision, and they will be able to write fixnum-specific, flonum-specific, exact-specific, and inexact-specific arithmetic without having to change the procedure names when porting to a different implementation. Will