[Openmcl-devel] Why is remhash being called here?
Ron Garret
ron at flownet.com
Sun Jun 30 18:20:35 PDT 2013
On Jun 30, 2013, at 2:08 PM, Gary Byers wrote:
> My guess is that REMHASH is being called to remove something from a hash table.
Yes. That much I was actually able to figure out on my own.
> If your next question is going to be something like "what hash table, and why
> is a hash table apparently being maintained when forms are being read bv the
> REPL (in this case) ?", a short answer is that this is involved in making
> M-. (the editor command) work in more cases for more people and in allowing
> DISASSEMBLE to annotate its output with the corresponding source code.
That would make sense except for two things:
1. This happens in the command-line version too where there is no meta-.
2. REMHASH is (apparently) only called when I evaluate a form that invokes a reader macro.
I know the toplevel does some things besides simply calling (print (eval (read))) but AFAIK none of those things should care (of even know) that a reader macro had been invoked. Hence my puzzlement.
> If your next question is going to be "aren't there significant costs involved
> here, and do the benefits justify those costs ?", my answer would be a resounding ...
> oh wait, you haven't really asked that question. Never mind.
Indeed, I have not asked that question. I'm really just trying to understand why the toplevel is doing something different when a reader macro is invoked.
In hopes of being deemed worthy of a non-snarky answer, I did some more digging on my own. The function that is calling remhash turns out to be ccl::read-recording-source:
? (trace ccl::read-recording-source)
NIL
? '$x
0> Calling (CCL::READ-RECORDING-SOURCE #<GUI::COCOA-LISTENER-INPUT-STREAM #x30200221A4BD> :EOFVAL (NIL) :FILE-NAME NIL :START-OFFSET NIL :MAP #<HASH-TABLE :TEST EQ size 0/60 #x30200221F89D> :SAVE-SOURCE-TEXT T)
1> Calling (REMHASH $X #<HASH-TABLE :TEST EQ size 2/60 #x30200221F89D>)
<1 REMHASH returned T
<0 CCL::READ-RECORDING-SOURCE returned 2 values :
<0 '$X
<0 #<SOURCE-NOTE Interactive "'$x ">
So the code that is calling remhash is (apparently):
(defun read-recording-source (stream &key eofval file-name start-offset map save-source-text)
"Read a top-level form, perhaps recording source locations.
If MAP is NIL, just reads a form as if by READ.
If MAP is non-NIL, returns a second value of a source-note object describing the form.
In addition, if MAP is a hash table, it gets filled with source-note's for all
non-atomic nested subforms."
...
(loop for form being the hash-key using (hash-value note) of map
do (cond ((eq note source-note) nil)
;; Remove entries with multiple source notes, which can happen
;; for atoms. If we can't tell which instance we mean, then we
;; don't have useful source info.
((listp note) (remhash form map))
((loop for p = note then (source-note-source p) while (source-note-p p)
thereis (eq p source-note))
;; Flatten the backpointers so each subnote points directly
;; to the toplevel note.
(setf (source-note.source note) source-note))))
But '$x doesn't have multiple source notes. It shouldn't have any source notes at all. And this code is beyond the limits of my ability to reverse-engineer it. So any additional light you (or anyone else) could shed on this would be much appreciated.
rg
More information about the Openmcl-devel
mailing list