How to get class information in Common Lisp? - common-lisp

For example, I want to see a list of available accessors of a slot from the REPL instead of jumping to the source. How do I do that?

Not sure there's a way to get a list of accessors easily. The object inspection functions tend to be exported from implementation-specific packages. You can take a look at the package file of cl-mop to see where they are. The relevant lines are
...
(:shadowing-import-from
#+openmcl-native-threads #:ccl
#+cmu #:pcl
#+sbcl #:sb-pcl
#+lispworks #:hcl
#+allegro #:mop
#+clisp #:clos
#:class-slots #:slot-definition-name)
...
The project also exports slot-names and to-alist methods that do exactly what they sound like.
If you're in slime, rather than a plain command-line REPL, you can use slime-inspect. If you use it to inspect a class, you'll see (among other things) a list of methods that specialize on it (you need to inspect a class this way, so if you have an instance, you need to call class-of on it first).

Related

How to remove a defmethod for a struct

I have 2 destructs: monster & orc. The orc includes monster. The generic monster has generic defmethods on it named monster-show & monster-hit. The orc has a specialized monster-hit but still keeps the generic monster-show. My problem is that I accidentally named the specialized method for the orc the wrong name (monster-show), so now when I try to use the generic monster-show, it runs code that it shouldn't (the wrongly named defmethod I compiled) instead of running the generic method.
Is there a way to get rid of a specialized defmethod in Slime + SBCL?
If you don't have an IDE or such, you can use remove-method:
(remove-method #'monster-show
(find-method #'monster-show
()
(list (find-class 'orc))))
Here’s how I would do it using the slime inspector:
Enter the generic function you want to modify:
CL-USER> #'monster-show
#<GENERIC FUNCTION: MONSTER-SHOW>
Move your cursor on to it and inspect the object by typing C-c C-v TAB
The inspector should show a list of methods for the function identified by their specialisers. Navigate to one and press the button to remove/unbind the method. You can click for this too.
Also by the description of your hierarchy it would probably be wiser to use real classes and not structs. Structs tens not to give a particularly big speedup compared to classes.
On spacemacs w/ evil mode :slime-inspect RET #'monster-show. Select remove-method on the orc.

Is it possible to #inheritParams from a function within another package?

I wrote an importer for an obscure TSV format, which I want to package and document: https://github.com/katrinleinweber/MWX-import/commits/package
The importer function passes a renamed skip_lines parameter to utils::read.table so I would like to "pass" the latter's documentation of skip into my .Rd. However, trying a few notations like #inheritParams utils::read.table skip always results in Warning: Failed to find topic […].
Whether it's actually possible to inherit a single, specific parameter from another package's function is not clear to me after reading http://r-pkgs.had.co.nz/man.html and https://blog.rstudio.org/2017/02/01/roxygen2-6-0-0/.
Is it possible? If yes, thanks for any hint!
If you use #inheritParams utils::read.table, then any parameters in your function which match those in utils::read.table will be inherited (provided they aren't already explicitly documented). So this would cover your use case if you used skip instead of skip_lines.
I don't think it's possible to inherit documentation for a parameter when your parameter name doesn't match though.

Function signature not found despite showing with methods(...)

I am new to Julia, so this might be trivial.
I have a function definition within a module that looks like (using URIParser):
function add!(graph::Graph,
subject::URI,
predicate::URI,
object::URI)
...
end
Outside of the module, I call:
add!(g, URIParser.URI("http://test.org/1"), URIParser.URI("http://test.org/2"), URIParser.URI("http://test.org/1"))
Which gives me this error:
ERROR: no method add!(Graph,URI,URI,URI)
in include at boot.jl:238
in include_from_node1 at loading.jl:114
at /Users/jbaran/src/RDF/src/RDF.jl:79
Weird. Because when I can see a matching signature:
julia> methods(RDF.add!)
# 4 methods for generic function "add!":
add!(graph::Graph,subject::URI,predicate::URI,object::Number) at /Users/jbaran/src/RDF/src/RDF.jl:29
add!(graph::Graph,subject::URI,predicate::URI,object::String) at /Users/jbaran/src/RDF/src/RDF.jl:36
add!(graph::Graph,subject::URI,predicate::URI,object::URI) at /Users/jbaran/src/RDF/src/RDF.jl:43
add!(graph::Graph,statement::Statement) at /Users/jbaran/src/RDF/src/RDF.jl:68
At first I thought it was my use of object::Union(...), but even when I define three functions with Number, String, and URI, I get this error.
Is there something obvious that I am missing? I am using Julia 0.2.1 x86_64-apple-darwin12.5.0, by the way.
Thanks,
Kim
This looks like you may be getting bit by the very slight difference between method extension and function shadowing.
Here's the short of it. When you write function add!(::Graph, ...); …; end;, Julia looks at just your local scope and sees if add! is defined. If it is, then it will extend that function with this new method signature. But if it's not already defined locally, then Julia creates a new local variable add! for that function.
As JMW's comment suggests, I bet that you have two independent add! functions. Base.add! and RDF.add!. In your RDF module, you're shadowing the definition of Base.add!. This is similar to how you can name a local variable pi = 3 without affecting the real Base.pi in other scopes. But in this case, you want to merge your methods with the Base.add! function and let multiple dispatch take care of the resolution.
There are two ways to get the method extension behavior:
Within your module RDF scope, say import Base: add!. This explicitly brings Base.add! into your local scope as add!, allowing method extension.
Explicitly define your methods as function Base.add!(graph::Graph, …). I like this form as it more explicitly documents your intentions to extend the Base function at the definition site.
This could definitely be better documented. There's a short reference to this in the Modules section, and there's currently a pull request that should be merged soon that will help.

Redefine generic function with different lambda list

I've made a mistake and forgot to specify keyword arguments in defgeneric the first time I've compiled it. Now I really don't want to restart SLIME only to redefine this one defgeneric to include more arguments. Is there a way to "undefine" it somehow?
Oh, sorry, never mind, after removing all methods defined for that generic, SBCL redefined it, so it's all good now:
(remove-method #'some-generic
(find-method #'some-generic '() (list of method types)))
For posterity.
See fmakunbound.
(fmakunbound 'some-generic)
SLIME has the command Ctrl-c Ctrl-u to undefine a function. Set the cursor on the function symbol and then type the sequence.
Another possibility would be to compile one or more methods with the additional arguments and then, after your Common Lisp implementation "complains" about the unknown parameters, select the restart which updates the arguments available in the generic function.

Customizing the ESS environment for R

I am trying to optimize my ESS - R environment. So far I make use of the r-autoyas, I set intendation and stuff following style guides, in the mini-buffer there are eldoc hints for function arguments, and I have the option to press a key in order to find information about variable at point (more here).
Are there any other things you use in order to have a nice R environment? Maybe non-ESS people have some nice things to add (I got that info of variable at point from looking at an Eclipser). One example could be an easy way to insert "just-before-defined" variables without typing the variable name (should be something for that?).
(Please help me to change the question instead of "closing" the thread if it is not well formulated)
I am not using autoyas as I find auto-complete integration a better approach.
Insertion of previously defined symbols is a general emacs functionality called 'dabbrev-expand' and is bound to M-/. I have this in my .emacs to make it complete on full symbols:
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_\\|s.")
(setq dabbrev-case-fold-search t)
Another thing which I use extensively is imenu-based-jump-to-symbol-definition. It offers similar functionality to emacs tags, but just for open buffers in the same mode as the current buffer. It also uses IDO for queries:
Put imenu-anywhere.el into your emacs load path and add this:
(require 'imenu-anywhere)
(global-set-key [?\M-o] 'imenu-anywhere)
Now, if I do M-o foo RET emacs jumps to the function/class/method/generic definition of 'foo' as long as 'foo' is defined in one of the open buffers. This of course works whenever a mode defines imenu-tags. ESS defines those, so you should not need to add more.
There is also somewhere a collection of R-yas templates. I didn't get around to starting using them but my guess is that it's a pretty efficient template insertion mechanism.
[edit] Activate tracebug:
(setq ess-use-tracebug t)

Resources