From: Hoehle, Joerg-C. <Joe...@t-...> - 2006-04-18 14:07:56
|
Nico wrote: >I posted before on this list on the same subject. However, I=20 >investigated some more after that. Thanks for taking the time to make a short example so I could look at = it. The parts relevant to the issue are >(def-c-var sequencetab and > (dolist (var '(sequencetab)) > (set var (read stream))))) IMHO this codes assumes undocumented behaviour of CLISP. DEF-C-VAR introduces a global symbol macro. Introducing a symbol macro = changes the interpretation of programs. E.g. the interpreter (and = compiler) will assign a new meaning to an occurrence of the form = SEQUENCETAB, and substitute the macro definition. However, using SET (aka SETF SYMBOL-VALUE) "bypasses" interpretation of = programs. It accesses the value cell of a symbol. Your program expects that cell to contain something related to the = interpretation of programs. But normally, such information is kept in = what's called the environment. >This 'works' with clisp 2.33. Indeed, on 2005-01-01 Bruno Haible introduced a change which made = global symbol macros orthogonal to symbol-value. Before that, the symbol macro definition where found in a symbol's = value cell. SET and SYMBOL-VALUE where special-cased so as to perform = the substitution. In effect they were doing part of the interpreter's = job. Since the change, the substitution is kept in the interpreter's (or = compiler's) environment -- where it arguably belongs. SYMBOL-VALUE is left untouched, and freely available. I don't know what motivated this change last year. Great (disappointing?) news, now let's return to your problem: >(defun load-seq (filename) > (with-open-file (stream filename :direction :input=20 > :if-does-not-exist :error) > (dolist (var '(sequencetab)) > (set var (read stream))))) >(load-seq "Mandseq-file") It looks like your functions "expects" to alter the interpretation of = the symbol SEQUENCETAB. This is a job of the interpreter (or = compiler), and SET or SYMBOL-VALUE will not manage to do so (anymore). So you need to modify the environment. Your initial example was: >(defmacro def-i/o (writer-name reader-name (&rest vars)) >(def-i/o save-seq load-seq (sequencetab)) Since you statically know the names of the variables involved, you can = have def-i/o generate the following snippet of code: ... (setq/setf sequencetab (read stream)) [As usual, use macroexpand-1 to test macro output.] Then the interpreter (and compiler) will do the right thing, since they = know (from their environment) that sequencetab is a foreign variable. It's purely lexical, there's no need for SPECIAL declarations or = SYMBOL-VALUE. Regards, J=F6rg H=F6hle. |