Hi Peter,
On Wed, Dec 30, 2009 at 7:18 AM, Peter Olsen pcolsen@gmail.com wrote:
I'm writing to ask how to redefine the "or" macro in ABCL. I'm working on a project and there's one package in which I need "or" to mean something else than its usual definition. I've tried simply to redefine it, but it doesn't work. I understand that the Common Lisp spec requires special provision for that to be done --- such as the package-lock construct in SBCL.
Well, actually, ABCL doesn't have package locks, so this should be easier in ABCL. Your approach was going in the right direction, however, you've hit a little snag which is in the way: OR is a special operator and a macro. The special operator makes the interpreter perform better because it prevents object allocations.
How can I do that in ABCL? I want to be able to do this within the code, for example, with in a "let" so that I can bound its scope. Can anyone point me in the right direction? My first --- failed --- experiment is below.
My comments below.
A way that doesn't work. slipstream:~ pcolsen$ abcl Armed Bear Common Lisp 0.17.0 Java 1.5.0_20 Apple Inc. Java HotSpot(TM) Client VM Low-level initialization completed in 1.476 seconds. Startup completed in 4.363 seconds. Type ":help" for a list of available commands. CL-USER(1): (or nil t) T CL-USER(2): (defmacro or (x) (+ 1 x)) ; My very own new "or" OR
Here, OR is still both a special operator and a macro. The special operator has precedence on evaluation. The actual macro function gets stored in the symbol-plist. If you execute
(setf (symbol-function 'or) (get 'or 'sys::macroexpand-macro))
before running the defmacro, you're done. However: note that if you trigger any part of the interpreter or compiler depending on the behaviour of OR, you're in trouble: it'll see the incorrect version of OR if it's within the scope of the specific block.
Another solution could be to rename the OR in your code to something else, but I guess you thought of that.
CL-USER(3): (or 3) ; Result should be 4 3 CL-USER(4): (or nil nil) ; My "or" should take only one argument. NIL CL-USER(5): (or nil t) T CL-USER(6): ;;; Redefinition didn't work.
Hope that helps; it works on my system, at least.
Bye,
Erik.