Hi,
The return value of FIND-DEFINITIONS isn't specified as rigorously as I'd like; I'm referring to its DSPEC part specially.
For instance, on CMUCL:
(find-definitions #'car) ==> (((FUNCTION CAR) ..location..) ...)
whereas on SBCL
(find-definitions #'car) ==> (((DEFUN CAR) ..location..) ...)
Similiarly, CMUCL returns a dspec (VARIABLE :SPECIAL *FOO*) whereas SBCL returns (DEFVAR *FOO*).
I'd like to specify that a DSPEC is either
a symbol, or
a list where the CAR is the defining symbol (DEFVAR for variables, DEFUN for function, &c.) that resulted in the respective definition, the CADR is the name of the thing, and optionally there's an extra description as the rest argument (specializing arglist for methods, for instance.)
Furthermore, I'd like to explicitly validate this with a DESTRUCTURE-CASE such that each backend implementator can directly see what's expected.
Opinions?
-T.
* Tobias C. Rittweiler [2008-02-22 20:50+0100] writes:
I'd like to specify that a DSPEC is either
a symbol, or
a list where the CAR is the defining symbol (DEFVAR for variables, DEFUN for function, &c.) that resulted in the respective definition, the CADR is the name of the thing, and optionally there's an extra description as the rest argument (specializing arglist for methods, for instance.)
Furthermore, I'd like to explicitly validate this with a DESTRUCTURE-CASE such that each backend implementator can directly see what's expected.
Opinions?
Sounds like a noble effort. Both, Lispworks and Allegro have some documentation about dspecs resp. fspecs. That probably counts as previous work, but both seem to be rather ad-hoc. Lispworks' dspecs are even user-extendable, so validating the result isn't that easy. Moreover, CMUCL/SBCL return compiler internals like transformation and type propagation rules. Not to mention that that some implementations return nothing at all. It's not easy to generalize without allowing implementation specific extensions.
Currently, we use the dspec part only for display purposes. It would be good to find a useful application for these dspecs before spending too much time on them.
Helmut.
Helmut Eller heller@common-lisp.net writes:
Currently, we use the dspec part only for display purposes. It would be good to find a useful application for these dspecs before spending too much time on them.
I've written a FIND-DEFINITION-FOR-THING that tries to find the definition of the data structure behind an object. And I've got to rule out definitions returned from FIND-DEFINITIONS which don't match.
For example:
(find-definitions '(setf car))
may return definitions for a SETF-EXPANDER and for a SETF function definition for CAR.
However,
(find-definition-for-thing #'(setf car))
may only return the SETF function definition.
Objective is to provide a general Find Definition menu option for presentations.
Does this count as useful application?
-T.
* Tobias C. Rittweiler [2008-02-23 12:07+0100] writes:
Helmut Eller heller@common-lisp.net writes:
Currently, we use the dspec part only for display purposes. It would be good to find a useful application for these dspecs before spending too much time on them.
I've written a FIND-DEFINITION-FOR-THING that tries to find the definition of the data structure behind an object. And I've got to rule out definitions returned from FIND-DEFINITIONS which don't match.
For example:
(find-definitions '(setf car))
may return definitions for a SETF-EXPANDER and for a SETF function definition for CAR.
However,
(find-definition-for-thing #'(setf car))
may only return the SETF function definition.
Objective is to provide a general Find Definition menu option for presentations.
Does this count as useful application?
Yes, that's a useful application. I don't quite understand how FIND-DEFINITIONS can be used here because FIND-DEFINITIONS expects a (generalized) name as argument. One possibility would be to use a (yet-to-be-invented) function, say FUNCTION-NAME, which returns the name of a function object and passing that name to FIND-DEFINITIONS. But if we invent a FUNCTION-NAME function, we could just as well invent FUNCTION-SOURCE-LOCATION and CLASS-SOURCE-LOCATION, which would easier to use than FIND-DEFINITIONS.
If you want to stay with FIND-DEFINITIONS: instead of filtering out results manually, it could be be easier to narrow the specification for the argument instead of the return value. E.g. and you could say that for an argument like '(:function (setf foo)) the setf-expanders shouldn't be returned.
Helmut.
Helmut Eller heller@common-lisp.net writes:
Yes, that's a useful application. I don't quite understand how FIND-DEFINITIONS can be used here because FIND-DEFINITIONS expects a (generalized) name as argument. One possibility would be to use a (yet-to-be-invented) function, say FUNCTION-NAME, which returns the name of a function object and passing that name to FIND-DEFINITIONS. But if we invent a FUNCTION-NAME function, we could just as well invent FUNCTION-SOURCE-LOCATION and CLASS-SOURCE-LOCATION, which would easier to use than FIND-DEFINITIONS.
I decided to do this way, because SWANK-BACKEND:FUNCTION-NAME does in fact already exist. And you can retrieve the name of structures and classes via TYPE-OF.
If you want to stay with FIND-DEFINITIONS: instead of filtering out results manually, it could be be easier to narrow the specification for the argument instead of the return value. E.g. and you could say that for an argument like '(:function (setf foo)) the setf-expanders shouldn't be returned.
This is a possibility. Another possibility would be to specify the return value as outlined in my original posting, with the following addition:
FIND-DEFINITIONS returns a list of
(DSPEC LOCATION &optionally impl-dependent-p)
If IMPL-DEPENDENT-P is non-NIL (it's supposed to be EQ to :IMPLEMENTATION-DEPENDENT in this case, but not mandatorily so.), the DSPEC is of implementation dependent nature, and can anything.
How does this sound?
(In the end, I don't care all /that/ much, but specifying the return value at least for a subset seems to be the more general solution to me, and validating by DESTRUCTURE-CASE is nice for documentation purposes, too.)
-T.
* Tobias C. Rittweiler [2008-02-24 21:06+0100] writes:
Helmut Eller heller@common-lisp.net writes:
Yes, that's a useful application. I don't quite understand how FIND-DEFINITIONS can be used here because FIND-DEFINITIONS expects a (generalized) name as argument. One possibility would be to use a (yet-to-be-invented) function, say FUNCTION-NAME, which returns the name of a function object and passing that name to FIND-DEFINITIONS. But if we invent a FUNCTION-NAME function, we could just as well invent FUNCTION-SOURCE-LOCATION and CLASS-SOURCE-LOCATION, which would easier to use than FIND-DEFINITIONS.
I decided to do this way, because SWANK-BACKEND:FUNCTION-NAME does in fact already exist. And you can retrieve the name of structures and classes via TYPE-OF.
I guess that this will not fly for stuff like:
(setf (fdefinition 'foo) (lambda () ...)) (find-definition-for-thing #'foo)
If you want to stay with FIND-DEFINITIONS: instead of filtering out results manually, it could be be easier to narrow the specification for the argument instead of the return value. E.g. and you could say that for an argument like '(:function (setf foo)) the setf-expanders shouldn't be returned.
This is a possibility. Another possibility would be to specify the return value as outlined in my original posting, with the following addition:
FIND-DEFINITIONS returns a list of
(DSPEC LOCATION &optionally impl-dependent-p)
If IMPL-DEPENDENT-P is non-NIL (it's supposed to be EQ to :IMPLEMENTATION-DEPENDENT in this case, but not mandatorily so.), the DSPEC is of implementation dependent nature, and can anything.
How does this sound?
(In the end, I don't care all /that/ much, but specifying the return value at least for a subset seems to be the more general solution to me, and validating by DESTRUCTURE-CASE is nice for documentation purposes, too.)
Sounds like you already made up your mind.
Helmut.
Helmut Eller heller@common-lisp.net writes:
- Tobias C. Rittweiler [2008-02-24 21:06+0100] writes:
Helmut Eller heller@common-lisp.net writes:
Yes, that's a useful application. I don't quite understand how FIND-DEFINITIONS can be used here because FIND-DEFINITIONS expects a (generalized) name as argument. One possibility would be to use a (yet-to-be-invented) function, say FUNCTION-NAME, which returns the name of a function object and passing that name to FIND-DEFINITIONS. But if we invent a FUNCTION-NAME function, we could just as well invent FUNCTION-SOURCE-LOCATION and CLASS-SOURCE-LOCATION, which would easier to use than FIND-DEFINITIONS.
I decided to do this way, because SWANK-BACKEND:FUNCTION-NAME does in fact already exist. And you can retrieve the name of structures and classes via TYPE-OF.
I guess that this will not fly for stuff like:
(setf (fdefinition 'foo) (lambda () ...)) (find-definition-for-thing #'foo)
Probably not.
Do you prefer the explicit SOURCE-LOCATION machinery?
-T.
* Tobias C. Rittweiler [2008-02-25 01:08+0100] writes:
Do you prefer the explicit SOURCE-LOCATION machinery?
Yes, for this application it would be the more direct path, because names/dspecs don't work well with anonymous objects.
Helmut.
Helmut Eller heller@common-lisp.net writes:
- Tobias C. Rittweiler [2008-02-25 01:08+0100] writes:
Do you prefer the explicit SOURCE-LOCATION machinery?
Yes, for this application it would be the more direct path, because names/dspecs don't work well with anonymous objects.
So are you content with a SWANK-BACKEND:FIND-SOURCE-LOCATION which takes an object and returns a list of source locations for the passed object (i.e. let the backend deal with _all_ details)?
Should I implement a default implementation that goes the
(swank-backend:find-definitions (guess-name thing))
path? (Without any sort of filtering afterwards; it may arguably be a good enough default to provide every possible location than providing nothing and erroring out instead---although the latter may force backend implementators to actually take care about solving this rightly. So I'm opting for no such default implementation.)
Or how would you like it to be implemented?
-T.
* Tobias C. Rittweiler [2008-02-27 16:40+0100] writes:
So are you content with a SWANK-BACKEND:FIND-SOURCE-LOCATION which takes an object and returns a list of source locations for the passed object (i.e. let the backend deal with _all_ details)?
That would be fine with me.
Should I implement a default implementation that goes the
(swank-backend:find-definitions (guess-name thing))
path? (Without any sort of filtering afterwards; it may arguably be a good enough default to provide every possible location than providing nothing and erroring out instead---although the latter may force backend implementators to actually take care about solving this rightly. So I'm opting for no such default implementation.)
Try the simplest approach first.
Or how would you like it to be implemented?
I'd try to return a single location and not a list. Presumably the implementation of the UI would then be simpler. A function could reasonably have multiple locations (I mean the region of the body, not the locations of different methods), but it probably doesn't matter for the intended application.
Helmut.
I haven't been following this properly, so my concerns may be unfounded, but I just wanted to have it on record that getting the current kind of listing for M-. (which includes VOPS, transforms, etc) in SBCL is essential to me.
I can understand that it is not that for everyone, but if it ends up under the hammer, please retain it as a contrib.
Cheers,
-- Nikodemus
"Nikodemus Siivola" nikodemus@random-state.net writes:
I haven't been following this properly, so my concerns may be unfounded, but I just wanted to have it on record that getting the current kind of listing for M-. (which includes VOPS, transforms, etc) in SBCL is essential to me.
This is about providing a Find Definition (M-.) facility for the things behind presentations in the Slime REPL.
HTH,
-T.