From: Kenny Tilton
Subject: newbie CMUCL question re fighting off otherwise cool runtime checks
Date: 
Message-ID: <3F4E5EB8.60503@nyc.rr.com>
Cool cmucl runtime error!:

Function with declared result type NIL returned:
   BOT-PROCSS-ALL-PENDING-MSGS

And I see from the cmucl manual that by default the type checking is 
pretty string, including type inferencing obviously since I would not 
even know how to declare a return type in Lisp.

Puzzled, actually. This thing ran thru one exercise without a problem 
(but I think without hitting a certain branch of code, because..) but on 
the second drill it started yelping about function result types. I am 
guessing cmu is watching and noticed some runtime return value and made 
some notes off that.

This will be great fun someday when I am in the mood, but right now I 
just want to get on with things, and I am not sure how to make cmu stop 
its backseat driving. I'll keep flipping thru the manual, but so far the 
best I have is "increasing [compilation-speed] above safety weakens 
type-checking". Oy, just found something else say safety is 1 by default 
and to play with this to get diif runtime level checking as documented 
on a page where it is not documented. Hmmm.

How about: (optimize (safety 1)(speed 2)(compilation-speed 2)...) to get 
the conventional Lisp behavior until I have time to fuss with the code 
to make cmucl happy.

Or am I barking up the wrong tree?


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
                                                  -- Bob Uecker

From: Christophe Rhodes
Subject: Re: newbie CMUCL question re fighting off otherwise cool runtime checks
Date: 
Message-ID: <sqbru9lf7z.fsf@lambda.jcn.srcf.net>
Kenny Tilton <·······@nyc.rr.com> writes:

> Cool cmucl runtime error!:
>
> Function with declared result type NIL returned:
>    BOT-PROCSS-ALL-PENDING-MSGS
>
> And I see from the cmucl manual that by default the type checking is
> pretty string, including type inferencing obviously since I would not
> even know how to declare a return type in Lisp.

This one isn't your fault, I suspect, it's cmucl being non-compliant.
Generally, this happens when you redefine a function interactively
that previously the compiler had proved to never return (i.e. throw an
error); cmucl isn't very good at invalidating its previous assumptions
when you redefine the function.

> Or am I barking up the wrong tree?

Try (setf ext:*derive-function-types* nil) in your init file.

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)
From: Joe Marshall
Subject: Re: newbie CMUCL question re fighting off otherwise cool runtime checks
Date: 
Message-ID: <ekz5czfp.fsf@ccs.neu.edu>
Christophe Rhodes <·····@cam.ac.uk> writes:

> Kenny Tilton <·······@nyc.rr.com> writes:
>
>> Cool cmucl runtime error!:
>>
>> Function with declared result type NIL returned:
>>    BOT-PROCSS-ALL-PENDING-MSGS
>>
>> And I see from the cmucl manual that by default the type checking is
>> pretty string, including type inferencing obviously since I would not
>> even know how to declare a return type in Lisp.
>
> This one isn't your fault, I suspect, it's cmucl being non-compliant.
> Generally, this happens when you redefine a function interactively
> that previously the compiler had proved to never return (i.e. throw an
> error); cmucl isn't very good at invalidating its previous assumptions
> when you redefine the function.
>
>> Or am I barking up the wrong tree?
>
> Try (setf ext:*derive-function-types* nil) in your init file.

I'm not a CMUCL expert, so I suspect that Christophe Rhodes's advice
is sound in this regard.

However, when I get a mysterious type error in my code, I generally
turn the safety *way* up.  This usually pinpoints exactly where
I got my assumptions wrong instead of letting the error propagate.

But in your case, it sounds like a compiler/runtime issue of type
inference.
From: Kenny Tilton
Subject: Re: newbie CMUCL question re fighting off otherwise cool runtime checks
Date: 
Message-ID: <3F4E67A1.9040209@nyc.rr.com>
Joe Marshall wrote:
> However, when I get a mysterious type error in my code, I generally
> turn the safety *way* up.  This usually pinpoints exactly where
> I got my assumptions wrong instead of letting the error propagate.

