I’m attempting to write my first anaphoric macro and am running into a problem. I am using sblc and slime.
When the anaphoric macro is expanded in another package its symbols are prefixed with the package it was defined in (i.e. they become tjb-utilities::value instead of just value. What is going on?
PE> (macroexpand-1 '(act-if-key :pcram (get-node) (print value)))
(IF (HAS-KEY? :PCRAM (GET-NODE))
(LET ((TJB-UTILITIES::KEY :PCRAM)
(TJB-UTILITIES::VALUE (GETHASH :PCRAM (GET-NODE))))
(PRINT VALUE)))
This is the macro definition:
(defmacro act-if-key (key hashtable &body body)
`(if (has-key? ,key ,hashtable)
(let ((key ,key) (value (gethash ,key ,hashtable)))
,@body)))
It does work correclty if I prefix the value:
(act-if-key :pcram (get-node) (print tjb-utilities::value))
; in: ACT-IF-KEY :PCRAM
; (LET ((TJB-UTILITIES::KEY :PCRAM)
; (TJB-UTILITIES::VALUE
; (GETHASH :PCRAM (PHILOSOPHY-EXPERIENCE::GET-NODE))))
; (PRINT TJB-UTILITIES::VALUE))
;
; caught STYLE-WARNING:
; The variable TJB-UTILITIES::KEY is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
"hello"
"hello"
The packages are defined as follows:
(defpackage #:tjb-utilities
(:nicknames :tjb)
(:use #:cl)
(:export "HAS-KEY?" "KEY-VALUE-PAIRS" "ACT-IF-KEY" "TJB-MAKE-HASH-TABLE"))
(defpackage #:my-package
(:nicknames :pe)
(:use #:cl #:clsql #:tjb-utilities))
Update: Changing the key in the lambda list to key_in has no effect
(defmacro act-if-key (key_in hashtable &body body)
`(if (has-key? ,key_in ,hashtable)
(let ((key ,key_in) (value (gethash ,key_in,hashtable)))
,@body)))
Not sure if I copied all that you needed, and I’m a tad blur on how did you intend to use the “key”, so I did it only for the
valuein the way it will be created in the package, where the macro is used. You’d figure it for yourself whether you need the same for thekeyor not.The above bind the symbol
valuein the current package to whatevergethashwill return. In your original version you havekeysupplied by the user of the macro, so I decided you didn’t want a symbolkeyinside the macro, just it’s value.But wait a bit, perhaps there will be a better answer, maybe you can just
make-symbolit instead of interning and then bind it somehow. I’m not sure.