From: ···········@alcoa.com
Subject: Appalled by un-C-like behavior
Date: 
Message-ID: <7lt311$f1s$1@nnrp1.deja.com>
A colleague was appalled that Common Lisp does not coerce single floats
to double floats, and vice versa, and does not coerce floats to integers
either. This can only be the case when declarations are being used as
they are with the test function below using ACL 5.0. I guess this is his
problem, but my concern after writing this test function is that it
gives the wrong answers. Wouldn't it be more helpful if the compiler
used the declarations to give a compiler error or even warning? Failing
that a run time error is a possibility but that would take away some of
the higher effeciency sought by using declarations to begin with. Then
there is a third possibility - coerce like the static languages do.
Which brings me full circle. Why is automatic coercion not a good idea
and does the spec prevent it?

(defun test ()
  (declare (optimize (speed 3) (safety 0)))
  (let ((single1 1.0f0)
	(single2 1.0f0)
	(double1 1.0d0)
	(double2 1.0d0)
	(int1 1))
    (declare (single-float single1 single2)
	     (double-float double1 double2)
	     (fixnum int1))
    (setq single2 double1
	  double2 single1
	  int1 single1)
    (values single2 double2 int1)))

--
John Watton
Alcoa Inc.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

From: Barry Margolin
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <zrqg3.1148$KM3.276620@burlma1-snr2>
In article <············@nnrp1.deja.com>,  <···········@alcoa.com> wrote:
>A colleague was appalled that Common Lisp does not coerce single floats
>to double floats, and vice versa, and does not coerce floats to integers
>either. This can only be the case when declarations are being used as
>they are with the test function below using ACL 5.0. I guess this is his
>problem, but my concern after writing this test function is that it
>gives the wrong answers. Wouldn't it be more helpful if the compiler
>used the declarations to give a compiler error or even warning? Failing

Some compilers do enough data flow analysis to detect this at compile
time.  Try his code in CMUCL and I'll bet you get warnings.

>that a run time error is a possibility but that would take away some of
>the higher effeciency sought by using declarations to begin with. Then

Right.  He said (optimize (speed 3) (safety 0)), implying that he's sure
that the code is correct and he doesn't want to waste any time checking
data at run time.

>there is a third possibility - coerce like the static languages do.
>Which brings me full circle. Why is automatic coercion not a good idea
>and does the spec prevent it?

The spec doesn't prevent automatic coercion when declarations are
provided.  The spec says that the consequences are undefined if you violate
a declaration, which allows the implementation to do anything.  Automatic
coercion would be a reasonable behavior.

However, this is definitely not portable.  It's more common for
implementations to insert type checks in safe code.  Type declarations in
Lisp are intended to be hints to aid the compiler in optimizing, they
aren't supposed to change the semantics of the program (a compiler that
ignores them completely is still conforming).  If you want to coerce,
you're expected to call a coercion function explicitly.  Type declarations
are promises by the programmer, not requests.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kenneth P. Turvey
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <slrn7o5j1n.l4g.kturvey@pug1.sprocketshop.com>
On Tue, 06 Jul 1999 16:48:31 GMT, Barry Margolin <······@bbnplanet.com> wrote:
[Snip]
>
>However, this is definitely not portable.  It's more common for
>implementations to insert type checks in safe code.  Type declarations in
>Lisp are intended to be hints to aid the compiler in optimizing, they
>aren't supposed to change the semantics of the program (a compiler that
>ignores them completely is still conforming).  If you want to coerce,
>you're expected to call a coercion function explicitly.  Type declarations
>are promises by the programmer, not requests.

It should be noted (this came up a few weeks ago) that if you want to
check the types explicitly, Lisp allows this. 

Take a look at CHECK-TYPE.

From the hyperspec:

(check-type aardvark-count (integer 0 *) "A positive integer")

-- 
Kenneth P. Turvey <·······@SprocketShop.com> 
----------------- http://www.tranquility.net/~kturvey

  Those who would give up essential Liberty, to purchase a little
  temporary safety, deserve neither Liberty or safety.
        -- Benjamin Franklin
From: Duane Rettig
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <4pv23maa1.fsf@beta.franz.com>
Barry Margolin <······@bbnplanet.com> writes:

> In article <············@nnrp1.deja.com>,  <···········@alcoa.com> wrote:
> >A colleague was appalled that Common Lisp does not coerce single floats
> >to double floats, and vice versa, and does not coerce floats to integers
> >either. This can only be the case when declarations are being used as
> >they are with the test function below using ACL 5.0.

[The key concept here is "automatic coercion"; CommonLisp of course
provides several ways to coerce explicitly, via the COERCE and FLOAT
functions.  There simply isn't any concept of automatically doing this
coercion]

