* Paulo Madeira [2011-11-23 00:08] writes:
2011/11/22 Helmut Eller:
Currently we return nil by default. That way we can at least tell that the backend has no strong opinion on the matter and we simply use the current value of *package* as fallback. (...) Basically we are interested in the package that was current when the function was compiled.
This is quite interesting. Maybe it should be called "definition package" instead of "frame package".
I was thinking along the line that `e' in sldb reads (or used to read) the form in CL-USER (it seems) and evalutes it in the repl's package.
The debugger switches to the *buffer-package* if it is bound. That's bound before the evaluation is started (the one that triggers the debugger). Not sure if that is such a great idea, but it's what we currently do.
For instance:
(defpackage #:foo)
(defun test () (let ((*package* (find-package '#:foo))) (break)))
If you enter "(test)" in the repl while in package CL-USER, press `e' in frame "break" or "test" and enter "(symbol-package 'sym1)", you get the CL package.
CL-USER would be ok, but CL package is indeed unexpected.
If you enter "(cl-user::test)" in the repl while in package FOO and do the rest, you get the FOO package.
In my though, executing `symbol-package' shouldn't even succeed, since package FOO doesn't use CL. `sdlb-eval-in-frame' would read the form and execute it with the `*package*' of the current frame.
That's probably because you weren't aware of the *buffer-package* thing.
Ok, after exposing this, my opinion is kind of split. When debugging, it's mighty handy to just copy-paste a source form and have it be read in the package where the definition was defined. But there might also be cases where one really wants to read and evaluate things in the frame's bound value of `*package*'.
I'm not sure that I can follow your reasoning. In the latter case symbols need to be entered with qualifiers to access frame local variables. That's never more desirable than non-qualified symbols. And if we aren't accessing local variables, why are we using eval-in-frame?
I wasn't considering the chance that an implementation wouldn't have an accessible dynamic environments for each frame. In this case, it may be more intuitive to just use the frame's `*package*' for both reading and evaluating, even if that means always using the most recent frame's `*package*'.
I think we should aim at the common case. It seems to me that few frames explicitly bind *package* but that the functions on the stack often belong to different packages.
There is also no need to use the same package for read and eval.
The purpose of frame-package was primarily that we can read the names of local variables without package prefix.
Maybe there should be an SLDB binding just to get a binding's value , e.g. that would try match a variable name no matter its package, unless there were two same named symbols in different packages, where CMUCL could use its magic to Guess What You Mean (TM).
Something like that would amount to implement eval-in-frame directly. And there is still the problem that two local lexical variables can in fact have the same name when one shadows the other. Luckily, sldb-toggle-details solves that problem most of the time.
Helmut