From: Mateusz Berezecki on 8 Aug 2010 16:35 Hi, I have a following package/symbol question. I'm using SBCL on ubuntu lucid lynx. Here's the source code reproducing the problem. (make-package 'test) (in-package :test) (cl:use-package :cl) (defmacro test-macro (op) `,(case op (hi t) (t nil))) (test-macro hi) ==> t (test-macro hello) ==> nil All is good so far, but problems emerge as soon as I switch to a different package. (in-package :cl-user) (test:test-macro hello) ==> nil (test:test-macro hi) ==> nil (test:test-macro test::hi) ==> t I understand that 'hi symbol is interned into a test package so the real comparison inside of case statement is against op and test::hi but this is not what I want. Is there a way to correct this behavior and not requiring prefixing with packages, etc. ? I am building a DSL macro but I want it to be exported from one package and used by other packages. Any ideas?
From: joswig on 8 Aug 2010 16:52 On 8 Aug., 22:35, Mateusz Berezecki <mateu...(a)gmail.com> wrote: > Hi, > > I have a following package/symbol question. > I'm using SBCL on ubuntu lucid lynx. > > Here's the source code reproducing the problem. > > (make-package 'test) > (in-package :test) > (cl:use-package :cl) > > (defmacro test-macro (op) > `,(case op > (hi t) > (t nil))) `, is not needed. > > (test-macro hi) ==> t > (test-macro hello) ==> nil > > All is good so far, but problems emerge as soon as I switch to a > different package. > > (in-package :cl-user) > > (test:test-macro hello) ==> nil > (test:test-macro hi) ==> nil > (test:test-macro test::hi) ==> t > > I understand that 'hi symbol is interned into a test package so the > real comparison inside of case statement is against op and test::hi > but this is not what I want. Is there a way to correct this behavior > and not requiring prefixing with packages, etc. ? You can compare the symbol names. Then you might want to use COND instead of CASE, since CASE compares with EQL. You might want to compare the symbol names with EQUAL. > > I am building a DSL macro but I want it to be exported from one > package and used by other packages. > > Any ideas?
From: Scott L. Burson on 8 Aug 2010 18:47 Mateusz Berezecki wrote: > > I understand that 'hi symbol is interned into a test package so the > real comparison inside of case statement is against op and test::hi > but this is not what I want. Is there a way to correct this behavior > and not requiring prefixing with packages, etc. ? The usual way to deal with this problem is to use keywords (symbols in the keyword package). Thus: (defmacro test-macro (op) (case op (:hi t) (t nil))) (in-package :cl-user) (test:test-macro :hi) ==> t This maybe isn't quite what you want since the colon is still required, but it is the standard approach in CL. An alternative would be to export both TEST-MACRO and HI from the TEST package, and use the TEST package in the package where you write your code. Then you won't have to include the package prefix on TEST-MACRO either: (in-package :test) (export '(test-macro hi) :test) (in-package :cl-user) (use-package :test) ;;; Assuming your original definition of TEST-MACRO (test-macro hi) ==> t This might seem like the obviously preferable solution -- and indeed you certainly will want to use it for the symbol TEST-MACRO -- but in general I think it's better for symbols that are part of the syntax of macros (like HI in this example) to be in the keyword package. -- Scott
From: Pascal J. Bourguignon on 8 Aug 2010 21:21 Mateusz Berezecki <mateuszb(a)gmail.com> writes: > I have a following package/symbol question. > I'm using SBCL on ubuntu lucid lynx. > > Here's the source code reproducing the problem. > > (make-package 'test) The behavior of the package thusly created will be implementation dependent. Better create it as: (make-package 'test :use '(:cl)) > (in-package :test) > (cl:use-package :cl) > > (defmacro test-macro (op) > `,(case op > (hi t) > (t nil))) > > (test-macro hi) ==> t > (test-macro hello) ==> nil > > > All is good so far, but problems emerge as soon as I switch to a > different package. > > (in-package :cl-user) > > (test:test-macro hello) ==> nil > (test:test-macro hi) ==> nil > (test:test-macro test::hi) ==> t > > I understand that 'hi symbol is interned into a test package so the > real comparison inside of case statement is against op and test::hi > but this is not what I want. Is there a way to correct this behavior > and not requiring prefixing with packages, etc. ? > > I am building a DSL macro but I want it to be exported from one > package and used by other packages. > > Any ideas? Use defpackage and export HI: (defpackage "TEST" (:use "CL") (:export "TEST-MACRO" "HI")) (in-package "TEST") (defmacro test-macro (op) (case op ((hi) t) (otherwise nil))) (in-package "CL-USER") (use-package "TEST") (test-macro hi) ;; -> T (test-macro lo) ;; -> NIL -- __Pascal Bourguignon__ http://www.informatimago.com/
|
Pages: 1 Prev: How to run a lisp file Next: The behavior of backquotes in macro definitions |