亀田馬志 masashi.kameda@gmail.com writes:
Hi.
I saw something strange about SLIME and tried googling about it. But couldn't find any clues. Please allow me to post here.
I read "Let Over Lambda", a book about macros, and noticed function, named with "!", on a file couldn't be recognized nor compiled through using SLIME.
The codes are listed below, using some utilities from the book "On Lisp", written by Paul Graham.
;; *-SIMBOL-P-GENERATOR
;; (defmacro *-symbol-p-generator (str) ;; (let ((len (1+ (length str))) ;; (init-part (string-upcase str))) ;; `(defun ,(intern (concatenate 'string init-part "-SYMBOL-P")) (s) ;; (and (symbolp s) ;; (> (length (symbol-name s)) ,len) ;; (string= (symbol-name s) ;; ,init-part ;; :start1 0 ;; :end1 ,len)))))
;; G-BANG-SYMBOL-PREDICATE ;; (*-symbol-p-generator "g!")
(defun g!-symbol-p (s) (and (symbolp s) (> (length (symbol-name s)) 2) (string= (symbol-name s) "G!" :start1 0 :end1 2)))
;; DEFMACRO-WITH-G-BANG! (defmacro defmacro/g! (name args &body body) (let ((syms (remove-duplicates (remove-if-not #'g!-symbol-p (flatten body))))) `(defmacro ,name ,args (let ,(mapcar (lambda (s) `(,s (gensym ,(subseq (symbol-name s) 2)))) syms) ,@body))))
;; ONCE-ONLY (defmacro once-only ((&rest names) &body body) (let ((gensyms (loop for n in names collect (gensym)))) `(let (,@(loop for g in gensyms collect `(,g (gensym)))) `(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n))) ,(let (,@(loop for n in names for g in gensyms collect `(,n ,g))) ,@body)))))
;; O-BANG-SYMBOLS ;; (*-symbol-p-generator "o!")
(defun o!-symbol-p (s) (and (symbolp s) (> (length (symbol-name s)) 2) (string= (symbol-name s) "O!" :start1 0 :end1 2)))
(defun o!-symbol-to-g!-symbol (s) (symb "G!" (subseq (symbol-name s) 2)))
Wrap these (and the above) function definitions in an
(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) ...)
;; DEFMACRO-BANG (defmacro defmacro! (name args &body body) (let ((os (remove-if-not #'o!-symbol-p args))) (let ((gs (mapcar #'o!-symbol-to-g!-symbol os))) `(defmacro/g! ,name ,args `(let ,(mapcar #'list `(,,@gs) `(,,@os)) ,(progn ,@body))))))
;; NIF (defmacro! nif (o!expr pos zero neg) `(cond ((plusp ,g!expr) ,pos) ((zerop ,g!expr) ,zero) (t ,neg)))
;;; This is the end of file
C-c C-k shows such a message below.
; in: DEFMACRO! NIF
; (DEFMACRO! NIF (O!EXPR POS ZERO NEG) ; `(COND ((PLUSP ,G!EXPR) ,POS) ((ZEROP ,G!EXPR) ,ZERO) (T ,NEG))) ; ; caught ERROR: ; (during macroexpansion of (DEFMACRO! NIF ...)) ; The function O!-SYMBOL-P is undefined. ; ; compilation unit finished ; caught 1 ERROR condition
; /home/cametan/lol.chapter_2.fasl written ; compilation finished in 0:00:00.091
Strange. The function O!-SYMBOL-P was THERE on the file.
But its definition is not yet there at compilation time where it is used in DEFMACRO!. The EVAL-WHEN make it also available at compilation time.
So I check sbcl repl directly on my bash; in that case, the file could be loaded and compiled without any problem. Therefore, SLIME must have the problem.
No, it's either a problem of your or that book's author's understanding of the execution model of Common Lisp.
P.S. I also found SLIME's REPL don't recognized reader macros. Though making reader macro with #foo, SLIME says something like "incomplete input".
I think this came up before. What's the exact way to trigger it anyway?
CL-USER> (set-dispatch-macro-character ## #\f (constantly t)) T CL-USER> #f T
seems to work just fine.
-T.c