Subject: Re: Show me a better way?
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 01 Mar 2009 21:10:18 -0600
Newsgroups: comp.lang.lisp
Message-ID: <K46dnXDlr_SH0zbUnZ2dnUVZ_i2WnZ2d@speakeasy.net>
D Herring  <dherring@at.tentpost.dot.com> wrote:
+---------------
| Pillsy wrote:
| > (defmethod something-mathematical ((x integer) (y double-float))
| >   ...)
| > is also perfectly legit.
| 
| Check again...  Param specializers are a symbol (naming a class), a
| class, or an eql form.  The numeric types are not necessarily classes
| (some implementations support this, but its not required).
+---------------

Hmmm... I think you're somewhat less than half right here. True, the
CLHS does not define a System Class for DOUBLE-FLOAT per se [or any
of the other various precisions of floats], but it *does* for FLOAT:

    http://www.lispworks.com/documentation/HyperSpec/Body/t_float.htm
    System Class FLOAT
    Class Precedence List:
    float, real, number, t 

and, of course, also for INTEGER:

    http://www.lispworks.com/documentation/HyperSpec/Body/t_intege.htm
    System Class INTEGER
    Class Precedence List:
    integer, rational, real, number, t 

In fact, AFAICT a conforming CL *must* provide a System Class for -- and
thus be able to dispatch on -- at least INTEGER, RATIO, FLOAT, COMPLEX
and all of their their superclasses (e.g., RATIONAL, REAL, NUMBER).

The reason [again, AFAICT] that a conforming CL need not provide
System Classes for the ${PRECISION}-FLOAT subtypes of FLOAT is that
the ANSI Standard permits them to be degenerate, see:

    http://www.lispworks.com/documentation/HyperSpec/Body/t_short_.htm
    Type SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT, LONG-FLOAT
    Supertypes:
    short-float:   short-float, float, real, number, t
    single-float: single-float, float, real, number, t
    double-float: double-float, float, real, number, t
    long-float:     long-float, float, real, number, t 
    ...
    There can be fewer than four internal representations for floats.
    ...
    - If there is only one, it is the type single-float. In this
      representation, an object is simultaneously of types
      single-float, double-float, short-float, and long-float.
    ...

Given that, the standard *can't* mandate that (say) SINGLE-FLOAT and
DOUBLE-FLOAT dispatch differently, since they might be identical types.

+---------------
| IIRC, Clisp does not support numeric specializers.
+---------------

Again, only half-correct. Older CLISPs did not allow specializers
of the ${PRECISION}-FLOAT subtypes of FLOAT [newer versions may be
more liberal, I dunno], but certainly *did* allow numeric types
which are system classes:

    $ clisp -q
    [1]> (defmethod types ((x integer) (y float))
	   (list (list x 'is (type-of x)) (list y 'is (type-of y))))
    #<STANDARD-METHOD (#<BUILT-IN-CLASS INTEGER> #<BUILT-IN-CLASS FLOAT>)>
    [2]> (types 3 4.0)
    ((3 IS FIXNUM) (4.0 IS SINGLE-FLOAT))
    [3]> (types 3 4d0)
    ((3 IS FIXNUM) (4.0d0 IS DOUBLE-FLOAT))
    [4]> 

Other CLs also do allow some degree of ${PRECISION}-FLOAT specializers,
e.g., CMUCL-19e on x86 permits specializing on SINGLE-FLOAT & DOUBLE-FLOAT
[and provides System Classes for those], but *not* on either SHORT-FLOAT
or LONG-FLOAT [which are degenerate with SINGLE-FLOAT & DOUBLE-FLOAT,
respectively].

+---------------
| P.S.  This is one of the things which should have been fixed in the 
| past 10 years...
+---------------

See above for why it's not "broken".  (IMHO, YMMV.)


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607