This is a read-only archive!

I'm better now

I calmed down a bit from yesterday, scrapped all my code and started over, with much better results. I'm not sure what was wrong yesterday, but things work today. I think I may have been using variable names that clashed with function names internal to CL-WHO. Or else I somehow had a CL-WHO macro trying to evaluate function names as variables. Or something. I'm still not sure why it was complaining about PRINC since I didn't mention that symbol in any of my code. But no matter. CL-WHO is properly inherited into my class today; I attribute yesterday to PEBKAC malfunction.

I still have problems with sometimes accidentally obliterating functions that exist in other packages, or functions/variables that exist in my own packages. The problem(?) with a persistent environment is that the effects of one typo live forever, until you clean up your mess. If I define a function and then decide my function needs to be a macro, the compiler complains that I'm murdering a function I defined previously. If I typo a variable name, that symbol is interned whether I like it or not, and it may shadow something important. Peter Seibel mentions this problem in passing at the very end of Chapter 21 of PCL.

Interestingly today, I tried to define an :after method on INITIALIZE-INSTANCE for one of my classes***. I forgot to type the ":after", so I actually obliterated a function that's used as my class's constructor, which is bad because now I couldn't construct objects any more for that class.

I could've shut down and restarted my Lisp image and reloaded all the code (which is what you'd do in any other language: recompile, or re-run the script). But that's overkill and seems like it's very much not the Lisp way to do things.

Instead Common Lisp has facilities to unintern symbols, and undefine functions and methods, and whatnot. This page for example has a snippet telling how to undefine a method:

(let* ((generic-function (symbol-function 'gf-name))
       (method (find-method generic-function
                            '(method-specializers)
                            (list (find-class parameter-class-name)
                                  ; one per argument 
                                  ...))))
  (remove-method generic-function method))

Quoth the website: ...where gf-name is the name of the generic function (i.e. the name of the method), method-specializers is either empty or a method combination specifier, such as :BEFORE, :AFTER, or :AROUND, and parameter-class-name is the name of the class on which a particular method parameter is specialized.

This worked very well. And I actually think I almost understand how/why it works, which is surprising.

I guess some days everything goes wrong, and some days everything goes right. Emacs is mostly behaving itself today; I guess I've managed to chain the beast down enough so that it does my bidding. I managed to define some classes using CLSQL:DEFINE-VIEW-CLASS and now my objects appear in my database as I create and modify them, like magic, which makes me happy. Maybe there's hope yet.

(*** These "method-specifiers" or whatever you call them are an awesome thing in Common Lisp. You can modify the behavior of existing methods by telling CLOS to run a certain method before, after, or around an existing method. One great thing about this is that you can use it to extend the behavior of automatically-generated methods, for example constructors. Say you want to have an object which, after being constructed, is automatically stored in a DB; just define an :after method on the constructor, that takes the already-constructed object and inserts it into the DB. I likes it.)

January 10, 2008 @ 5:54 PM PST
Cateogory: Programming
Tags: Lisp, Emacs

2 Comments

Zach Beane
Quoth Zach Beane on January 11, 2008 @ 4:53 AM PST

SLIME has a pretty slick system for removing methods from generic functions. If you inspect the GF object (like #'foo), it'll give a list of methods, and a button next to each to allow you to remove it. It's easier than find-method plus remove-method.

Recent SLIMEs require you to load the fancy inspector contrib for this to work, though.

Brian
Quoth Brian on January 11, 2008 @ 12:38 PM PST

I never knew you could inspect methods that way in SLIME, let alone that you could manipulate them there. That's awesome, thanks.