[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Issue: FUNCTION-TYPE-REST-LIST-ELEMENT, FUNCTION-DECLARATION issues



    Date: 2 Dec 87 20:40 PST
    From: Masinter.pa@Xerox.COM

    ...
    (declare (function my-cons (float string) list) )
    ...
    The problem is that the argument type declaration here is of absolutely
    no use.
    ...
    It would be more valuable as far as I can see to say that a
    (function (float string) list)
    is one to which *only* a float and a string can be passed. Perhaps
    someone familiar with an implementation that pays attention to these
    declarations can explain what they are used to denote? 

In Maclisp, if you declared a function to take arguments (fixnum flonum),
for example, special tricks were allowed to be done with passing the arguments
without having to heap-cons them. You were required to only use this declaration
if you had made it available to the compiler at the time of compiling the function
(so that it would have done the special tricks necessary to make the external
calling sequence work). The net effect was that the function had a naive entry
point (for people who didn't know about the declaration) and a magic entry point
for people who wanted to exploit the declaration information and bypass some
setup instructions.

In order to get this effect in CL, we have only to restrict the declaration of
a function to be exactly the declaration that the function was compiled under.
That is, there are a number of possible universes we could elect to be in:

 * We could allow local function declarations to just say things we know to
   be true, regardless of whether they were interesting. eg,
      (PROCLAIM '(FUNCTION FOO (INTEGER) INTEGER))
      (DEFUN FOO (X) (+ X 1))
   could be matched in another file by
      (LOCALLY (DECLARE (FUNCTION FOO (INTEGER) INTEGER)) ... (FOO ...) ...)
   or (LOCALLY (DECLARE (FUNCTION FOO (FIXNUM) FIXNUM)) ... (FOO ...) ...)
   or (LOCALLY (DECLARE (FUNCTION FOO (T) T)) ... (FOO ...) ...)

   This would tend to thwart interesting compilations because nothing in the
   declaration would tell you anything useful about how the function was compiled.

 * We could allow local function declarations only if they restrict the
   declaration under which the function was compiled. eg,
      (PROCLAIM '(FUNCTION FOO (INTEGER) INTEGER))
      (DEFUN FOO (X) (+ X 1))
   could be matched in another file by
      (LOCALLY (DECLARE (FUNCTION FOO (INTEGER) INTEGER)) ... (FOO ...) ...)
   or (LOCALLY (DECLARE (FUNCTION FOO (FIXNUM) FIXNUM)) ... (FOO ...) ...)
   but not by
      (LOCALLY (DECLARE (FUNCTION FOO (T) T)) ... (FOO ...) ...)

   This might thwart some interesting compilations because you wouldn't know 
   everything about the way the function was compiled, but you'd know some
   information.

 * We could allow local function declarations only if they exactly match
   the declaration under which the function was compiled. eg,
      (PROCLAIM '(FUNCTION FOO (INTEGER) INTEGER))
      (DEFUN FOO (X) (+ X 1))
   could be matched in another file by
      (LOCALLY (DECLARE (FUNCTION FOO (INTEGER) INTEGER)) ... (FOO ...) ...)
   but not by
      (LOCALLY (DECLARE (FUNCTION FOO (FIXNUM) FIXNUM)) ... (FOO ...) ...)
   or (LOCALLY (DECLARE (FUNCTION FOO (T) T)) ... (FOO ...) ...)

   This would have the best chance of getting interesting compilations, I think.

 * We could, as I guess Pavel is suggesting (though I lost or missed the
   original mail), allow multiple declarations of the same function, in which
   case the information provided would be of an entirely different nature (in
   what amounts to a DEFMETHOD style) than what it's used for in the previous
   three bullet items.

   Presumably there are some gains to be had from this style. I have no feel for
   how useful they are. An example, though, would be:
      (PROCLAIM '(FUNCTION FOO (LIST) LIST))
      (PROCLAIM '(FUNCTION FOO (VECTOR) VECTOR))
   which would let you compile
      (LENGTH (FOO (THE LIST L)))
   into
      (SYSTEM:LENGTH-ROUTINE-FOR-THINGS-KNOWN-TO-BE-OF-TYPE-LIST (FOO L))

   [Sigh. I'd have called it SYSTEM:LIST-LENGTH, but that's taken by CLtL for
    something that doesn't mean what I think of as LIST-LENGTH. A poor naming
    decision if you ask me...]

 * This is a placeholder to remind readers that the likelihood that this list is
   exhaustive is fairly low.

This really gets at the heart of the problem, which is:

 * Are declarations just for compilation or do they serve some more abstract
   higher level goal (eg, "documentation").

 * How important is exact-typep information vs typep information.

 * How much of a modularity violation (or documentation constraint) is it to
   have to know the exact conditions under which a function was compiled.

 * How important are optimal compilations?