On Wed, Feb 21, 2024 at 7:54 AM Camm Maguire <c...@maguirefamily.org> wrote:

> Greetings, and thanks for your feedback!
>
> Raymond Toy <toy.raym...@gmail.com> writes:
>
> > When a is a floating-point number (= a a) should not be optimized to
> > T.  Likewise (/= a a) should not be optimized to NIL.  I'm pretty sure
> > IEEE754 says that NaN is never = to itself or another NaN or any other
> > number.
>
> Why not?  I agree the 'C' IEEE operator of similar name ('==') should be
> left untouched, but the spec for common-lisp::=  clearly implies that
> the *same* NaN should be '= to itself, and even that different boxed
> versions of the same bit patterns should be.  I am suggesting that (/= a
> a) not be a NaN detector, but to provide some other means (described
> below).
>

I have no problem with alternative ways.  Cmucl offers float-nan-p and
float-signalling-nan-p functions.  But since IEEE says NaN = NaN is always
false, Lisp should support that as well. Cmucl supports this.  I think sbcl
does too.  I'd try to test ecl and ccl, but I don't know how to turn off FP
traps to create a NaN.

>
> I agree on 'staying close to the hardware', and one could just as well
> say who cares on a practical violation of the spec.  In general I am
> sympathetic to such a point of view, but here it seems unnecessary.
>

I think CLHS isn't really super clear on IEEE floats.

>
> Lisp after all is just a bunch of hardware instructions with optional
> type checking layered on top :-).  #'car on a long-float should trigger
> an error, and does at certain safety levels, but compile at safety 0,
> and one gets the 'hardware' car which will return a value however
> dubious it may be.  The same could be the case for '=.  Say NaN was
> boxed with identical layout to a long-float, but with a different
> type-word denoting something orthogonal to 'number, say 'ieee-special-64
> or some such.  '= will then signal an error on nan input, except when
> compiled at safety 0, in which case the NaN can be read as before in
> boxed or unboxed form.  The compiler would then simplify '= to t on
> equivalent bindings, and we could use #'si::isnan or even (typep nan
> 'ieee-special-64) as a detector.
>

I agree with what Robert says.  Compilation safety here should change the
computed results for valid inputs.

>
>
> >
> >  We also have the following charming behavior:
> >
> >  (typep nan 'long-float) ->t
> >  (typep nan '(long-float 0) ->nil
> >  (typep nan '(long-float * 0)) ->nil
> >  (typep nan '(or (long-float 0) (long-float * 0))) ->nil
> >
> >  but the first and last types are of course identical.
> >
> > Isn't the last one a bug?  Should the compiler convert (or (long-float
> > 0) (long-float * 0)) to just long-float?
> >
>
> I don't think so.  (typep a '(or b c)) == (or (typep a b) (typep a c))
>

FWIW, both cmucl and sbcl convert the type (or (double-float 0d0)
(double-float * 0d0)) to just double-float and the last typep returns T.

>
>
> > I'm not sure what the second and third cases returning nil really
> > means in practice.  I think even if you declare a function as only
> > taking and returning (long-float 0), you can have operations return
> > NaN, even if the inputs are non-negative floats.
> >
>
> It means that NaN does not fit into a total ordering scheme of say
> long-floats, and the type explicitly recognizes and denotes ordered
> subsets.
>

Fair enough.

>
>
> >  If NaN was truly 'not a number', the numerical functions would trigger
> >  an error on input only when compiled with safety, and might be arranged
> >
> > I think I would defer to whatever the HW does and the floating point
> > traps that are enabled.  If the invalid trap is enabled, then we get
> > errors.  If the invalid trap is disabled, NaN gets returned.
> >
>
> I think we can have our cacke and eat it too.  We can still compile at
> safety 0 and proceed with errors optionally triggered only when setting
> FPE traps.  But when interpreted or compiled with safety, standard type
> errors would be triggered.
>

This seems ok.  But (= nan nan) must return false.

>
>
> > The subject also mentions +/= inf.  Did you forget to mention issues
> > with infinities?
> >
>
> I am much less bothered by these, though they do make
> most-positive-long-float meaningless.  They are in fact quite useful in
> bounds checking arithmetic in the compiler.  Maybe
> most-positive-long-float == +inf?
>
I don't think that would be really useful to anyone.  It should be most
positive finite value.

>
> Can anyone without too much effort summarize how other lisps handle
> this?  Can one access/manipulate nan at the lisp prompt level?
>

For cmucl you can do (set-floating-point-modes :traps nil) to disable all
FP traps.  Then (/ 0d0 0d0) returns a NaN.  Sbcl uses
sb-int::set-floating-point-modes instead.  I don't know about the others.

Oh, and sbcl says (type nan '(double-float 0d0)) is NIL.  Cmucl says it's
true.  That's probably not right.

>
> Take care,
>
> >  Take care,
> >  --
> >  Camm Maguire
> c...@maguirefamily.org
> >
> ==========================================================================
> >  "The earth is but one country, and mankind its citizens."  --
> Baha'u'llah
>
> --
> Camm Maguire                                        c...@maguirefamily.org
> ==========================================================================
> "The earth is but one country, and mankind its citizens."  --  Baha'u'llah
>


-- 
Ray

Reply via email to