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

Common Lisp Problems - Can't write a code walker

This is the first of a few messages describing the problems I have had
with Common Lisp while writing Portable Common Loops.  This message
lists some reasons why it is *hard* to write a portable code walker in
Common Lisp.  This message doesn't propose detailed solutions to these
problems, it mostly just states the problems.

- You can't query to find the current state of global proclamations.
Specifically, you can't ask if a variable has been declared globally
special.  This doesn't make is impossible to write a code walker since
you can write a little piece of code to test if a variable is special,
but it is a nuisance.  This piece of code from PCL shows the problem: 

#-(or Symbolics Xerox TI VaxLisp KCL LMI)
(defvar *globally-special-variables* ())

(defun variable-globally-special-p (symbol)
  #+(or Symbolics Lucid TI LMI) (get symbol 'special)
  #+Xerox                       (member symbol globalvars)
  #+VaxLisp                     (get symbol 'system::globally-special)
  #+KCL			        (proclamation `(special ,symbol))
  #-(or Symbolics Lucid TI LMI Xerox VaxLisp KCL)
  (or (not (null (member symbol *globally-special-variables* :test
      (when (eval `(flet ((ref () ,symbol))
		     (let ((,symbol '#,(list nil)))
		       (and (boundp ',symbol) (eq ,symbol (ref))))))
	(push symbol *globally-special-variables*)

KCL has a function called PROCLAMATION which takes the same arguments as
proclaim and returns t if that PROCLAIM is in effect.  Perhaps Common
Lisp should have a function called PROCLAIMP which works the same way as
the KCL proclamation function.  

2- Lack of clarity and lack of functionality with regard to

Common Lisp doesn't *clearly* provide a mechanism to make an environment
that has certaion function macro or lexical variable bindings.  Or to
make an environment that is based on some existing environment but has
extra bindings.  Or to query an environment about its bindings.  In I
tried to get around this problem with a weird evalhook macroexpand hack.
But it isn't completely portable.  CommonLisp needs defined mechanisms
for manipulating these environment structures.

3- Implementations have special forms in their extended lisps that are
not Common Lisp special forms.  I don't know if there is anything we can
do about this, but I thought I would mention it.  (I suppose we could
agree on a common syntax for defining code walker templates and a common
mechanism for retrieving them but that doesn't seem too likely).