This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: GSOC | Extending Common Lisp support


* Jamison Hope [2012-04-27 14:49] writes:

> 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.

OK, it matters whether value satisfies the declaration or not.  This
example is a bit more complicated because Kawa seems to evaluate (* x x)
at compile time.  SBCL actually emits a warning about dead code so it
doesn't need to evaluate it neither at compile time nor at runtime.
Kawa should probably do the same, but Kawa's handling of dead code has
also problems.  (I thinks dead code makes it hard to pass the JVM
verifier.)

>> 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'd expect a compile time warning and an error at runtime.  Automagic
coercion from float to int surprises me.  E.g. (string-ref "abc" 0.6)
should be an error instead of returning #\a or #\b.

One could also argue that either 11 or 10 is the nearest integer to 10.5
so the result should either be 121 or 100.  110 is quite odd, as the
coercion happens after the multiplication, but the type declaration is
lexically before the multiplication.

> 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.

AFAIU, int in Kawa is intentionally not the same as (signed-byte 32) in
CL.  It's a different type so that operations like +, * etc. can have
"methods" that wrap around.  I think the boxed representation of an int
is java.lang.Integer and the boxed representation of (unsigned-byte 32)
would be something like Fixnum or Bignum.  The trouble is that automatic
coercions from ints to other number types aren't that well specified.

Helmut


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]