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.
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.
Thanks!
Peter
------------------------------------------------------- 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 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.
Peter Olsen olsen@sigmaxi.net
I have loved the stars too fondly to be fearful of the night. Galileo Galilei
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.
Eric,
Thanks very much for your response.
We're going to try both this approach and that suggested by Alessio. We appear to have some "package problems" --- about which I as yet no nothing more. (I'm much more of a Schemer than a Lisper, so packages are still something of a challenge.)
Again, thanks for your help and for your examples, from which I'm learning a lot.
Peter
On 2009-12-30 05:58 , "Erik Huelsmann" ehuels@gmail.com wrote:
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.
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. 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.
In addition to what Erik said, if you need you own OR to be effective only in your package, you can use your-package:or instead of common-lisp:or to name your macro, for example:
(defpackage :my-package (:use :common-lisp) (:shadow #:or) (:export ...))
then, start your source files with
(in-package :my-package)
and in one of them put
(defmacro or ...) ;the symbol is my-package:or, not common-lisp:or
Of course, this way your macro will only get used by your own code (and code that imports the symbol OR from your package); it won't affect other libraries or the system itself, so it's not equivalent to Erik's advice. This solution has the advantage of being portable Common Lisp.
hth, Alessio
armedbear-devel@common-lisp.net