For better or worse, our application generates lots of interned symbols. MCL seems to garbage-collect interned symbols after a while when they are no longer referenced (which hasn't caused a problem so far), while Allegro CL seems to keep them around forever (which causes it to bog down and crash if given enough time).
I have a couple of questions:
0) Is the above description accurate?
1) What is the correct behavior, if there is one (CLTL2 has little to say)?
2) Is there a way to get rid of interned symbols that are no longer needed that is safer and more efficient than to explicitely unintern them individually?
"The ANSI CL spec unfortunately prevents garbage collection of interned but unused symbols (because of FIND-SYMBOL, and INTERNs second value). I'm glad they did not repeat this mistake for classes, and did not include the MOP."
-- Fernando D. Mato Mira Real-Time SW Eng & Networking Advanced Systems Engineering Division CSEM Jaquet-Droz 1 email: matomira AT acm DOT org CH-2007 Neuchatel tel: +41 (32) 720-5157 Switzerland FAX: +41 (32) 720-5720
In article <389F2006.B9348...@iname.com>, Fernando D. Mato Mira <matom...@iname.com> wrote:
>And I quote Bruno..
>"The ANSI CL spec unfortunately prevents garbage collection of interned but >unused symbols (because of FIND-SYMBOL, and INTERNs second value). I'm glad >they did not repeat this mistake for classes, and did not include the MOP."
Sure, it would change the result of FIND-SYMBOL, DO-SYMBOLS, etc., but how could a program possibly care? Unless it has a reference to the symbol that used to be interned (which would then prevent the symbol from being GC'ed), why would it care if INTERN returns a new symbol rather than an old one?
The only way this could affect a program is if it were using the package system as a general-purpose lookup mechanism. In Maclisp obarrays were often used as a substitute for hash tables, but there's no reason for that to be done in Common Lisp.
However, if a symbol has anything in its property list, value cell, or function cell then it should *not* be GC'ed. If it is, you lose those references, which could be important.
Maclisp had an option called "GCTWA" -- GC Truly Worthless Atoms. It controlled whether symbols which were only referenced by obarrays would be GC'ed.
-- Barry Margolin, bar...@bbnplanet.com GTE Internetworking, Powered by BBN, Burlington, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
* Christian Lebiere <c...@andrew.cmu.edu> | For better or worse, our application generates lots of interned symbols.
well, if you don't use the Lisp reader to find symbols by name, there are always a number of available solutions better than using interned symbols. if, say, you only use symbols as unique keys, but whose name does not actually matter, a fresh cons cell like (nil . nil) may be used as long as you keep the key around someplace else. if the name matters, you can also use a string.
| MCL seems to garbage-collect interned symbols after a while when they are | no longer referenced (which hasn't caused a problem so far), while | Allegro CL seems to keep them around forever (which causes it to bog down | and crash if given enough time). | | I have a couple of questions: | | 0) Is the above description accurate?
no. an interned symbol is ipso facto referenced -- by the very package in which it is interned!
moreover, whether a symbol is "useless" or not is not determined by what references the symbol, but by what the symbol references -- quite the opposite of your concern. the whole point with an interned symbol is that it holds onto some values and that there might be a reference to those values in the future through the symbol by its name read from an outside source, so _clearly_ we can't chuck interned symbols -- it would defeat the fundamental purpose of symbols. (aggressive short-sightedness is required to label this fact "unfortunate", as some evidently do.)
| 1) What is the correct behavior, if there is one (CLTL2 has little to say)?
since MCL is clearly in the wrong as you have described it, I'm inclined to think that something else is at work.
btw, CLtL2 is no longer _the_ language reference. use the HyperSpec (or the standard).
| 2) Is there a way to get rid of interned symbols that are no longer | needed that is safer and more efficient than to explicitely unintern them | individually?
DELETE-PACKAGE gets rid of the last reference to interned symbols that have no references, for all symbols in that package. you could always copy the symbols you need to a new package, and do your own copying garbage collection that way.
iterators over symbols are allowed to unintern the symbol it looks at. you may want to use DO-SYMBOLS over the symbols in a package to get rid of the ones you don't need.
it sounds as if what you _really_ want is a weak hash table that you index with _some_ unique key, as outlined at the start of this message.
The important piece to that statement is 'after a while', it doesn't always throw it out on the first gc (but sometimes it does). Here are 2 traces from MCL showing the point.
Welcome to Macintosh Common Lisp Version 4.2! ? (intern "BAZ") BAZ NIL ? (gc) NIL ? (dotimes (i 100) (gentemp "FOO")) NIL ? (gc) NIL ? (dotimes (i 50) (gentemp "FOOBAR")) NIL ? (gc) NIL ? (find-symbol "BAZ") NIL NIL
Welcome to Macintosh Common Lisp Version 4.2! ? (dotimes (i 10) (intern (symbol-name (gensym "FOO")))) NIL ? (do-symbols (x *package*) (let ((name (symbol-name x))) (when (and (> (length name) 3) (string= (subseq name 0 3) "FOO")) (pprint x))))
>>>> In message <14709548.3158918...@pc34763.psy.cmu.edu> >>>> On the subject of "Interned Symbols and GC" >>>> Sent on Mon, 07 Feb 2000 13:29:25 -0500 >>>> Honorable Christian Lebiere <c...@andrew.cmu.edu> writes:
>> For better or worse, our application generates lots of interned >> symbols.
you probably use `read' on a stream which was not originally inteneded to be read by lisp. I have the same problem. when foo:bar (which calls read) is called from the package zot, it internes in zot. I wish I could control where the symbols are interned. (e.g., with *read-intern* which can be NIL for no interning, T for interning in *package* and a package to intern in that package).
-- Sam Steingold (http://www.podval.org/~sds) Micros**t is not the answer. Micros**t is a question, and the answer is Linux, (http://www.linux.org) the choice of the GNU (http://www.gnu.org) generation. main(a){printf(a,34,a="main(a){printf(a,34,a=%c%s%c,34);}",34);}
* Sam Steingold <s...@gnu.org> | when foo:bar (which calls read) is called from the package zot, it | internes in zot. I wish I could control where the symbols are | interned. (e.g., with *read-intern* which can be NIL for no interning, | T for interning in *package* and a package to intern in that package).
this makes _zero_ sense. you're not calling functions "from" any packages in Common Lisp. the default package used by INTERN is the value of *PACKAGE*, and READ doesn't do anything magical in the absence of a package specification, so if you want to control the package into which INTERN interns symbols, justbind *PACKAGE* to that package.
In article <0scLsyu00UiA01n...@andrew.cmu.edu>, Daniel J Bothell
<db...@andrew.cmu.edu> wrote: > The important piece to that statement is 'after a while', it doesn't > always throw it out on the first gc (but sometimes it does). Here are 2 > traces from MCL showing the point.
Hmm, I'm observing it, too. I'll ask Digitool about it.