[Ecls-list] turn off auto declares

Dean O'Connor dean.oconnor at ite.com.au
Thu Nov 24 22:51:01 UTC 2005


Cool. It all works nicely. It really helped me find logical errors in 
code :)
I found just shadowing setq in cl-user worked fine too (instead of those 
3 package statements).
ie.

(shadow 'setq 'cl-user)

(defun var-declared-in-ecl-env (var env)
   (assoc var (car env)))

(defmacro setq (var value &rest rest &environment env)
   (let (form)
     (setf form
	   (if (or (consp var) (var-declared-in-ecl-env var env))
	       `(cl:setq ,var ,value)
	       `(if (boundp ',var)
		 (cl:setq ,var ,value)
		 (error "Tried to assign a value to undefined variable ~A" ',var))))
     (if rest
	 `(progn ,form (setq , at rest))
	 form)))


cheers
Dean.

Juan Jose Garcia Ripoll wrote:

>On Thu, 2005-11-24 at 12:09 +1100, Dean O'Connor wrote:
>  
>
>>I don't know if this is possible, but it would also be great if there 
>>was a further option for setq to trip errors only at execution time.
>>    
>>
>
>I'd rather not include that on "standard" ECL. SETQ is not really a
>function. It is a special form. Adding such option would mean adding a
>check for a global flag on many spots by, perhaps, redefining the
>ECL_SETQ macro. That would be a real performance hog. As I show below,
>however, your problem has a solution using standard Common Lisp plus
>some environment magic.
>
>  
>
>>I my situation, my globals (dynamic specials) are created/bound in a 
>>root function and accessed by functions called by that execution path.
>>(I am trying to use this method for allowing per thread "globals" on an 
>>execution path.)
>>
>>For example:
>>
>> > (SETQ EXT:*ACTION-ON-UNDEFINED-VARIABLE* 'ERROR)
>>Error
>> > (defun foo ()
>>        (let ((*global* 1))
>>             (declare (special *global*))
>>             (print *global*)
>>             (bar)
>>             (print *global*)))
>>Foo
>> > (defun bar ()
>>         (setq *global* 2)
>>         (setq undefined-local 3))
>>Undefined variable referenced in interpreted code.
>>Name: *Global*
>>Top level.
>> >>
>>
>>Instead, if the defun of bar didn't throw an error, but when foo is 
>>called, thus calling bar, only the 2nd setq fails, since at this point
>>*global* is bound, whereas undefined-local is not.
>>    
>>
>
>The problem is that, even if FOO declares *GLOBAL* to be special,
>special declarations only has effect on the function in which it
>appears, not on the rest of functions. There is no magic flag that
>converts *GLOBAL* suddenly on a special variable, and functions to be
>called have no standard way of testing whether *GLOBAL* is a special
>variable. Not even in standard Common Lisp.
>
>Only thing I can recommend you is to do something like what I show in
>the attached file (foo.lsp), which redefines SETQ. When you load it in
>the interpreter, it will complain about the only undefined variable. You
>have, however, to use the new SETQ everywhere and ensure that any
>DEFVAR/DEFPARAMETER has a value (it is not enough to declare the
>variable special: it has to have a value to be detected at run time).
>
>  
>
>>(load "~/foo")
>>    
>>
>;;; Loading #P"/home/jlr/foo.lsp"
>Tried to assign a value to undefined variable *D*
>Broken at EVAL.
>MY-LISP>> :q
>Top level.
>
>Regards,
>
>Juanjo
>
>  
>
>------------------------------------------------------------------------
>
>(when (find-package "MY-LISP")
>   (delete-package "MY-LISP"))
>
>(defpackage "MY-LISP"
>	(:use "COMMON-LISP")
>	(:shadow "SETQ"))
>
>(in-package "MY-LISP")
>
>(defun var-declared-in-ecl-env (var env)
>   (assoc var (car env)))
>
>(defmacro setq (var value &rest rest &environment env)
>   (let (form)
>     (setf form
>	   (if (or (consp var) (var-declared-in-ecl-env var env))
>	       `(cl:setq ,var ,value)
>	       `(if (boundp ',var)
>		 (cl:setq ,var ,value)
>		 (error "Tried to assign a value to undefined variable ~A" ',var))))
>     (if rest
>	 `(progn ,form (setq , at rest))
>	 form)))
>
>(let ((a 2))
>  (setq a 2))
>
>(let ((*b* 2))
>  (declare (special *b*))
>  (setq *b* 2))
>
>(defvar *c* 2)
>
>(setq *c* 2)
>
>(setq *d* 3)
>  
>




More information about the ecl-devel mailing list