ãã¯ãå±éæã«å¯ä½ç¨ãèµ·ãããã¨ã®æããã
Lisp Advent Calendar 2015ã®23æ¥ç®ã®è¨äºã§ãã
ãããåã³è °ã§ãããããã£ã¨ç©ºãã¦ããã®ã§ããããã§ç»é²ãã¦ã¿ã¾ããã
ãã¯ãå±éæã«å¯ä½ç¨ãèµ·ãããªå±éºãã¨ããå 容ã§ãã
åæ¸ã
On Lisp: ãã¯ãã®ãã®ä»ã®è½ãç©´ã«ããã¨ããLispã¯ï¼ãã¯ãå±éãçæããã³ã¼ã㯠第3ç« ã§è«ããæå³ã§ç´ç²ã«é¢æ°çã§ãããã®ã¨äºæãã¦ããï¼ å±éãè¡ãã³ã¼ãã¯å¼æ°ã¨ãã¦æ¸¡ãããå¼ã«ã®ã¿ä¾åãã¹ãã§ï¼ å¤ãè¿ãä»ã«ã¯å¨å²ã®ä¸çã«å½±é¿ãããã¨ãã¹ãã§ã¯ãªãï¼ãã¨ããã¾ããä¸ç·ãè¨ãæããã¨å¯ä½ç¨ãèµ·ãããªã¨ãããã¨ã«ãªãã¨æãã¾ããNGä¾ã®ä¸ã¤ã«ããã¯ãã®å±éåæ°ãæ°ãããã¨ãã¦ã°ãã¼ãã«å¤æ° *nil!s*
ã«è§¦ã以ä¸ã®ä¾ã示ããã¦ãã¾ãã
(defmacro nil! (x) ; 誤ã (incf *nil!s*) `(setf ,x nil))
æ£ç´ã«è¨ãã¨ãã®ä¸ã«ãã説æã§ã¯çµå±ãã¤å°ãã®ããã³ã¨æ¥ã¾ããã§ãããããParenscriptãããã£ã¦ãã¦ããã§æ£ã ããã£ã*1ã®ã§ãåå¼·çµæãå±éãã¦ã¿ã¾ãã次ãä¼ãããã¨ãç®æ¨ã§ãã
- ã©ãæãããã®ãã¨ããæè¦
- ã©ããã¦ãããªãã®ãã¨ããçå±
大å¤æ°ã®Lisperã«ã¨ã£ã¦ã¯åãããã£ã話ã ããã¨æãã¤ã¤ã次ã®ãããªæãã§é²ãã¦ããã¾ãã
- å座ï¼Parenscriptã®ç°¡åãªç´¹ä»
- æããä¼ãããããããªãä¾
- 解説
- å®éã«ããã£ã話
- ã¾ã¨ã
å座ï¼Parenscriptã®ç°¡åãªç´¹ä»
Parenscriptã¯Common Lispã®ï¼ãµãã»ããï¼ã³ã¼ããJavaScriptã³ã¼ãã«å¤æãã¦ãããã©ã¤ãã©ãªã§ããä¸ã®ããã« ps:ps
ãã¯ãã®ä¸ã«Common Lispã³ã¼ããæ¸ãã¨Javascriptã³ã¼ããæååã¨ãã¦åºåãã¦ããã¾ãã
CL-USER> (ql:quickload :parenscript :silent t) (:PARENSCRIPT) CL-USER> (ps:ps (test-func 10 20)) "testFunc(10, 20);" CL-USER> (ps:ps (funcall (lambda (a b) (+ a b)) 10 20)) "(function (a, b) { return a + b; })(10, 20);"
Lispã¨ãã¦ã¯å¤ããªããã¯ãããµãã¼ãããã¦ãã¦ã大ããã¯æ¬¡ã®2ã¤ã®æ¹æ³ã§å®ç¾©ã§ãã¾ãã
;; psç°å¢å ã§defmacroãå¼ã¶æ¹æ³ CL-USER> (ps:ps (defmacro test-macro (a b) `(+ ,a ,b)) (test-macro 10 20)) "10 + 20;" CL-USER> (ps:ps (test-macro 20 30)) ; ã°ãã¼ãã«ã«å®ç¾©ããã "20 + 30;" ;; defpsmacro ã«ããæ¹æ³ CL-USER> (ps:defpsmacro test-psmacro (&rest rest) `(* ,@rest)) TEST-PSMACRO CL-USER> (ps:ps (test-psmacro 10 20 30)) "10 * 20 * 30;"
psç°å¢å
ã§ã®defmacro
ã¯å
é¨çã«ã¯defpsmacro
ãå¼ãã§ãã¾ãããã®ãããã©ã¡ããåãããã«ä½¿ãã¾ãâ¦ã ã£ããè¯ãã£ãã®ã§ããâ¦ã
ä½ãèµ·ããã®ã
Parenscriptç¨ã®ãã¯ãï¼ä»¥ä¸ãPSãã¯ãï¼å®ç¾©ã2種é¡ç´¹ä»ãã¾ããããããã¯PSãã¯ãã管çããã°ãã¼ãã«ãªå¤æ°parenscript::*macro-toplevel*
ã«ç»é²ãããã¿ã¤ãã³ã°ãç°ãªãã¾ãã
- psç°å¢å
ã§ã®
defmacro
: å±éãæãã«ãã¯ãå®ç¾©ãç»é²ããã defpsmacro
: å±éãå¾ãã«ãã¯ãå®ç¾©ãç»é²ããã
å¾ã£ã¦ãpsç°å¢å
ã§ã® defmacro
ã®æ¹ãå±éæã«å¯ä½ç¨ãèµ·ããã¨ããã¾ããåä½ããã¦ãã¾ãããããä½ãå¼ãèµ·ããã®ãè¦ã¦ã¿ã¾ãã
æºå
REPLãä¸ã¤ã®ã¹ã¯ãªãããã¡ã¤ã«ã§è©¦ãã¦ãã¦ãä¸ã èµ·ããªãç¾è±¡ã§ãããããå°ããªããã¸ã§ã¯ããä¸ã¤èµ·ããã¦ãquicklispã®é ä¸ã«ç½®ãã¾ãã
CL-USER> (ql:quickload :cl-project :silent t) (:CL-PROJECT) CL-USER> (cl-project:make-project (merge-pathnames #p"test-ps-eval-order" ql:*quicklisp-home*) :author "eshamster" :licence "MIT" :depends-on '(parenscript)) writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/.gitignore writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/README.markdown writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/README.org writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/test-ps-eval-order-test.asd writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/test-ps-eval-order.asd writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/src/test-ps-eval-order.lisp writing /home/esh/.roswell/impls/ALL/ALL/quicklisp/test-ps-eval-order/t/test-ps-eval-order.lisp T
次ã«ãã§ãããã£ãsrc/test-ps-eval-order.lisp ãç·¨éãã¦æ¬¡ã®ããã«2種é¡ã®æ¹æ³ã§Parenscriptç¨ã®ãã¯ããå®ç¾©ãã¦ã¿ã¾ããã¾ãããããã®ãã¯ãã®å±éçµæã確èªãããããprint-ps
é¢æ°ãä½æ & exportãã¾ãããªããeval-when
ããªãã¨(print (ps (test-defpsmacro)))
ã®é¨åã§ãã¯ããåãã¾ããããæ¬é¡ã§ã¯ãªãã®ã§è©³ç´°ç¥ã§ã*2ã
ããã«ãã§ããã ãã¯ãªã¼ã³ãªç°å¢ã§å®è¡ãããã®ã§ãRoswellã¹ã¯ãªãããä¸ã¤èµ·ããã¦ãä¸è¨ã®print-ps
é¢æ°ãå¼ã³åºãã³ã¼ãï¼ã¨Parenscriptããã¼ãããã³ã¼ãï¼ã追å ãã¾ãã
# â»OSã³ã³ã½ã¼ã« $ cd ä»»æã®å ´æ $ ros init execute.ros
å®è¡
ãã¦å®è¡ã§ãã
$ ./execute.ros To load "test-ps-eval-order": Load 1 ASDF system: test-ps-eval-order ; Loading "test-ps-eval-order" [package test-ps-eval-order] ----- From test-ps-eval-order::print-ps ----- "ok = 'expanded by test-defpsmacro';" "ok = 'expanded by test-defmacro-in-ps';"
ã©ã¡ãã®å®ç¾©ãããã±ã¼ã¸å é¨ã§ã¯ãã¾ãåãã¦ããããã§ãï¼ä¸3è¡ï¼ã次ã¯ããã±ã¼ã¸å¤ï¼execute.roså´ï¼ããå¼ã³åºãããã以ä¸ãä¿®æ£ãã¾ãã
- src/test-ps-eval-order.lispã®exportã«ä¸¡ãã¯ãã追å
- execute.rosã®mainé¢æ°ã«ããããå¼ã³åºãã³ã¼ãã追å
;; src/test-ps-eval-order.lisp (defpackage test-ps-eval-order (:use :cl :parenscript) (:export :test-defpsmacro :test-defmacro-in-ps :print-ps))
;; execute.ros (defun main (&rest argv) (declare (ignorable argv)) (print-ps) (princ "----- From execute.ros ----") (print (ps (test-defpsmacro))) ; ãã㨠(print (ps (test-defmacro-in-ps))) ; ããã®2è¡ã¯print-psé¢æ°ã¨åãã³ã¼ã (fresh-line))
ããã¦å®è¡ã
$ ./execute.ros To load "test-ps-eval-order": Load 1 ASDF system: test-ps-eval-order ; Loading "test-ps-eval-order" [package test-ps-eval-order] ----- From test-ps-eval-order::print-ps ----- "ok = 'expanded by test-defpsmacro';" "ok = 'expanded by test-defmacro-in-ps';" ----- From execute.ros ---- "ok = 'expanded by test-defpsmacro';" "ok = 'expanded by test-defmacro-in-ps';"
ãªãã åé¡ãªããããªããâ¦ã¨æã£ã¦ãããä¸åº¦å®è¡ãã¦ã¿ã¾ãã
$ ./execute.ros To load "test-ps-eval-order": Load 1 ASDF system: test-ps-eval-order ; Loading "test-ps-eval-order" ----- From test-ps-eval-order::print-ps ----- "ok = 'expanded by test-defpsmacro';" "ok = 'expanded by test-defmacro-in-ps';" ----- From execute.ros ---- "ok = 'expanded by test-defpsmacro';" "testDefmacroInPs();"
ãªãã¨ãããã¨ã§ãããã1åç®ã¨ç°ãªããexecute.roså´ã ãpsç°å¢å
ã®defmacro
ã§å®ç¾©ããtest-defmacro-in-ps
ãã¯ããæ¶ãã¦ãã¾ãï¼é¢æ°æ±ãããã¦ãã¾ãï¼ã
- åãããã«æ¸ããã®ã«çµæãéãâ¦
- â æ¸ããã³ã¼ãããããçºãã¦ãåå ãåãããªã
- 2度å®è¡ããã¨çµæãå¤ããâ¦
- â åç¾æ¡ä»¶ã«ç¢ºä¿¡ãæã¦ãªããããè²ã ããã£ã¦ãç´ã£ãã®ãå¤æã§ããªã
è¦ãç¬éãããã°ããæ°åãåãããè¦ç´ ã«æºã¡ã¦ãã¾ãã
解説
ã©ããã¦ãããªã£ããã解説ããããã«ãç¾è±¡ãåç¾ããå°ããªã³ã¼ããæ¸ãã¦åä½ãçºãã¦ã¿ã¾ãã
ã©ããã¦ãããªã£ã
ä¸è¨ã®2åé£ç¶å®è¡ã®åºåãè¯ãè¦ãã¨ãæ¬ä½ã§ããprint-ps
ã®åºåã®æåã«éããããã¾ãã1åç®ã¯[package test-ps-eval-order]
ã®åºåãããã¾ãã2åç®ã¯ããã¾ãããquicklisp/setup.lispãè¦ã¦ã¿ãã¨ãããã¯ã³ã³ãã¤ã«æã®ã¿åºåãããã¡ãã»ã¼ã¸ã®ããã§ã*3ã
(defun macroexpand-progress-fun (old-hook &key (char #\.) (chars-per-line 50) (forms-per-char 250)) ;; ï½ç¥ï½ (show-package (name) ;; Only show package markers when compiling. Showing ;; them when loading shows a bunch of ASDF system ;; package noise. (when *compile-file-pathname* (finish-line) (show-string (format nil "[package ~(~A~)]" name))))
ããããã以ä¸ã®éãã«ãã1åç®ã¨2åç®ã§çµæãå¤ãã£ãã¨æ¨æ¸¬ã§ãã¾ãããã¯ãå±éæã®å¯ä½ç¨ã¯ãã¤ããªã«ã¯æ®ããªããã¨ã«æ³¨æãã¾ã*4ã
- 1åç®ï¼test-ps-eval-orderãã³ã³ãã¤ã«*5ãç¶ãã¦ããããã¼ããã¦execute.rosãå®è¡
- ã³ã³ãã¤ã«ããå®è¡ã¾ã§ãåãç°å¢ã§è¡ããã
- â ãã¯ãå±éæã®å¯ä½ç¨ï¼
test-defmacro-in-ps
ãã¯ãã®å®ç¾©ï¼ã¯ãã¤ããªã«ã¯æ®ããªãããç°å¢ã«ã¯æ®ã£ã¦ãã - â
test-defmacro-in-ps
ãã¯ãã®å®ç¾©ãexecute.rosãããè¦ãã
- 2åç®ï¼ã³ã³ãã¤ã«æ¸ã¿ã®test-ps-eval-orderããã¼ããã¦execute.rosãå®è¡
- ã³ã³ãã¤ã«ã¨å®è¡ãç°ãªãç°å¢ã§è¡ããã
- â ãã¯ãå±éæã®å¯ä½ç¨ã¯ãã¤ããªã«ã¯æ®ããªããããã®ããç°å¢ã«ããã¼ããããªã
- â
test-defmacro-in-ps
ãã¯ãã®å®ç¾©ãexecute.rosããã¯è¦ããªã
çµå±ã®ã¨ãããã¯ãå±éæã®å¯ä½ç¨ã¯ãã©ã¤ãã©ãªã«å¤æ´ããªãå ´åã¯ã³ã³ãã¤ã«ãçç¥ãã¦ãçµæã¯å¤ãããªããã¨ããï¼å¦¥å½ãªï¼ä»®å®ãå´©ããã¨ã«ãªãã¾ãã
ãªãããã®ä»2ç¹ã®çåã¯ä»¥ä¸ã®ããã«èª¬æã§ãã¾ãã
- ãªããtest-ps-eval-orderã©ã¤ãã©ãªå
é¨ããã¯å¸¸ã«
test-defmacro-in-ps
ãè¦ããã®ã- ãã¤ããªã«ã¯
test-defmacro-in-ps
ãã¯ããæ¢ã«å±éãããç¶æ ã§è¨é²ããã¦ãããã- ps:psãã¯ãã«ãã
test-defmacro-in-ps
ãã¯ãã®å±éãã³ã³ãã¤ã«æã«è¡ããã
- ps:psãã¯ãã«ãã
- ãã¤ããªã«ã¯
- ãªãã
test-defpsmacro
ã¯å¸¸ã«ã©ãããã§ãè¦ããã®ã- ãã¤ããªã«Parenscriptç¨ãã¯ãå®ç¾©ï¼=
parenscript::*macro-toplevel*
ã¸ã®ç»é²ï¼ãè¡ãå¦çèªä½ãæ®ãã®ã§ããã¼ãæã«å®ç¾©ãå®è¡ããããã
- ãã¤ããªã«Parenscriptç¨ãã¯ãå®ç¾©ï¼=
å°ããåç¾ãã¦ã¿ã
解説ã®ããã¨ããããã¯ãç¾è±¡ãããå¥ãåºãã«ããããã®å°ããªã³ã¼ããæ¸ãã¦ã¿ã¾ãã
2ã¤ã®ãã¡ã¤ã«ãç¨æãã¾ãã1ã¤ã¯ã©ã¤ãã©ãªã®ã¤ããã§test-lib.lispãããã1ã¤ã¯ãããå©ç¨ããã¢ããªã±ã¼ã·ã§ã³ã®ã¤ããã§test-app.rosã¹ã¯ãªãããç¨æãã¾ãã
test-lib.lisp
(eval-when (:compile-toplevel :execute :load-toplevel) (defvar *hoge-func-list* nil)) (defmacro defhoge (name &body body) `(progn (pushnew ',name *hoge-func-list*) (defun ,name () ,@body))) (defmacro defhoge-wrong (name &body body) (pushnew name *hoge-func-list*) ; 誤ã `(defun ,name () ,@body)) (defhoge lib 1) (defhoge-wrong lib-wrong 2) (defun print-all-hoge () (dolist (hoge (reverse *hoge-func-list*)) (format t "~A from ~A~%" (funcall hoge) hoge)))
å¤ã®ç°å¢ã«è§¦ããããªãã®ã¯å¤§æµdefineç³»ãã¯ãã ããã¨æããtest-lib.lispã§ã¯defhoge
ã¨ããhogeãå®ç¾©ãããã¯ããæä¾ãã¾ããdefhoge-wrong
ãåæ§ã§ããããã¯ãå±éæã«ç»é²ãè¡ãã¨ããééã£ãåä½ããã¾ããã¾ãããããããå©ç¨ãã¦2ã¤ã®hogeãlib
ã¨lib-wrong
ãå®ç¾©ãã¾ããããã«ãhogeãç»é²é ã«åºåããprint-all-hoge
é¢æ°ãæä¾ãã¾ãã
test-app.ros
#!/bin/sh #|-*- mode:lisp -*-|# #| exec ros -Q -- $0 "$@" |# (defvar *load-kind* 0) ; ãããæ¸ãæãã¦å®è¡ãã: 0, 1, 2 (case *load-kind* (0 (load "test-lib.lisp")) (1 (compile-file "test-lib.lisp" :output-file "test-lib.fasl" :print nil :verbose nil) (load "test-lib.fasl")) (2 (load "test-lib.fasl")) (t (error "arg error"))) (defhoge app 10) (defhoge-wrong app-wrong 20) (defun main (&rest argv) (declare (ignorable argv)) (print-all-hoge) (fresh-line))
test-app.rosã§ã¯ä¸è¨ã®test-lib.lispããã¼ããã¦2ã¤ã®hogeãapp
ã¨app-wrong
ãå®ç¾©ããprint-all-hoge
ãå¼ã³åºãã¦ç»é²æ¸ã¿hogeä¸è¦§ãåºåãã¾ãããã¼ãã¯*load-kind*
ã®å¤ã«å¿ãã¦3種é¡ã®ããããã®æ¹æ³ã§è¡ãã¾ãã
*load-kind*
ã0ã®å ´åï¼test-lib.lispèªä½ããã¼ã
$ ./test-app.ros 1 from LIB 2 from LIB-WRONG 10 from APP 20 from APP-WRONG
*load-kind*
ã1ã®å ´åï¼test-lib.lispãã³ã³ãã¤ã«ããç¶ãã¦test-lib.faslããã¼ã
$ ./test-app.ros 2 from LIB-WRONG 1 from LIB 10 from APP 20 from APP-WRONG
*load-kind*
ã2ã®å ´åï¼ã³ã³ãã¤ã«æ¸ã¿test-lib.faslããã¼ãï¼â»äºåã«1ã®ã±ã¼ã¹ãåãããã¨ï¼
$ ./test-app.ros 1 from LIB 10 from APP 20 from APP-WRONG
ããã¾ã§ã®èª¬æã§åçã¯åããã¯ããªã®ã§è§£èª¬ã¯çç¥ãã¾ãã念ã®ãããæåã®test-ps-eval-orderã®ä¾ã§ã¯ã1åç®ã®å®è¡ã¯*load-kind*
ã1ã®å ´åã«ã2åç®ã®å®è¡ã¯*load-kind*
ã2ã®å ´åã«ç¸å½ãã¾ãããªãããã®ä¾ã§ã¯*load-kind*
ãåºå®ãã¦ããéããä½åº¦å®è¡ãã¦ãå®è¡çµæã¯å¤ããã¾ããã
ä½è«ã§ãããhogeãè¨é²ãã*hoge-func-list*
ãdefvar
ã§ã¯ãªãdefparameter
ã§å®ç¾©ããã¨ã*load-kind*
ã1ã®ã¨ãã®çµæã2ã®å ´åã¨åãã«ãªãã¾ããå®ç¾©æ¸ã¿ã®å¤æ°ãä¸æ¸ãããdefparameter
ã¨ä¸æ¸ãããªãdefvar
ã®æåã®éãã§ããã
å®éã«ããã£ãä¾
æå¾ã«ãã®è¨äºã®çºç«¯ã¨ãªã£ãã³ã¼ãããParenscriptãããå°ã便å©ã«ä½¿ããªããã¨è²ã å®é¨ããã¦ããps-experimentã¨ããã©ã¤ãã©ãªãä½ã£ã¦ãã¾ã*6ã
ãã®ä¸ã§ãpsç°å¢ä¸ã§å©ç¨ã§ããdefstruct
ã®ãµãã»ãããä½ã£ãã®ã§ããããããå©ç¨ããã³ã¼ãã§ã¨ã©ã¼ãåºã¦æ£ã
ã«ãããã¾ãããå®ç¾©ã®ä¸é¨ãè¼ãã¾ããåé ã®ãã¼ã¹ç³»ã®é¢æ°ã®å®ç¾©ã¯æ¬é¡ã¨ç¡é¢ä¿ãªããçç¥ãã¾ãã
ã³ã¡ã³ãã«ããã¾ãããã¢ã¯ã»ãµã®å®ç¾©ã§å©ç¨ãã¦ããdefmacro
ãåé¡ã§ããããã§æ³¨æã§ãããdefpsmacro
ã§å®ç¾©ããParenscriptç¨ã®ãã¯ãã¯ãçµå±psç°å¢ä¸ã§å±éããã¾ãããã®ãããdefpsmacro
ä¸ã§ã®defmacro
ã¯psç°å¢ä¸ã§ã®defmacro
ã¨å®è³ªä¸åããã®ã§ãã
ã¢ã¯ã»ãµããã¯ãå±éæã«å®ç¾©ããã¦ãã¾ãããããã®defstruct
ã§å®ç¾©ããæ§é ä½ãå¥ã®ã©ã¤ãã©ãªãã使ããã¨ããã¨ãã¢ã¯ã»ãµã ãè¦ããªãï¼ãã¨ãããï¼ã¨ããåé¡ã«æ©ã¾ããããã¨ã«ãªãã¾ãï¼ãªãã¾ããï¼ã
åä»ãªãã¨ã«ããã®åé¡ã¯ps-experimentã®ãã¹ãã§ã¯æ¤åºããã¾ããã§ããããã¹ãã§ã¯åãç°å¢ä¸ã§defstruct
ã«ããæ§é ä½å®ç¾©ã¨ãã®ãã¹ãã³ã¼ãããã¼ããããããåé¡ãªããåãã¦ãã¾ãã¾ããããä¸è¨ã®test-libã¨test-appã®ä¾ã§è¨ãã¨ãtest-appå´ã§ã®defhoge-wrong
ã®å©ç¨ã«ç¸å½ããã±ã¼ã¹ã§ãã
çµå±ã©ãããã®ãã§ãããpsç°å¢ä¸ã§ã®defstruct
ã¯ããµãã¼ããããã¨ã«ãã¾ããã代ããã«ããããã©ãããã¦ãããã¬ãã«ã§å©ç¨ããããã«ç¨æãã¦ããdefmacro.ps
ãã¯ããç´æ¥æä¾ãããã¨ã«ãã¾ããã
defxxx.ps
ç³»ãã¯ãã¯ãããã¬ãã«ã§Parenscriptç¨ã®è²ã
ãå®ç¾©ããããã«ps-experimentã§ç¨æãã¦ãããã¯ã群ã§ããå
¨ä½ã¨ãã¦ãdefpsmacro
ãdefmacro
ã§ããã®ä»defxxx
ãdefxxx.ps
ã§ç½®ãæãã以å¤ãè¦ãç®ã«å¤§ããªéãã¯ããã¾ããã
ãã ããã¯ãå±éæã«ã°ãã¼ãã«ãªå¤ãèªã¿è¾¼ãã§ããç®æããããåé¡ããªããæ°ã«ãã¦ãã¾ããå
·ä½çã«ã¯ãincludeï¼ã¹ãããå®ç¾©ã®ç¶æ¿ï¼ãå®ç¾ããããã«ãparse-defstruct-name-and-options
ã*ps-struct-slots*
ï¼ä¸è¨ã§ã¯çç¥ï¼ã¨ããã°ãã¼ãã«ãªããã·ã¥ãèªã¿è¾¼ãã§ãã¾ãããã®ããã·ã¥ã¸ã®ã¹ãããã®ç»é²ã¯register-defstruct-slots
ã§è¡ã£ã¦ãã¾ããeval-when
ã«ããæå®ã§ãä¸è¨ã®ãããªã³ã¼ããã³ã³ãã¤ã«ããã¨ãã«ããchildã®ãã¯ãå±éãããæ©ã段éã§parentã®ç»é²ãè¡ãå½¢ã«ãªã£ã¦ãã¾ãï¼ãã¤ãã¯ãå±éæã®å¯ä½ç¨ãé¿ãã¦ãã¾ãï¼ãããã®ããã·ã¥èªã¿è¾¼ã¿ã¯æããã«ãç´ç²ã«é¢æ°çãã§ãªãããæªããã®ã§ãããå½é¢ããã§æ§åãè¦ããã¨æã£ã¦ãã¾ãã
(defstruct parent a b) (defstruct (child (:include parent)) c)
ç¾ç¶ã§è¦ãã¦ããæªãããªåä½ã¨ããã¨ãã³ã³ãã¤ã«âãã¼ãã¨ããã¨åãå®ç¾©ã2度å®è¡ãããã¨ãããã®ãããã¾ããããåããã®ã§ä¸æ¸ãããã ããªã®ã§å¤§æµåé¡ãªãâ¦ã¯ããã¡ãªã¿ã«ããã®è¾ºãã®åä½ã¯ä¸è¨test-lib, test-appã«ããã¦ã1. defhoge
ã®progn
ãeval-when
ã«ç½®ãæããã2. pushnew
ãpush
ã§ç½®ãæããã3. *load-kind*
ã1ã«è¨å®ãããã¨ãã¦ã¿ãã¨ç¢ºèªã§ãã¾ãï¼"1 from LIB"ã2ååºã¾ãï¼ã
è¨äºãæ¸ãã«ããããåèã«Clozure CLã®defstruct
ã®å®è£
ãè¦ã¦ã¿ãã®ã§ãããã°ãã¼ãã«ãªç°å¢ã¸ã®ç»é²ã¯ããã¾ã§ãã¼ãæã«è¡ã£ã¦ããï¼%defstruct-do-load-time
ï¼ãã³ã³ãã¤ã«æã«ã¯ã¬ãã·ã«ã«ãªç°å¢&environment env
ã«ä¸æçã«ç»é²ãããã¨ã§å¯ä½ç¨ãé¿ãã¦ããããã§ãï¼define-compile-time-structure
ï¼ããã¯ãå±éããç´ç²ã«é¢æ°çããªåä½ãããããã«ããªãæ
éã«ä½ããã¦ããæ§åã伺ãã¾ãã注æã§ãããã¾ã &environment
ãç解ãåãã¦ããªãã®ã§åãè¨ã£ã¦ããããããã¾ããã
ã¾ã¨ãï¼æããã«ã¤ãã¦æ¹ãã¦
ãã¯ãå±éæã«å¯ä½ç¨ãèµ·ãããã¨ã®æãããã¯ãåå ãç¹å®ãã«ãããã°ã«ã¤ãªãããã¨ããã¨ããã«ã¤ãã¾ãã
ãã¯ãå±éæã®å¯ä½ç¨ã®çµæã¯ç°å¢ã«ã¯æ®ããããLispã®å©ç¹ã§ããã¤ã³ã¯ãªã¡ã³ã¿ã«ãªéçºã®æä¸ã«ã¯ã¾ãæ°ã¥ãã¾ãããããã«ããã¹ããæ¸ãã¦ã¯ãªã¼ã³ãªç°å¢ã§å®è¡ãã¦ãã¦ãã¾ã æ°ã¥ããªãã±ã¼ã¹ãå¤ãã§ããããã¯ãä¸è¨ã®ps-experimentã®defstruct
ãµãã»ããã®ããã«ãèªèº«ã§ã¯ä½¿ããªãå¤åãã«æä¾ããæ©è½ã§èµ·ãããããã§ããããã¦ããæ¥ãå®è¡æ¡ä»¶ã«å¿ãã¦çµæãå¤ãããããªåç¾ãã«ãããã°ã«ééãã¾ãã
ãã°ã®åå ç¹å®ãå°é£ã«ããå ¸åçãªè¦å ã§ãããçºè¦ã¾ã§ã«æéãããããã¨ã¨ãåç¾æ¡ä»¶ãåããã«ãããã¨ã¨ãã両æ¹ãæºããããã§ããèªåã¯ãã®ãã°ã«ééãã¦ããè¦å½éãã®æ¹åã«ãèµ°ãã¤ã¤æ°æ¥è¦ãã¿ã¾ããã
ã¨ãããã¨ã§ããã¯ãå±éæã®å¯ä½ç¨ã«ã¯ææã«ãªãã¾ããããã¨é迦ã«èª¬æ³ãããã¨ããã§çµããã«ãã¾ãã
*1:Parenscriptã®ä»æ§ã¨é¢ä¿ãªãåæã«ããã£ãé¨åãå¤ã ããã¾ããããã¨ããããé¢ä¿ããé¨åã®ç´¹ä»ã§ã
*2:eval-whenãdefpsmacroå ã§å¼ã°ãã¦ããªãã®ã¯ãããã¯ããã§åé¡ãªã®ã§ãããå¤ä»ãã§å¯¾å¦å¯è½ãªããå·ã¯æµ ãã§ããeval-whenèªä½ã«ã¤ãã¦åèã«ãªãã®ã¯ãã®è¾ºããmacros - Eval-when uses? - Stack Overflowãã§ããããããªããParenscriptã®ãã®ã³ãããï¼ãªã³ã¯ï¼ã§masterã¯ä¿®æ£ããã¦ãã¾ãããquicklispã®åç §ãã¦ããhttp://common-lisp.net/project/parenscript/release/parenscript-latest.tgzã«åæ ããã¦ããªãããã§ã
*3:æ¬é¡ã¨é¢ä¿ãªã調æ»ã¡ã¢ãHyperSpecã«ããã¨ã*compile-file-pathname*ã¯compile-fileé¢æ°ã®å®è¡ä¸ã®ã¿ãã¡ã¤ã«ãã¹ãè¨å®ããããã以å¤ã¯nilã«ã»ããããããã®ã®ããã§ããã¾ããmacroexpand-progress-funèªä½ã¯ã*macroexpand-hook*ç¨ã®hooké¢æ°ãè¿ãã¾ããåãåºããã³ã¼ãã®å°ãä¸ãè¦ãã¨ãdefpackageãã¯ãã®å±éæã§ãããã¨ãå é¨é¢æ°show-packageãå¼ã³åºãæ¡ä»¶ã®ä¸ã¤ã«ãªã£ã¦ãã¾ãã以ä¸ãåããã¦ãã³ã³ãã¤ã«æã®ã¿ããã±ã¼ã¸åãï¼éè¤ãªãï¼åºåããåä½ãå®ç¾ãã¦ããããã§ãã
*4:HyperSpecã«ããexpansion functionã®èª¬æã§ã¯"The value of the last form executed is returned as the expansion of the macro"ã¨è¨è¿°ããã¦ãã¾ãã
*5:ä¸ã®ä¾ã§ã¯ãããã§ã³ã³ãã¤ã«ãããããã«test-ps-eval-orderã©ã¤ãã©ãªå´ã«ããã¨ãããå¤æ´ãå ãã¦ãã¾ã :)
*6:åèè¨äºï¼Parenscriptで遊んで見る (1) defun編 - eshamster’s diary