> The spec doesn't prevent automatic coercion when declarations are
> provided.  The spec says that the consequences are undefined if you violate
> a declaration, which allows the implementation to do anything.  Automatic
> coercion would be a reasonable behavior.

When this thread first started, I was of the opinion that automatic coercion
would be nice to offer, and reasonable.  However, I have been convinced by
my colleagues and by your argument below, that it is not reasonable to provide
automatic coercion.  I was half-convinced when reminded that declarations
cannot (with the exception of (declare (special ...)) ) change the semantics
of the program. This is also in line with what you have stated below:

> However, this is definitely not portable.  It's more common for
> implementations to insert type checks in safe code.  Type declarations in
> Lisp are intended to be hints to aid the compiler in optimizing, they
> aren't supposed to change the semantics of the program (a compiler that
==^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ignores them completely is still conforming).  If you want to coerce,
> you're expected to call a coercion function explicitly.  Type declarations
> are promises by the programmer, not requests.

The most convincing argument was given to me by a colleague:

=====
I would normally expect, in correct code, that
  (progn
    (setq x y)
    (eql x y))

would always return t.

Are you proposing that

  (let ((single 1.0f0)
        (double 1.0d0))
    (declare (single-float single)
             (double-float double))
    (setq single double)
    (eql single double))

will return nil and that this is good?


It's legal, in the sense that the declarations are illegal
and so anything you do is ok.  But is it a good thing?
=====

The current position at Franz is that no (automatic) coercion
should be done, and that either a warning or an error be given
when the assignment mismatches in type and type declarations are
being "trusted".  The most major point of discussion now is whether
to make the message a warning or an error.

Final note:  The subject line betrays an attitude (not of the original
author, but of his colleague, who may or may not be C-oriented, but
who like me fell into the C-orientation trap).  Quite frankly, I am
pleased and proud of CL's un-C-like behavior ...

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Christopher R. Barry
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <87908tek2n.fsf@2xtreme.net>
···········@alcoa.com writes:

