I've got another question involving self-reference in Common Lisp. I found a thread on Stack Exchange which poses a problem of writing the shortest program that would print all printable ASCII characters NOT present in the program's source code. This got me thinking how to tackle the problem in Common Lisp. I hit against two problems - one probably trivial, the other more tricky:
First is the case of writing a CL script, e.g. starting with
#!/usr/bin/env sbcl --script
. I thought that through*posix-argv*
I could access all command line arguments including the name of the called script. I also looked for the equivalent of Bash$0
but could find none. What worked for me in the end is this ugly Bash-ified SBCL script, which explicitly passes$0
to SBCL and proceeds from that:#!/bin/bash #| sbcl --script $0 $0 exit |# (defun file-string (path) (with-open-file (stream path) (let ((data (make-string (file-length stream)))) (read-sequence data stream) data))) (let* ((printable (mapcar #'code-char (loop for i from #x20 to #x7e collect i))) (absent (set-difference printable (coerce (file-string (cadr *posix-argv*)) 'list)))) (print (coerce absent 'string)))
My question regarding this point is: can you think of any way of doing it without relying so heavily on Bash supplying relevant arguments? Or, more briefly: is there a CL (SBCL in particular) equivalent of
$0
?Now comes the part that I'm totally puzzled with. Before resorting to the script approach above I tried to accomplish this goal in a more REPL-oriented way. Based on the
&whole
specifier indefmacro
and considerations in this thread I've tried to get the name of the macro from the&whole
argument and somehow "read in" its source. And I have absolutely no idea how to do it. So in short: given the name of the macro, can I somehow obtain thedefmacro
form which defined it? And I'm talking about a generic solution, rather than parsing the REPL history.EDIT: Regarding mbratch's question about use of
macroexpand-1
here's how I do it:(defmacro self-refer (&whole body) (macroexpand-1 `',body))
With this call I'm able to obtain
(SELF-REFER)
by calling(SELF-REFER)
. Which isn't much of a solution...
I hope someone could point me in the right direction. Thanks!