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

Re: readtable within fasl



I too was bothered by fasl's insistence on using the standard readtable
to process literals in liszt-compiled files until I realized the reason
for this limitation:

All source input to liszt is processed by `read' -- that is, the
compiler reads only forms, never ascii strings.  In order to place a
literal form in an object file, liszt must essentially convert the form
back into ASCII via `print'.  (Actually, a somewhat modified version
which knows how to wrap an assembler `.asciz' directive around the
printed representation of the form, etc.)  Unfortunately, liszt can make
no easy assumption about what strange readtable is likely to be active
at load time, so the only sane choice is to use the standard readtable.

In other words, you shouldn't think of literal forms stored in a fasl
object file as external (ASCII) representation of lisp data.  Rather,
liszt/fasl use ASCII as a convenient "position-independent" encoding of
a form which has already been processed by read at compile time.  This
is entirely analogous to what traditional compilers and assemblers do
with numeric constants represented in ASCII inside a program, except
their compiler-to-loader data format uses the native binary number
representation of the object machine.

One could argue that this isn't really a limitation provided one is
willing and able to provide the desired readtable at compile time.
Usually this isn't a problem, although I once I had a macro which wanted
to insert into a form a particular uninterned symbol which (obviously)
couldn't even exist until execution time.  I was forced to wrap the form
inside another function which would accomplish the substitution at load
time.

There is no reason liszt could not be made to copy ASCII forms into the
fasl file without read->print translation, but this would require
changes to the compiler and to fasl format, things not to be done
lightly.  If you *really* need the facility, and don't need to read huge
volumes of data, you could include ASCII forms inside a fasl file by
encoding them as lisp strings, and seeing that they get processed by an
appropriate function at load time, something like:

	(defun strange-read (str)
	       (let ((readtable strange-readtable))
		    (readlist (explodec str))))

Then you can do things like:
	(setq foo (strange-read ") a b )c d( e (")

[What?  You don't like my readtable with the parens reversed?]  The
invocation of `strange-read' can, of course, be conveniently macrofied.
If appropriate, automatic printing of literal strings can also be
performed by compile time macros.  You will have to deal with the
problem of escaping quotes inside these forms, and you might want to
enable string garbage collection if you do a lot of this sort of thing.

I know it's ugly, but...

Steve Haflich