> A colleague was appalled that Common Lisp does not coerce single floats
> to double floats, and vice versa, and does not coerce floats to integers
> either. This can only be the case when declarations are being used as
> they are with the test function below using ACL 5.0. I guess this is his
> problem, but my concern after writing this test function is that it
> gives the wrong answers. Wouldn't it be more helpful if the compiler
> used the declarations to give a compiler error or even warning? Failing
> that a run time error is a possibility but that would take away some of
> the higher effeciency sought by using declarations to begin with. Then
> there is a third possibility - coerce like the static languages do.
> Which brings me full circle. Why is automatic coercion not a good idea
> and does the spec prevent it?
> 
> (defun test ()
>   (declare (optimize (speed 3) (safety 0)))
>   (let ((single1 1.0f0)
> 	(single2 1.0f0)
> 	(double1 1.0d0)
> 	(double2 1.0d0)
> 	(int1 1))
>     (declare (single-float single1 single2)
> 	     (double-float double1 double2)
> 	     (fixnum int1))
>     (setq single2 double1
> 	  double2 single1
> 	  int1 single1)
>     (values single2 double2 int1)))

  USER(1): (coerce 1.0 'double-float)
  1.0d0

  USER(2): (coerce 1.0d0 'single-float)
  1.0

  USER(2): (round 1.0)
  1
  0.0

If you compile with high enough safety settings then the single will
be coerced to a double and vice-versa as you originally wanted
anyways. You can't convert a float to an integer implicitly or by
using COERCE. This a good thing, in case you didn't know.

Christopher
From: ···········@alcoa.com
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <7lvf5c$aii$1@nnrp1.deja.com>
In article <··············@2xtreme.net>,
  ······@2xtreme.net (Christopher R. Barry) wrote:
> If you compile with high enough safety settings then the single will
> be coerced to a double and vice-versa as you originally wanted
> anyways. You can't convert a float to an integer implicitly or by
> using COERCE. This a good thing, in case you didn't know.

Not with ACL 5.0. Using (optimize (speed 3)(safety 3)) I get 1.0d0 1.0
1.0. No types get changed on assignment. With (optimize (speed 3)
(safety 0) I get various answers of the sort 3.0176827e-19
3.114655902821663d-151 1.0.

--
John Watton
Alcoa Inc.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
From: Vassil Nikolov
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <l03130302b3a7deec30d4@195.138.129.96>
On 1999-07-06 14:15 +0000,
···········@alcoa.com wrote:

  > A colleague was appalled that Common Lisp does not coerce single floats
  > to double floats, and vice versa, and does not coerce floats to integers
  > either. This can only be the case when declarations are being used as
  > they are with the test function below using ACL 5.0. I guess this is his
  > problem, but my concern after writing this test function is that it
  > gives the wrong answers. Wouldn't it be more helpful if the compiler
  > used the declarations to give a compiler error or even warning? Failing
  > that a run time error is a possibility but that would take away some of
  > the higher effeciency sought by using declarations to begin with. Then
  > there is a third possibility - coerce like the static languages do.
  > Which brings me full circle. Why is automatic coercion not a good idea
  > and does the spec prevent it?
  > 
  > (defun test ()
  >   (declare (optimize (speed 3) (safety 0)))
  >   (let ((single1 1.0f0)
  > 	(single2 1.0f0)
  > 	(double1 1.0d0)
  > 	(double2 1.0d0)
  > 	(int1 1))
  >     (declare (single-float single1 single2)
  > 	     (double-float double1 double2)
  > 	     (fixnum int1))
  >     (setq single2 double1
  > 	  double2 single1
  > 	  int1 single1)
  >     (values single2 double2 int1)))

Automatic coercion is not a very good idea because floating-point
arithmetic is subtle and it's better to have the programmer in full
control.

It `is an error' to have assignment such as the above.  With (SAFETY 0),
however, one can't rely upon any error message to be produced.  (It
would be nice to get a warning from the compiler, but that is not
mandated by the standard.)

With e.g. (SETQ INT1 SINGLE1), from the point of view of the implementation
a pointer to a bit string that should be interpreted as a single-float is
stored in INT1 and due to the declaration of the latter that bit string
is interpreted as a FIXNUM value.  With (SAFETY 0), the compiled code
may not examine the tag that identifies that bit string as a single float
(and with (SPEED 3) the compiler is quite justified in omitting that
examination).

A more general remark: in C, a declaration such as ``int int1'' mandates
the internal representation of the value of the variable besides telling
the compiler how to treat that value when it occurs.  In Common Lisp,
a declaration such as (FIXNUM INT1) does only the latter; the internal
representation follows from the act of creating the value object (in
the above code example, the value object (the fixnum 1) is created by
the reader when it scans the token "1" and then a reference (a pointer
in implementation terms) to that object is placed in the variable INT1.

Good luck,
Vassil.


Vassil Nikolov
Permanent forwarding e-mail: ········@poboxes.com
For more: http://www.poboxes.com/vnikolov
  Abaci lignei --- programmatici ferrei.
From: Marco Antoniotti
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <lwbtdobx6y.fsf@copernico.parades.rm.cnr.it>
···········@alcoa.com writes:

> A colleague was appalled that Common Lisp does not coerce single floats
> to double floats, and vice versa, and does not coerce floats to integers
> either.

The authors of "Numerical Recipes in C" (some of the worst criminals
on the planet, when it comes to 'programming style' :) ) are appalled
that C does this by default.  Show your colleague the introduction to
that (indispensable) book and have her/him think back to C and
FORTRAN. :)

> This can only be the case when declarations are being used as
> they are with the test function below using ACL 5.0. I guess this is his
> problem, but my concern after writing this test function is that it
> gives the wrong answers. Wouldn't it be more helpful if the compiler
> used the declarations to give a compiler error or even warning? Failing
> that a run time error is a possibility but that would take away some of
> the higher effeciency sought by using declarations to begin with. Then
> there is a third possibility - coerce like the static languages do.

Which of the 'static' languages would you choose?

> Which brings me full circle. Why is automatic coercion not a good idea
> and does the spec prevent it?
> 
> (defun test ()
>   (declare (optimize (speed 3) (safety 0)))
>   (let ((single1 1.0f0)
> 	(single2 1.0f0)
> 	(double1 1.0d0)
> 	(double2 1.0d0)
> 	(int1 1))
>     (declare (single-float single1 single2)
> 	     (double-float double1 double2)
> 	     (fixnum int1))
>     (setq single2 double1
> 	  double2 single1
> 	  int1 single1)
>     (values single2 double2 int1)))
> 

BTW. In CMUCL

* (compile 'test)
In: LAMBDA NIL
  (SETQ SINGLE2 DOUBLE1 DOUBLE2 SINGLE1 ...)
--> SETQ 
==>
  DOUBLE1
Warning: This is not a SINGLE-FLOAT:
  1.0d0

==>
  SINGLE1
Warning: This is not a DOUBLE-FLOAT:
  1.0
Warning: This is not a FIXNUM:
  1.0

Compilation unit finished.
  3 warnings


TEST
T
T
* 


-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: William Deakin
Subject: Re: Appalled by un-C-like behavior
Date: 
Message-ID: <37832BD0.5C5954E1@pindar.com>
Marco Antoniotti wrote:

> The authors of "Numerical Recipes in C" (some of the worst criminals on the
> planet, when it comes to 'programming style' :) )  ...

I concur. If there were a not-the-Miss-World beauty competition for code
writing then Mr Press et al would be up for a good beating with the ugly-stick
;-)

Also see "http://www.Colorado.EDU/ITS/docs/scientific/fortran/numrec.html" for
other critisms of the books contents....

--will