Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!munnari.oz.au!goanna!ok From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) Newsgroups: comp.lang.lisp Subject: Re: Virtues of Lisp syntax Message-ID: <3805@goanna.cs.rmit.oz.au> Date: 24 Sep 90 08:16:28 GMT References: <33709@cup.portal.com> <1990Sep10.091911.20877@hellgate.utah.edu> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 96 On 14 Sep 90 07:45:24 GMT, ok@goanna.cs.rmit.oz.au (I) wrote > operation. Floating-point "+" and "*" are not associative. In article , pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: > The semantics *are* different. Didn't I write that? I was responding to this exchange: Andy Freeman wrote: "+" isn't really a binary operator, neither is "*"; there are surprisingly few true binary operations to which Pierlecarlo Grandi replied Precisely. Agreed. and surely to agree that "+" and "*" are "not really" binary operations but are really N-ary "associative" operations "precisely" is to say that they are associative? > ok> For integer and rational arithmetic, there's no problem, > > Well, this is a case in point for my argument about the pitfalls; there > is still a problem. Nobody constrains you to have only positive numbers > as the operands to n-ary fixed point +, so that > > (+ -10 +32767 +10) > > is not well defined on a 16 bit machine, unless you do modular > arithmetic throughout. This turns out not to be the case. Given any arithmetic expression made up of 16-bit integer constants, variables having suitable values, and the operations "+", unary "-", binary "-", and "*", if the result of the whole expression should be in range, the answer is guaranteed correct. If the implementation detects integer overflow, then arithmetic expressions are only weakly equivalent to their mathematical counterparts, but if integer overflow is ignored, then the answer is right iff it is in range. In particular, on a 16-bit machine, if (+ -10 +32767 +10) gives you any answer other than 32767 or "overflow", your Lisp is broken. Given that I referred to "integer and rational arithmetic", I think it's reasonably clear that I was referring to Common Lisp (and of course T!) where integer and rational arithmetic are in fact offered. > As we already know but sometimes forget, arithmetic on computers follows > *very* different rules from arithmetic in vanilla mathematics, Not for integer and rational arithmetic it doesn't, and even N-bit arithmetic is correct *modular* arithmetic (except for division). > (+ a b c d e) > > simply means apply repeated *computer* addition on *computer* fixed or > floating point throughout. But it is an utterly hopeless notation for that! The only excuse for using N-ary notation for addition is that it genuinely doesn't matter which way the additions are done. For 2s-complement (with overflow ignored) and for integer and rational arithmetic, this is indeed the case, and (+ ...) notation can be used without misleading. But for FP it matters. > ok> but anyone doing floating point calculations in Lisp has to be very > ok> wary of non-binary + and * . > > Anyone doing floating point arithmetic on *any* machine, IEEE standard > or Cray, has to be very very wary of assuming it is the same as > arithmetic on reals This completely misses the point. I am supposing someone who thoroughly understands floating-point arithmetic. (+ a b c) is a trap for _that_ person, no matter how much he understands IEEE or CRAY or even /360 arithmetic, because there is no promise about how it will turn into >floating-point< operations (which we assume the user thoroughly grasps). (+ a b c) may be compiled as (+ (+ a b) c) or as (+ a (+ b c)) or even as (+ (+ a c) b). For floating-point, these are different formulas. The trap here is that the particular Lisp used by a floating-point expert may compile (+ a b c) into (+ (+ a b) c) and he may mistake this for something guaranteed by the language. The copy of CLtL2 I've borrowed is at home right now, but there is nothing in CLtL1 to require this. The entire description of "+" is + &rest numbers [Function] This returns the sum of the arguments. If there are no arguments, the result is 0, which is an identity for this operation. There is no reason to expect that + will always involve an addition. As far as I can see, there is nothing to prevent a CL implementation compiling (declare (type float X)) (+ X X X) as (* 3 X) even though on the given machine the two imagined floating-point formulas may yield different answers. I'm sure CLtL2 must clarify this. -- Heuer's Law: Any feature is a bug unless it can be turned off.