In Common Lisp, how to define a macro expanding to nothing (rather than `nil`)?
Asked Answered
G

4

6

I want to define a macro which can comment a s-expression, for example:

I hope that

(list 1 2 (comment-macro (something))) -> (1 2)

But if I define the macro like this

(defmacro comment-macro (x))

the result of the above form is actually

(1 2 nil)
Gramnegative answered 10/9, 2013 at 14:32 Comment(2)
#4288839Uppercase
@AdamBurry That question is more about editor support for multiline comments, although the answer about the #=(and) and #+(or) are relevant (and sds's answer includes them).Counterblow
P
9

You cannot accomplish what you want with a regular macro because its primary value (or nil if no values are returned) will always be used.

However, there are two common options:

  1. comment: #| ... |# - for general text

  2. feature expressions: #+(or) ... or #-(and) ... - for (temporarily?) disabling code

You can also define your own read macros using set-macro-character and set-dispatch-macro-character.

Paisano answered 10/9, 2013 at 14:52 Comment(6)
#|...|# actually are reader macros, too, and they're also the better option, because the conditional reader macros are meant to be used with features.Engels
I really truly want a read macro. I think it's convenient if I can quickly switch on/off a s-expression. But I just don't know how to expand them to nothing.Gramnegative
read macro or regular macro? read macro is expanded by the reader and regular macro by the compiler/interpreterPaisano
But how can I define my own read macro? I know how to define a dispatch-macro, but it just not works (always returns nil)Gramnegative
@Gramnegative You might have a look at On Lisp Chapter 17. Read Macros. Also, see 2.1.4.4 Macro Characters in the HyperSpec which says that "The function either returns the parsed object, or else it returns no values to indicate that the characters scanned by the function are being ignored (e.g., in the case of a comment)." If you want to indicate a comment, return zero values with (values).Counterblow
Note that using a read macro means you will need to re-read the original form, if you want to switch the disabled state for an S-expression.Isothere
B
3

In Common Lisp, there is no way to define a macro which expands to nothing. The primary value returned from the macro (i.e. the macro function) is always inserted in place of the macro call.

Bigname answered 10/9, 2013 at 15:6 Comment(3)
This is technically correct, but the @Gramnegative clarified in other comments that a read macro is desired, and those can be like comments (e.g., the #| ... |# macros).Counterblow
Right; my answer applies to the the question as originally stated.Bigname
Agreed. I was just highlighting the difference for any readers who come across the later, especially in the case that the question gets edited to better match the OP's desires.Counterblow
L
0

The short answer is you can't, but still there are many other ways to solve it.

first I thought about using (values) in the last sentence of macro,but in SBCL that doesn't work -- It seems equal (values) with nil.

The easier way to think is to use remove:

(remove nil '(1 2 (comment-macro (x)))))

but it may not work anytime.

the best way to do it is using condition:

(aif (comment-macro (x)) (list 1 2 it) (list 1 2))

for the condition I have met, I just turn the situtation "I have to let it return nothing" to "with proper condition I construct proper code".I hope that works.

Lucius answered 21/9, 2018 at 6:48 Comment(0)
S
0

Here's the implementation of serapeum:comment:

(defmacro comment (&body body)
  "A macro that ignores its body and does nothing. Useful for
comments-by-example.

Also, as noted in EXTENSIONS.LISP of 1992, \"This may seem like a
silly macro, but used inside of other macros or code generation
facilities it is very useful - you can see comments in the (one-time)
macro expansion!\""
  (declare (ignore body)))

(aliased to example)

Serapeum is intended to be portable.

Shakedown answered 19/3, 2023 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.