This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: GSOC | Extending Common Lisp support
On Apr 27, 2012, at 2:20 AM, Helmut Eller wrote:
From a philosophical point of view, type declarations in Lisp don't
change the semantics, i.e. a program with declarations should produce
the same results as the program without (though it could be more
efficient or give extra warnings).
My reading is that this is only the case for valid input (and the
meaning
of "valid" depends upon any relevant declarations). CLHS[0] says:
"During
the execution of any reference to the declared variable within the
scope of
the declaration, the consequences are undefined if the value of the
declared
variable is not of the declared type." So an implementation is free to
issue a warning or throw an error or just ignore the declaration
entirely.
And indeed, executing
(let ((x 10.5))
(declare (integer x))
(* x x))
in SBCL throws me into the debugger with a SIMPLE-TYPE-ERROR, since SBCL
treats type declarations as assertions. CLISP, on the other hand, just
returns 110.25.
It's also in line with tradition to
emit a warning at compile time but still generate code that will raise
an runtime error. IMO Kawa acts quite gracefully here.
A different story is this example:
(define (test)
(let ((x :: int 10.5))
(* x x)))
Kawa returns 110 which seems quite wrong.
The difference here with int instead of integer is of course due to
how coercions to primitive types are handled [and (*:intValue 110.25)
returns 110]. It does seem like things should be more consistent
between primitive and Object numbers.
But I don't really see a return value of 110 as being wrong, per se: the
program itself is flawed, since 10.5 is not an int, so we're already in
nasal demon territory, but 110 is the nearest int to (* 10.5 10.5), so
the result seems fairly gracious. What would you have expected?
I will note that the compiler has taken the extra step to infer that if
x is an int, then (* x x) will be an int, too. That would not be a valid
inference in Common Lisp. Turning to the HyperSpec again, we see:
A type declaration for the arguments to a function does not
necessarily
imply anything about the type of the result. The following function is
not permitted to be compiled using implementation-dependent fixnum-
only
arithmetic:
(defun f (x y) (declare (fixnum x y)) (+ x y))
To see why, consider (f most-positive-fixnum 1). Common Lisp defines
that
F must return a bignum here, rather than signal an error or produce a
mathematically incorrect result.
That doesn't imply that (f 1.5 1.5) has to return 3, though.
-Jamie
[0] http://www.lispworks.com/documentation/lw60/CLHS/Body/d_type.htm
--
Jamison Hope
The PTR Group
www.theptrgroup.com