Speaking of TXR, and of "holding on weakly", as a result of this discussion, I made a little change.
A remark was made somewhere that interned symbols are held with a non-weak reference. But it occurred to me that this isn't something engraved in stone. A package should be able to hold on to its interned symbols via weak references. This means that if the only reference to a symbol is from within a weak package, that symbol can be removed from the package and relclaimed by the garbage collector.
Since a package uses hash tables, and hash tables support weak keys, it's trivial to put the two together. I added an argument to make-package to specify a weak package.
In the following test, the symbols interned into package foo get reclaimed because it is weak. Those interned into bar don't get reclaimed:
(defun weak-package-test (name weak)
(let ((wp (make-package name weak)))
(let ((*package* wp))
(let ((obj (read "(a b c d e f)")))
(mapcar (op finalize @1 prinl) obj)))))
(weak-package-test "foo" t)
(sys:gc t)
(weak-package-test "bar" nil)
(sys:gc t)
$ ./txr weak-package.tl
foo:a
foo:b
foo:c
foo:d
foo:e
foo:f
A remark was made somewhere that interned symbols are held with a non-weak reference. But it occurred to me that this isn't something engraved in stone. A package should be able to hold on to its interned symbols via weak references. This means that if the only reference to a symbol is from within a weak package, that symbol can be removed from the package and relclaimed by the garbage collector.
Since a package uses hash tables, and hash tables support weak keys, it's trivial to put the two together. I added an argument to make-package to specify a weak package.
In the following test, the symbols interned into package foo get reclaimed because it is weak. Those interned into bar don't get reclaimed:
I'm committing to this as a documented feature.