Lispy Days

趣味で Lisp な日々 (index) (weblog) (view) (edit) (help)

The Craft of Text Editing

lispmeister.com より.The Craft of Text Editing がオンライ ンで読める! ……あれ?そういえば c.l.l で CL-Emacs が話題になったときにもブックマークしたんだった….

LispShell

括弧の対応がなくても使いやすいようなシェルっぽい環境を試しに作ってみる. リーダーマクロで前置記法と括弧をごまかす事 に. (なんか後置記法っぽくなってしまった)

LSH[6]> #@"../../".cd
#p"/home/lambda/commonlisp/"
LSH[7]> #@"user/lsh/".cd
#p"/home/lambda/commonlisp/user/lsh/"
LSH[8]> #@"./".merge("../../").merge("user/lsh/").ls
lsh.x86f
pathnames.x86f
lsh.lib
pathnames.lib
pathnames.fas
lsh.lisp
lsh.asd
pathnames.lisp
lsh.fas
NIL
LSH[9]> #@"./".merge("../../").merge("user/lsh/").merge("lsh.asd")
#P"../../user/lsh/lsh.asd"
LSH[10]> #@"./".merge("../../").merge("user/lsh/").merge("lsh.asd").cat
(in-package :asdf)

(defsystem :lsh
  :components ((:file "pathnames")
               (:file "lsh" :depends-on ("pathnames"))))

NIL
LSH[11]> #@"./".merge("../../").merge("user/lsh/").merge("lsh.asd").cat(:num t)
   1 (in-package :asdf)
   2
   3 (defsystem :lsh
   4   :components ((:file "pathnames")
   5                (:file "lsh" :depends-on ("pathnames"))))
   6
NIL
LSH[12]>

コマンド増すか read-eval-loop を自前で持つようにすれば良い感じになるかも…と思いつつ この #@ リーダーマクロを使って Lisp の S 式よりも書き易い場合を考えてみた.

LSH> '(setf #@bob.friend #@'<Human>.make-instance(:name "Jim" :friend #@'<Dog>.make-instance(:name "Pochi")))
(setf (friend bob)
        (make-instance '<human>
                       :name
                       "Jim"
                       :friend
                       (make-instance '<dog> :name "Pochi")))

こんなプログラムを

(in-package :lsh)

(defclass <Life> () ())
(defclass <%Social> ()
  ((friend :accessor friend :initarg :friend)
   (name :accessor name :initarg :name)))
(defclass <Human> (<Life> <%Social>) ())
(defclass <Dog> (<Life> <%Social>) ())

(defmethod say ((self <Human>))
  (write-line "Hello."))
(defmethod say ((self <Dog>))
  (write-line "Bow! Bow!"))

をロードしておいて,#@ マクロを試す.

LSH> #@'<Human>.make-instance
; Evaluation aborted
;;;; Compile file /home/lambda/commonlisp/user/lsh/test.lisp ...
LSH> #@'<Human>.make-instance
#<<human> {484A4665}>
LSH> #@'<Human>.make-instance(:name "Bob").name
"Bob"
LSH> #@'<Human>.make-instance(:name "Bob")
#<<human> {484A6EF5}>
LSH> (setf bob #@'<Human>.make-instance(:name "Bob"))
Warning:  Declaring bob special.
#<<human> {484A9CAD}>
LSH> (setf #@bob.friend #@'<Human>.make-instance(:name "Jim" :friend #@'<Dog>.make-instance(:name "Pochi")))
#<<human> {484B540D}>
LSH> #@bob.friend
#<<human> {484B540D}>
LSH> #@bob.friend.name
"Jim"
LSH> #@bob.friend.say
Hello.
"Hello."
LSH> #@bob.friend.friend.name
"Pochi"
LSH> #@bob.friend.friend.say
Bow! Bow!
"Bow! Bow!"
LSH> 

書き易さとして #@bob.friend.friend.say と (say (friend (friend bob))) のどっちが好みかという問題に帰結する. 今回はシェルスクリプティングが最終目的なので一般受けしそうな #@bob.friend.friend.say を使う方針でいこうかなぁ….