How to remove a defmethod for a struct - common-lisp

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.

Related

How can the mouse be moved programatically in Common Lisp?

The code should run on Windows 10. I tried asking on Reddit, but the ideas are Unix/Linux only. There's also CFFI, but I didn't understand how to use it for this problem (the main usability part of the documentation I found is just an elaborate example not related to this problem).
I also looked through the SetCursorPos of Python, and found that it calls ctypes.windll.user32.SetCursorPos(x, y), but I have no clue what that would look like in CL.
And finally, there's CommonQt, but while there seems to be QtCursor::setPos in Qt, I couldn't find the CL version.
The function called by the Python example seems to be documented here. It is part of a shared library user32.dll, which you can load with CFFI,
(ql:quickload :cffi)
#+win32
(progn
(cffi:define-foreign-library user32
(:windows "user32.dll"))
(cffi:use-foreign-library user32))
The #+win32 means that this is only evaluated on Windows.
Then you can declare the foreign SetCursorPos-function with CFFI:DEFCFUN. According to the documentation, it takes in two ints and returns a BOOL. CFFI has a :BOOL-type, however the Windows BOOL seems to actually be an int. You could probably use cffi-grovel to automatically find the typedef from some Windows header, but I'll just use :INT directly here.
#+win32
(cffi:defcfun ("SetCursorPos" %set-cursor-pos) (:boolean :int)
(x :int)
(y :int))
I put a % in the name to indicate this is an internal function that should not be called directly (because it is only available on Windows). You should then write a wrapper that works on different platforms (actually implementing it on other platforms is left out here).
(defun set-cursor-pos (x y)
(check-type x integer)
(check-type y integer)
#+win32 (%set-cursor-pos x y)
#-win32 (error "Not supported on this platform"))
Now calling (set-cursor-pos 100 100) should move the mouse near the top left corner.
There are two problems here:
How to move the mouse in windows
How to call that function from CL.
It seems you have figured out a suitable win32 function exists so the challenge is to load the relevant library, declare the functions name and type, and then call it. I can’t really help you with that unfortunately.
Some other solutions you might try:
Write and compile a trivial C library to call the function you want and see if you can call that from CL (maybe this is easier?)
Write and compile a trivial C library and see if you can work out how to call it from CL
Write/find some trivial program in another language to move the mouse based on arguments/stdin and run that from CL

How to get class information in 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).

Defining aliases to standard Common Lisp functions?

Lisp is said to enable redefinitions of its core functions.
I want to define an alias to the function cl:documentation function, such that
(doc 'write 'function) === (documentation 'write 'function)
How can this be done and made permanent in SBCL?
Creating an Alias
You are not trying to redefine (i.e., change the definition of) the system function documentation, you want to define your own function with a shorter name which would do the same thing as the system function.
This can be done using fdefinition:
(setf (fdefinition 'doc) #'documentation)
How to make your change "permanent" in common lisp
There is no standard way, different implementation may do it differently, but, generally speaking, there are two common ways.
Add code to an init file - for beginners and casual users
SBCL
CLISP
Clozure
ECL
The code in question will be evaluated anew every time lisp starts.
Pro:
Easy to modify (just edit file)
Takes little disk space
Normal lisp invocation captures the change
Con:
Evaluated every time you start lisp (so, slows start up time if the code is slow)
Save image - for heavy-weight professionals
SBCL
CLISP
Clozure
ECL - not supported
The modified lisp world is saved to disk.
Pro:
Start uptime is unaffected
Con:
Requires re-dumping the world on each change
Lisp image is usually a large file (>10MB)
Must specify the image at invocation time
Even though #sds has already answered pretty thoroughly I just wanted to add that the utility library serapeum has defalias
I use a simple macro for this:
(defmacro alias (to fn)
`(setf (fdefinition ',to) #',fn))
e.g.
(alias neg -) => #<Compiled-function ... >
(neg 10) => -10
Other answers include detail about how to make this permanent.

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