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

Constant-Function



   From:	IN%"edsel!jonl@labrea.stanford.EDU"  "Jon L White" 11-MAY-1988 05:47
   
   re: Knowing the FTYPE of sqrt does not allow a compiler to substitute 2.23 for
       (sqrt 5).  You might redefine SQRT as SIN without violating the FTYPE.
   
   Right.  So your intention for "constant function" really was more along the
   line of "constant foldable" (or "reducible"), just as I guessed in my first 
   message?

No.  This is a special case of constant function.  The general definition
of constant-function is that it promises never to (incompatibly) redefine
the function.  Constant folding can occur by two processes.
(1) The compiler can open-code SQRT (above) or FOO (below) and 
algebraically simplify the result.  In this case we are assuming
the simplifying did very well and reduced the code to a constant.

(2) The compiler somehow knows that the function is reducible,
and proceeds to evaluate the form (in the compilation environment)
and substitute the result.

   In fact, "constant function" by this definition doesn't even imply a
   constant argument sepectrum.  Imagine a function (defun foo (x y) ...)
   which is "folded" as follows: (foo 2 3) --> 5; then at runtime the user
   redefines it as (defun foo (x y &optional z) ...) in such a way that
   (foo 2 3)  =  (foo 2 3 nil)  =  5.   No violation of compiler optimizations.

This doesn't make any sense to me.  This redefinition "is an error" but
you will probably get away with it.  The fact that in this one example
we have not depended upon the fixed FTYPE aspect of a 'constant-function'
does not make it legitimate to overgeneralize and assume that 
in no example is the FTYPE crucial.  
   
   re: Some Symbolics users use ' in place of #' to get around this bug. (!)
       I think it exists exactly because the 'constant-function' declaration
       is missing, . . . 
   
   Well, Hornig did mention, and others concurred, that the much more common
   case is to want this assumption; and having to place extra declarations
   around all the common cases would be a pain.

In itself this isn't important, but it leads to the general question of
what constant-function is intended for.  The relevant buzzwords
are "layered systems" and "block-compilation".  Initially a
function definitoin must be considered somewhat tentative.
Perhaps the semantics aren't quite right.  Perhaps there is a bug
in the definition.  In any case it is important that redefinition
and tracing work correctly.  Eventually this prototype phase ends,
and the function definition can be fixed with constant-function.
Subsequently the compiler can use knowledge about the arguments,
body and even compiled code for the constant-function.  ("Snapping
uuolinks" as Maclisp called it is effectively an optimization at
the compiled code level.)

If you believe this model of software development then Hornig's point
is wrong.  You do not need "extra declarations arount all the common cases"
because you (generally) use a single PROCLAIM for every function in
the base layer of your system.  (Hence the motivation to associate
the declaration with the DEFUN.)  Happily the Common Lisp declaration
system also provides fine-grained control of this form of block
compilation.