Portable type propagation in common lisp inlined functions without compiler-macros

Viewed 54

Say, I have the following:

(declaim (inline fun-1 fun-2))
(defun fun-1 (a)
  a)
(define-compiler-macro fun-1 (&whole form a &environment env)
  (print (introspect-environment:variable-type a env))
  form)
(defun fun-2 (a)
  (declare (type number a))
  (fun-1 a))
(define-compiler-macro fun-2 (&whole form a &environment env)
  (print (introspect-environment:variable-type a env))
  form)

Then, on compiling (fun-2 a) form, the additional type information gets lost.

CL-USER> (compile nil `(lambda (a)
                         (declare (type fixnum a))
                         (fun-2 a)))

FIXNUM 
NUMBER 
#<FUNCTION (LAMBDA (A)) {52E6BBDB}>
NIL
NIL

Is there a way to preserve that a is fixnum without using compiler-macros?

*The 'portable' in the title is because, SBCL does infer that a is a fixnum even inside fun-1 in its later stages of compilation; I wanted a portable-to-other-implementations method of doing it using cltl2.

**The compiler macros here are only for demonstration purposes. My original use case involved having a compiler macro for fun-1 but not for fun-2. And indeed, this can be achieved using compiler-macros; I wanted to know if there is a way to do it without them.

0 Answers
Related