It checks if the expression is constant in null lexical environment, and if it is, evaluates it; but the value of an expression that is constant in null lexical environment is not necessarily the same when evaluated in given environment (because of possible lexical shadowing of functions / macros / symbol-macros).
I was able to construct a counterexample only on ACL, as other implementations don't macroexpand the expression when given to constantp. (Although because of https://github.com/marcoheisig/sealable-metaobjects/issues/3 can't test it in the context of fast-generic-funtions.)
CL-USER> (lisp-implementation-type)
"International Allegro CL Free Express Edition"
CL-USER> (defun compiler-typep (form type environment) ...)
COMPILER-TYPEP
CL-USER> (defmacro macro-integerp (form &environment env)
(compiler-typep form 'integer env))
MACRO-INTEGERP
CL-USER> (define-symbol-macro %x 10)
%X
CL-USER> (defmacro foo ()
'(values %x (macro-integerp %x)))
FOO
CL-USER> (foo)
10
T
CL-USER> (symbol-macrolet ((%x :symbol))
(foo))
:SYMBOL
T ;; should be NIL!
It checks if the expression is constant in null lexical environment, and if it is, evaluates it; but the value of an expression that is constant in null lexical environment is not necessarily the same when evaluated in given environment (because of possible lexical shadowing of functions / macros / symbol-macros).
I was able to construct a counterexample only on ACL, as other implementations don't macroexpand the expression when given to
constantp
. (Although because of https://github.com/marcoheisig/sealable-metaobjects/issues/3 can't test it in the context of fast-generic-funtions.)