0

I love Racket's #;. I want to see it in every language that I ever use again. Can it be added to other Lisps via their macro systems? Or does the commenting character break the macro system's ability to read the code?

A sufficient answer will demonstrate a macro being built in any Lisp other than Racket that allows for a change in the commenting system. You need not actually implement Racket's #;, but I would like it if you do. Lisps with the least similarity to Racket, e.g. Clojure or any non-Scheme will be particularity nice to see.

J. Mini
  • 1,868
  • 1
  • 9
  • 38

2 Answers2

3

#; isn't a macro, it's what Common lisp would call a readmacro: what it does is defined at read time, not later than that. Read macros which aim to completely suppress input are mildly perilous because there needs to be a way of saying 'read the following thing, but ignore it', and that's only possible if any other readmacros behave well: there's nothing to stop someone defining a readmacro which produces some side-effect even if reading is suppressed.

However, well-behaved readmacros (which includes all of the standard ones and the rest of the standard reader) in CL won't do that: they'll listen to whether reading is being suppressed, and behave accordingly.

CL allows you to do this as standard by using its conditionalisation on features, and in particular #+(or) <expr> will always skip <expr>.

But you can define your own: #; is not predefined so you can define it:

(set-dispatch-macro-character
 #\# #\;
 (lambda (stream char n)
   (declare (ignore char))
   (let ((*read-suppress* t))
     (dotimes (i (or n 1) (values))
       (read stream)))))

After this, or at least with a better tested version of this, then #; <expr> (or obviously #;<expr>) will read as whitespace, and #2; ... ... will skip two following expressions:

> (let ((x #;1 #2; 2 3 4)) x)
4
  • You might get a better example by copy and pasting the Racket example from the answer linked in the question. Anyway, well done! – J. Mini Jan 10 '21 at 01:09
0

What you are looking for is #+(or) reader macro.

Since (or) evaluates to nil, the condition is always false the following form is never evaluated.

sds
  • 58,617
  • 29
  • 161
  • 278