Integral lookup and CLISP



   From: RTATECH\" <David.Billinghurst at riotinto.com>
   
   I can reproduce this with CLISP 2.46 on cygwin, and I think that 
   CLISP is correct.
   
   The common lisp hyperspec for FUNCTIONP gives as examples:
    (functionp '(lambda (x) (* x x))) =>  false
    (functionp #'(lambda (x) (* x x))) =>  true
   CLISP conforms, but gcl gives true in both cases.

Here's an explanation.

In order for CLOS to make sense, when it was being considered by
X3J13, it was necessary that various important types be disjoint.
This is so generic functions can discriminate on argument classes.
There is an ancient Lisp tradition that a form can be consed up at
well and passed to the interpreter.  This is what EVAL does.  But the
language cleanup required by CLOS was to make the FUNCTION type
disjoint from nearly everything else.

[1]  (type-of '(lambda (x) x))              ==> CONS
[2]  (type-of #'(lambda (x) x))             ==> FUNCTION
[3]  (type-of (function (lambda (x) x)))    ==> FUNCTION
[4]  (type-of (lambda (x) x))               ==> FUNCTION
[5]  (function '(lambda (x) x))             ==> "undefined consequences"

Functions are created by executing the FUNCTION special form, by
COERCE, by COMPILE, and by form in LOAD.  The above results are
required from any conforming ANSI CL, except that the returned types
might be some known subtype of FUNCTION, e.g. COMPILED-FUNCTION.

Form [1] should be clear.  Forms [2] and [3] are the same, since #' is
simply reader macro abbreviation for FUNCTION.

Form [4] is the one that might not be clear to everyone.  The symbol
LAMBDA has since John McCarthy was a young man been a flag that
appears on the car of a cons to denote a "lambda expression".  But
almost the last language change made by X3J13 was to add a definition
of LAMBDA as a macro that could have been defined this way:

  (defmacro lambda (&whole whole &rest rest)
    (declare (ignore rest))
    `(function ,whole))

In other words, it is just a convenience macro eliminating the need to
type #' in front of anaonymous lambdas.

Form [5] might work in some Lisps under a strange notion of back
compatibility, but is not defined by the standard.  The functions
returned by [2] [3] [4] are defined in the surrounding lexical
environment and have access to variables, functions, block tags, and
go tags defined in that environment.  It isn't clear what [5] is
intended to do.  The lambda expression might be consed up at run time
preventing the compiler from knowing its details when compiling the
surrounding environment; and the compiler might not leave around
enough information about the surrounding lexical environment in order
to compile the lambda expression in it.  One of the unstated
assumptions in ANSI CL is that when a form (typically a cons tree) is
converted to a function, everything sharing a lexical environment is
converted at the same time, when eval or compile or compile-file
times.

   From: "Robert Dodier" <robert.dodier at gmail.com>

   (functionp '(lambda (x) (* x x)))
   (functionp #'(lambda (x) (* x x)))
   (functionp (lambda (x) (* x x)))

   on my Linux desktop box, I get NIL, T, T from Clisp, CMUCL, SBCL,
   ECL, and Allegro, while GCL returns T, T, T.

To clarify situations like this, I suggest also testing type-of along
with functionp.  From the above it is impossible to determine whether
FUNCTION and LAMBDA are nonconformant in this GCL release, or whether
FUNCTIONP is nonconformant.  It used to be common before the adoiption
of CLOS that implementations of FUNCTIONP would return true for
cons-trees that looked sort of like lambda expressions.  It's no
longer conforming.