yes, when time permits (chya!) i am looking forward to exploring cmucl, 
including performance hints as well as possible bugs thru the type checking.


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
                                                  -- Bob Uecker
From: Kenny Tilton
Subject: Re: newbie CMUCL question re fighting off otherwise cool runtime checks
Date: 
Message-ID: <3F4E66C0.7000104@nyc.rr.com>
Christophe Rhodes wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>Cool cmucl runtime error!:
>>
>>Function with declared result type NIL returned:
>>   BOT-PROCSS-ALL-PENDING-MSGS
>>
>>And I see from the cmucl manual that by default the type checking is
>>pretty string, including type inferencing obviously since I would not
>>even know how to declare a return type in Lisp.
> 
> 
> This one isn't your fault, I suspect, it's cmucl being non-compliant.
> Generally, this happens when you redefine a function interactively
> that previously the compiler had proved to never return (i.e. throw an
> error); cmucl isn't very good at invalidating its previous assumptions
> when you redefine the function.
> 
> 
>>Or am I barking up the wrong tree?
> 
> 
> Try (setf ext:*derive-function-types* nil) in your init file.

ok, will do. would it help to turn that back on in a production setting 
for better performance, or is this a broken feature altogether, or...?

thx for the speedy response, btw.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
                                                  -- Bob Uecker
From: Christophe Rhodes
Subject: Re: newbie CMUCL question re fighting off otherwise cool runtime checks
Date: 
Message-ID: <sq1xv5ld6j.fsf@lambda.jcn.srcf.net>
Kenny Tilton <·······@nyc.rr.com> writes:

> Christophe Rhodes wrote:
>> Kenny Tilton <·······@nyc.rr.com> writes:
>>>Or am I barking up the wrong tree?
>> Try (setf ext:*derive-function-types* nil) in your init file.
>
> ok, will do. would it help to turn that back on in a production
> setting for better performance, or is this a broken feature
> altogether, or...?

It's not a broken feature altogether; I use its analogue in a parallel
system, but only when I'm building a stable library (it's off by
default in SBCL).

Despite its name, it doesn't affect the compiler's ability or
decisions to derive function types; no matter the value of the
setting, in sbcl
  (defun foo (x)
    (declare (optimize (debug 1))) ; for complicated reasons
    (error "ERROR ~S" x))
  (sb-int:info :function :type 'foo)
returns
  #<FUN-TYPE (FUNCTION (T) NIL))>
(that is, a type representing a function which takes any argument and
does not return).  However, the effect of *derive-function-types* is,
when set, to allow the compiler to use derived types like the above
(as opposed to explicitly declaimed types) when compiling other code,
say
  (defun bar (x)
    (foo x)
    (print x))

With *derive-function-types* set, compiling BAR's definition should
get you compiler notes about deleting unreachable code -- the compiler
"knows" that FOO never returns, so removes the call to PRINT, because
it never gets there.  However, as I suspect you've observed by now,
this strategy doesn't work when redefining functions; if I now
redefine FOO (as long as FOO and BAR are in a different file, if we
want to be technical; see CLHS 3.2.2.3), then I can violate the
assumption that cmucl has made (that FOO never returns) and, short of
recompiling everything that refers to FOO, I won't have a consistent
world.  Hence the "NIL function returned" error, which is cmucl's way
of saying "the world has changed from under me".

Where it is useful is in compiling large, stable libraries, such as
clx or the like; the system can elide type checks that it can prove
(under the assumption that function types don't change); in some of my
system descriptions, I have something of the form
  (defmethod perform :around ((o compile-op) (s clx-source-file))
    (let ((sb-ext:*derive-fun-types* t))
      (call-next-method)))
so that the library compilation gets the benefit of this type
derivation logic, without having to worry about it affecting the
systems where I typically do a lot of incremental development.
   
I should also say that I second Joe's response; compiling with cmucl
or its derivatives, in high safety, treating warnings as things that
should be investigated not ignored, is a good way to get fairly
bullet-proof code.

> thx for the speedy response, btw.

Y'r wlcm.

Christophe
-- 
http://www-jcsu.jesus.cam.ac.uk/~csr21/       +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b "~&Just another Lisp hacker~%")    (pprint #36rJesusCollegeCambridge)