Message from discussion
`fast' global variables (Ex: Re: ??: using * for variable ?)
From: Kent M Pitman <pit...@world.std.com>
Subject: Re: `fast' global variables (Ex: Re: ??: using * for variable ?)
Date: 1999/03/24
Message-ID: <sfwww07u2z9.fsf@world.std.com>#1/1
X-Deja-AN: 458191653
Sender: pit...@world.std.com (Kent M Pitman)
References: <Pine.SOL.3.96L.990311113423.1033S-100000@russell2.phil.cmu.edu> <djvhfzerqc.fsf@praeclarus.demon.co.uk> <7csm6k$31f$1@nnrp1.dejanews.com> <djsob1c7ij.fsf@planet.praeclarus.demon.co.uk> <bICI2.13$kM2.772@burlma1-snr2> <36F31455.35F0CCB4@IntelliMarket.Com> <7d4165$acl$1@nnrp1.dejanews.com> <36F66BFC.A7EA65D7@elwood.com> <sfwbthlqshb.fsf@world.std.com> <7d6dtj$bp0$1@nnrp1.dejanews.com> <7d6fdb$egv$1@spitting-spider.aracnet.com> <3131135071149992@naggum.no> <7d6pos$h6f$1@spitting-spider.aracnet.com> <3131171314435096@naggum.no> <7d8h8q$f53$1@spitting-spider.aracnet.com>
Organization: The World Public Access UNIX, Brookline, MA
Newsgroups: comp.lang.lisp
mike...@mikemac.com (Mike McDonald) writes:
> The part where you're adding the immutable to it. At least in the hyper
> spec's glossary, which you quoted, it does NOT say literal objects are
> immutable.
That's because, as I understand it, literal objects are not immutable.
But literal objects seen by the file compiler are.
In particular, I think:
(let ((x (list nil)))
(compile nil `(lambda () ',x)))
returns a function that yields a modifiable literal. It is the process
of externalization, not the process of semantic processing per se, that
renders an object immutable. As I recall, anyway.
There is an ordering problem here in the design of the language. We
reached this conclusion after much debate because we didn't yet have
LOAD-TIME-VALUE. We later added LOAD-TIME-VALUE because this matter
was so confusing and contentious but we didn't go back and clean up the
mess in EVAL. Now that there's LOAD-TIME-VALUE there is no essential
reason that all quoted things couldn't be immutable. But in the pre
LOAD-TIME-VALUE days there was an important efficiency reason why it
was important that code be able to return a "literal" that was still
"mutable" even if such code had to be itself created at loadtime in
"impure space" (or whatever they call data on non-read-only pages
these days.
> A literal object is that one, unique object. It says nothing about
> the status of its contents. In their example of '("two"), it's the
> cons cell that is the literal object being refered to, not the
> string "two" or the NIL on the end. Granted, in this example, you'd
> confuse most people by replaca-ing the list, but I don't see
> anything in this definition that it says you can't.
Yes, I agree with this analysis philosophically, though the record is
a bit muddled and both you and Erik are probably slightly confused because
the language itself is slightly confused on this point.
"Sorry about that."
> In every case where I've seen (defconstant *foo* (make-array ...)) used,
> what was intended that *foo* would always point to the same array, not that
> the array's contents would always be the same. But heck, with MCL's
> interpretation that it can be a different array in every compiled file,
> DEFCONSTANT doesn't mean anything useable.
Right. Externalization is a mess. As I recall, an example place
where it matters is in CLOS-like dispatching where you want to AREF
out of a table that can have known address at load time but that still
wants to be mutable to accomodate redefinition. If you require that
it live in a special variable, you have to do what the pdp10 called a
MOVE instruction (an instruction that takes an argument of a memory
location and does a memory read from that location); to access a
quoted constant, you can get away with a MOVEI (immediate move, where
you don't have to do a memory access because you know the "from" value
and can represent it in the code vector instead of in the heap). So,
in principle, (AREF (LOAD-TIME-VALUE ...) I) is possible to make
faster than (AREF +SOME-CONSTANT+ I) because the former can (in
principle) be made a MOVEI, while it's hard to tell how the second
could be any better than a MOVE indirect through +SOME-CONSTANT+'s
value cell (unless you put the value cell in the code vector itself
and there was never more than one such code vector, but that's pretty
odd). I don't know modern instruction sets well enough to know what
the instruction options are, so my apologies for picking such an old
one. Of course, an actual CLOS implementation is probably
system-provided and doesn't have to fuss about this, but if you wanted
to duplicate things CLOS does yourself with no loss of efficiency,
you'd want something this powerful to avoid losing a memory cycle on
some architectures.