[Openmcl-devel] two portability issues

Rainer Joswig joswig at lisp.de
Sun Dec 21 13:40:00 PST 2014


> Am 21.12.2014 um 22:10 schrieb Gary Byers <gb at clozure.com>:

>> > Please read and try to understand section 3.2.3.1.1, then think about whether your understanding of the issues here is correct.  I strongly suspect that it isn’t.
>> Okay, read it...
>> How about: http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm#defstruct <http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm#defstruct>
>> > If a defstruct form appears as a top level form, the compiler must make the structure type name recognized as a valid type name in subsequent declarations
>> My interpretation would be that a type declaration in a LOOP should be able to use a structure type, without compile-time evaluation.
> 
> The compiler indeed makes the structure name be recognized as a valid type name; you can use the structure name as a type name in subsequent declarations in the file that contains the defstruct form.  That means that the compiler can't warn that it's never heard of the type if it encounters it in a declaration (the type doesn't necessarily exist in the global environment at compile-time, but it will exist at runtime and at least some information about the type in the compilation environment.
> 
> Code called by the LOOP macro (the function ANSI-LOOP::LOOP-MAKE-VARIABLE) calls TYPEP on the structure name and the global environment when processing loop variable with OF-TYPE qualifiers, and that's wrong.  I don't think of that code as being part of the compiler (and find it confusing when people attribute behavior to the compiler that other code is responsible for), but I agree that code that's part of the implementation shouldn't be so casual about assuming that types that are used in declarations are globally defined.

Thanks for the update. Yes, looks like it’s a problem of the LOOP macro. I saw later that the problem appears to be LOOP specific, since in other declaration examples the type is indeed recognized.

>> The problem seems to appear without optimize declarations...
>> (defun get-longest-path (nodes node-id visited &aux (max 0))
>>  (setf (svref visited node-id) t)
>>  (setf max (loop for neighbour of-type route in (svref nodes node-id)
>>                  unless (svref visited (route-dest neighbour))
>>                  maximize (+ (the fixnum (route-cost neighbour))
>>                              (the fixnum (get-longest-path nodes
>>                                                            (route-dest neighbour)
>>                                                            visited)))
>>                            fixnum))
>>  (setf (svref visited node-id) nil)
>>  max)
>> Safety 3 and Speed 0 takes a long time and returns the wrong result: -1152921504606837995
> 
> 
> Note that (for instance)
> 
> ? (logand (1- (ash 1 14)) -1152921504606837995)'
> 8981
> 
>> The expected result would have been 8981.
> 
> I haven't looked at your code yet and probably won't have time to do that for that for at least a few days, but that's either an amazing coincidence or it isn’t.

Yes, that really looks suspicious…

I tried it in a simpler LOOP and could not reproduce the error there. One thing which is different here, is that the function gets called recursively from inside the LOOP.

Declaring the type of the maximized value seems to be a LOOP feature which is rarely used...

No need to hurry. Many thanks, Gary!





More information about the Openmcl-devel mailing list