1

'Hope it won't bother my using defmacros named in the style of keywords (colon-prefixed, e.g., :set-this or :get-that): it apparently tricks ELisp from otherwise requiring quoted symbols (') or function symbols (#').

For example:

(foo :set-this value-that) ; line 0

Nevermind that: the problem goes as follows.

Say there are two "keywordp"-like defmacros with one parameter, and given a cl-flet* context, there should be two similar forms (as in line #0), but with two different macros and arguments.

An MWE is the following.

(defmacro :m (x) `(length ,x)) ; line 1
    ⇒ :m
(and (keywordp :m) (macrop :m)) ; line 2
    ⇒ t

(:m `(3)) ; line 3
    ⇒ 1

(defmacro :w (x) `(length (nreverse ,x))) ; line 4
    ⇒ :w
(and (keywordp :w) (macrop :w)) ; line 5
    ⇒ t

(:w `(6)) ; line 6
    ⇒ 1

(defun x (y z) (eval `(,y ,z))) ; line 7
    ⇒ x

(x :m `(8)) ; line 8
    ⇒ Invalid function: 8

(x :w '(9)) ; line 9
    ⇒ Invalid function: 8

(- (eval `(:m '(8)) (eval `(:w `(9))) ; line 10
    ⇒ 0

The faulty code is in line #7.

In these simple cases, it don't matter if the argument-list is backquoted `(8), quoted '(9), or returned as (list 8).

Lines #8 and #9 show what is wrong.

Yet, line #10 shows that evaluating as it "should be" is possible.

Now, if instead of defun there were a defmacro:

(defmacro x (y z) `(eval (,y ,z))) ; line 11
    ⇒ x

then lines #8 or #9 would be equivalent to line 10, but this is impossible within a cl-flet*.

Any hints? Thank s.

1 Answer 1

1

Try this for line 7:

(defun x (y z) (eval `(,y ',z)))

That is, ensure that the second argument is quoted in the expansion. When you call (x :m `(8)), in your version the body of x ends up as:

(eval '(:m (8)))

which obviously implies a call to the function 8. With the extra quote in the definition of x, it would try this instead:

(eval '(:m '(8)))

which passes the list (8) to the :m macro without evaluating it.

1
  • Yes, this is it, or double quote ''(8) because defun removes one quote.
    – sjb
    Mar 25, 2015 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.