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)
SaltyEgg
  • 1,498
  • 1
  • 15
  • 26
  • http://stackoverflow.com/questions/4288339/how-do-you-comment-out-all-or-part-of-a-lisp-s-exp-using-paredit – Adam Burry Sep 10 '13 at 15:54
  • @AdamBurry That question is more about editor support for multiline comments, although [the answer](http://stackoverflow.com/a/4324444/1281433) about the `#=(and)` and `#+(or)` are relevant (and [sds's answer](http://stackoverflow.com/a/18722177/1281433) includes them). – Joshua Taylor Sep 10 '13 at 15:56

4 Answers4

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.

Svante
  • 50,694
  • 11
  • 78
  • 122
sds
  • 58,617
  • 29
  • 161
  • 278
  • `#|...|#` actually are reader macros, too, and they're also the better option, because the conditional reader macros are meant to be used with features. – Rörd Sep 10 '13 at 15:35
  • 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. – SaltyEgg Sep 10 '13 at 15:41
  • read macro or regular macro? read macro is expanded by the reader and regular macro by the compiler/interpreter – sds Sep 10 '13 at 15:41
  • 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`) – SaltyEgg Sep 10 '13 at 15:56
  • 3
    @SaltyEgg You might have a look at [On Lisp Chapter 17. Read Macros](http://dunsmor.com/lisp/onlisp/onlisp_21.html). Also, see [2.1.4.4 Macro Characters](http://www.lispworks.com/documentation/HyperSpec/Body/02_add.htm) 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)`](http://www.lispworks.com/documentation/lw51/CLHS/Body/f_values.htm). – Joshua Taylor Sep 10 '13 at 15:58
  • 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. – Vatine Sep 11 '13 at 16:44
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.

Community
  • 1
  • 1
Lars Brinkhoff
  • 13,542
  • 2
  • 28
  • 48
  • 2
    This is technically correct, but the @SaltyEgg clarified in other comments that a read macro is desired, and those can be like comments (e.g., the `#| ... |#` macros). – Joshua Taylor Sep 10 '13 at 15:57
  • 1
    Right; my answer applies to the the question as originally stated. – Lars Brinkhoff Sep 10 '13 at 16:08
  • 1
    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. – Joshua Taylor Sep 10 '13 at 16:10
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.

zqy787
  • 35
  • 5
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.

Ehvince
  • 17,274
  • 7
  • 58
  • 79