Subject: Re: Embedding arbitrary chars in string literals
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 06 Apr 2003 04:58:30 -0500
Newsgroups: comp.lang.lisp
Message-ID: <k46cnTVb1s_bZxKjXTWc-g@speakeasy.net>
Peter Seibel  <peter@javamonkey.com> wrote:
+---------------
| "Steven M. Haflich" <smh_no_spiced_ham@alum.mit.edu> writes:
| > Note that load and compile-file are defined to bind *readtable* and
| > *package* to themselves. ...
| > 
| > Similarly for *readtable*...
| 
| And then, if you want to be a good citizen, at the end of the file,
| you'll probably want to do something like this, right?
| 
|   (eval-when (:compile-toplevel :execute)
|     (setf *readtable* ... squirreled away original readtable ...))
| 
| Or maybe wrap your call to COMPILE-FILE like:
| 
|   (let ((*readtable* (copy-readtable))) (compile-file "foo.lisp"))
| 
| so the mucking around with *readtable* within the file doesn't linger
| after you're done and affect other files. Is that more or less right?
+---------------

Uh... Look again at what Steven wrote above [extra emphasis added]:

	Note that load and compile-file are __DEFINED__ to bind
	*readtable* and *package* to themselves.

From <URL:http://www.lispworks.com/reference/HyperSpec/Body/f_load.htm>:

	Function LOAD
	...
	load binds *readtable* and *package* to the values they held
	before loading the file.

From <URL:http://www.lispworks.com/reference/HyperSpec/Body/f_cmp_fi.htm>:

	Function COMPILE-FILE
	...
	compile-file binds *readtable* and *package* to the values they
	held before processing the file.

Therefore the values of both variables are automatically restored to
their previous values after LOAD'ing or COMPILE-FILE'ing a file, and
thus it is perfectly safe to SETF them in the file without restoring
them in the file.

Of course, one should be careful of the distinction between binding/assigning
a variable versus changing the object it is bound/assigned to, and always
mutate a *copy* of the current readtable rather than mutating the readtable
object which was current when the file started loading. Which is why Steven
wrote this:

+---------------
| >    (eval-when (compile eval)
| >      (setf *readtable* ... code that finds or constructs a readtable ...))
+---------------

instead of this:

	(eval-when (compile eval)
	  (set-dispatch-macro-character ...blah...blah...)
	  (set-macro-character ...blah...blah...)
	  ...
	  )

That is, as long as the code at the top of your file looks something
like this:

	(eval-when (compile eval)
	  (setf *readtable* (copy-readtable))  ;or maybe (copy-readtable nil)
	  (set-dispatch-macro-character ...blah...blah...)
	  (set-macro-character ...blah...blah...)
	  ...
	  )
	;;; Now use special syntax...

you won't need to do anything at all at the end of the file *or* in any
program which loads or compiles the file.


-Rob

-----
Rob Warnock, PP-ASEL-IA		<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607