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

Access to lexical environment?



  Date: Sun, 8 Nov 87 21:12:26 EST
  From: futrell%corwin.ccs.northeastern.edu@RELAY.CS.NET
  
  I am not sure how to properly develop simple extensions to Lisp
  syntax (using CL).  For example, suppose that I'd like to set up a
  way to create new things that has the following (familiar) syntax:
  
  (def-newthing fred (other-thing) ((n :initform (+ a b))
				    (ls :initform (rest ls1)))
				   ...etc.)
  
  Now a,b, and ls1 would typically be lexically scoped.  Given this, how
  do I define "def-newthing"?  If I use defun, it will attempt to
  evaluate (other-thing), and worse, ((n :initform ....)).  This won't
  work.  If I use defmacro, when I pull out an initform to evaluate, such
  as (+ a b), the defmacro won't allow me access to the lexical bindings
  of a and b.  

The mechanism in Lisp for capturing the lexical environment is LAMBDA.
Try this

(defmacro def-newthing (name superthings specs)
  `(progn (setf (getf ',name 'superthings) ',superthings)
	  (setf (getf ',name 'slots)
		(list ,@(map 'list
			      (lambda (spec)
				(destructuring-bind (name &key initform) spec
				  `(list ',name (lambda () ,initform))))
			      specs)))))

(def-newthing fred (other-thing) ((n :initform (+ a b))
				  (ls :initform (rest ls1))))
 ==> (PROGN (SETF (GETF 'FRED 'SUPERTHINGS) '(OTHER-THING))
	    (SETF (GETF 'FRED 'SLOTS)
		  (LIST (LIST 'N (LAMBDA () (+ A B)))
			(LIST 'LS (LAMBDA () (REST LS1))))))

I hope this clarifies the situation for you.