
Lispã¯å€ãã®å Žåãä»ã®èšèªãããæå©ãªèšèªãšããŠå®£äŒãããŠããŸããããã¯ãç¬èªã®ãçµ±åãããã䟿å©ãªæ©èœãåããŠããããã§ãã
以äžã¯ãæšæºCommon Lispã®äžé£ã®æ©èœãç°¡åã«ããããŠäŸãæããŠåŒ·èª¿ãã詊ã¿ã§ãã
ãã®èšäºã¯ãããã°ã©ãã³ã°ã®çµéšããããLispã«èå³ããããLispãé
åçã§ããçç±ãããããçè§£ãããäººã«æã圹ç«ã€ãšæãããŸãã
ããã¹ãã¯ãCLæ©èœãªã¹ããšRobert Strandhã®CLã¬ãã¥ãŒã«åºã¥ããŠããŸãã
è±å¯ã§æ£ç¢ºãªæŒç®
Lispã¯ãä»ã®èšèªãšããŸãçµ±åãããè±å¯ãªæ°å€åã®éå±€ãæäŸããŸãã
é·ãæ°å€ ïŒbignumïŒã¯å¿
èŠã«å¿ããŠèªåçã«äœæãããããããªãŒããŒãããŒã®ãªã¹ã¯ã軜æžããã粟床ã確ä¿ãããŸãã ããšãã°ãå€10ââ4ããã°ããèšç®ã§ããŸãã
> (expt (expt (expt (expt 10 10) 10) 10) 10) 100000000000000000000000000000000000[...]
æçæ°ã¯åæ°ãšããŠè¡šããããããäœ¿çšæã«äžžã誀差ã¯çºçããŸããã æ£ç¢ºãªåççãªç®è¡ãèšèªã«çµ±åãããŠããŸãïŒ
> (+ 5/9 3/4) 47/36
è€çŽ æ°ã¯ãLispã®çµã¿èŸŒã¿ããŒã¿åã§ããããŸãã ãããã¯çãæ§æãšããŠè¡šãããšãã§ããŸãïŒ#cïŒ10 5ïŒã¯10 + 5iãæå³ããŸãã ç®è¡æŒç®ã¯ãè€éãªå€ã§ãæ©èœããŸãã
> (* 2 (+ #c(10 5) 4)) #C(28 10)
äžè¬åããããªã³ã¯
圢ç¶ãŸãã¯å Žæã¯ãåå¥ã®å¯å€å€æ°ã§ãããã®ããã«äœ¿çšã§ããŸãã SETFããã³ä»ã®åæ§ã®æ§é ã䜿çšããŠãç¹å®ã®äœçœ®ã«æŠå¿µçã«é¢é£ä»ããããŠããå€ã倿Žã§ããŸãã
ããšãã°ã次ã®ããã«SETFã䜿çšã§ããŸãã
> (defvar *colours* (list 'red 'green 'blue)) *COLOURS* > (setf (first *colours*) 'yellow) YELLOW > *colours* (YELLOW BLUE GREEN)
PUSHã¯æ¬¡ã®ããã«ãªããŸãã
> (push 'red (rest *colours*)) (RED BLUE GREEN) > *colours* (YELLOW RED BLUE GREEN)
æ±çšãªã³ã¯ã¯ããªã¹ãã«é©çšããããšãã ãã§ãªããä»ã®å€ãã®çš®é¡ã®æ§é ããªããžã§ã¯ãã«ãé©çšãããŸãã ããšãã°ããªããžã§ã¯ãæåããã°ã©ã ã§ã¯ããªããžã§ã¯ãã®äžéšã®ãã£ãŒã«ãã倿Žããæ¹æ³ã®1ã€ã¯SETFã䜿çšããããšã§ãã
è€æ°ã®å€
ãªã¹ããªã©ã®æ§é ãæç€ºçã«äœæããªããŠããå€ãçµã¿åãããããšãã§ããŸãã ããšãã°ãïŒvalues 'foo' barïŒã¯ã2ã€ã®å€-'foo and' barãè¿ããŸãã ãã®ã¡ã«ããºã ã䜿çšãããšã颿°ã¯äžåºŠã«è€æ°ã®å€ãè¿ãããšãã§ããããã°ã©ã ãç°¡çŽ åã§ããŸãã
ããšãã°ãFLOORã¯2ã€ã®å€ãè¿ãæšæºé¢æ°ã§ãã
> (floor pi) 3 0.14159265358979312d0
æ
£äŸã«ãããè€æ°ã®å€ãè¿ã颿°ã¯ãããã©ã«ãã§ã¯1ã€ã®å€ã®ã¿ãè¿ããããã®ããã«äœ¿çšãããŸã-æåã®å€ã
> (+ (floor pi) 2) 5
ãã®å Žåãæ®ãã®å€ãæç€ºçã«ååŸããã³äœ¿çšã§ããŸãã æ¬¡ã®äŸã§ã¯ãäžžãæã«PIã®æŽæ°éšåãšå°æ°éšåãåé¢ããŸãã
> (multiple-value-bind (integral fractional) (floor pi) (+ integral fractional)) 3.141592653589793d0
ãã¯ã
Lispã®ãã¯ãã¯ãLispãã©ãŒã ãŸãã¯ãªããžã§ã¯ããåŒæ°ãšããŠåããååãšããŠã³ãŒããçæããã³ã³ãã€ã«ããŠå®è¡ããäžçš®ã®é¢æ°ã§ãã ããã¯ããã¯ãå±éãšåŒã°ããæ®µéã§ãããã°ã©ã ãå®è¡ãããåã«çºçããŸãã ãã¯ãã¯ãéçºäžã«èšèªã®ãã¹ãŠã®æ©èœã䜿çšããŠãããçš®ã®èšç®ãå®è¡ã§ããŸãã
ãã¯ãã®äœ¿çšæ³ã®1ã€ã¯ãäžéšã®ãœãŒã¹ã³ãŒãããæ¢åã®å®çŸ©ã«é¢ããŠæ£ãããã¥ãŒã«å€æããããšã§ãã ã€ãŸãããã¯ãã䜿çšãããšãèšèªã«æ°ããæ§æã远å ã§ããŸãïŒãã®ã¢ãããŒãã¯
æ§ææœè±¡åãšåŒã°ããŸãïŒã
ããã«ãããããã°ã©ã ãå®è¡ããåã«ç¹å¥ãªæ§æãèšèªã«è¿œå ã§ãããããLispã«ãã¡ã€ã³åºæèšèªïŒDSLïŒãç°¡åã«åã蟌ãããšãã§ããŸãã
ãã¯ãã䜿çšããäž»ãªå©ç¹ã¯ããã¯ããèšèªã®æ©èœãæ¡åŒµããããã°ã©ããŒãããç°¡åã«ãããå°ãªãã³ãŒãã§ã¢ã€ãã¢ã衚çŸã§ããããšã§ãã æ°ããããŒã«ãçµã¿èŸŒã¿ã®ããã«èšèªã«è¿œå ã§ããŸãã ããã«ããã¯ãã䜿çšããŠããŒã¿ã®äºåèšç®ãŸãã¯åæåãè¡ããšãããã©ãŒãã³ã¹ã®æé©åã«åœ¹ç«ã¡ãŸãã
ãã¯ãã«ãŒã
LOOPãã¯ãã¯ãã«ãŒãã衚ãããã®åŒ·åãªããŒã«ã§ãã å®éãããã¯å埩ããã»ã¹ãèšè¿°ããããã®ãŸã£ããå°ããªçµã¿èŸŒã¿èšèªã§ãã LOOPã¯ãåçŽãªç¹°ãè¿ãããå埩åãè€éãªç¶æ
ãã·ã³ãŸã§ãã«ãŒããèšè¿°ããããã«å¿
èŠãªãã¹ãŠã®ã¿ã€ãã®åŒãæäŸããŸãã
> (defvar *list* (loop :for x := (random 1000) :repeat 5 :collect x)) *LIST* > *list* (324 794 102 579 55)
> (loop :for elt :in *list* :when (oddp elt) :maximizing elt) 579
> (loop :for elt :in *list* :collect (log elt) :into logs :finally (return (loop :for l :in logs :if (> l 5.0) :collect l :into ms :else :collect l :into ns :finally (return (values ms ns))))) (5.7807436 6.6770835 6.3613024) (4.624973 4.0073333)
FORMAT颿°
FORMAT颿°ã¯ãããŒã¿ã®ãã©ãŒãããæ¹æ³ãèšè¿°ããåã蟌ã¿èšèªããµããŒãããŸãã åçŽãªããã¹ãã®çœ®æã«å ããŠãFORMATåœä»€ã¯ãæ¡ä»¶ãã«ãŒããå¢çã±ãŒã¹ã®åŠçãªã©ãããã¹ããçæããããã®ããŸããŸãªã«ãŒã«ãã³ã³ãã¯ããªåœ¢åŒã§è¡šçŸã§ããŸãã
ãã®é¢æ°ã䜿çšããŠååã®ãªã¹ãããã©ãŒãããã§ããŸãã
(defun format-names (list) (format nil "~{~:(~a~)~#[.~; and ~:;, ~]~}" list))
> (format-names '(doc grumpy happy sleepy bashful sneezy dopey)) "Doc, Grumpy, Happy, Sleepy, Bashful, Sneezy and Dopey." > (format-names '(fry laurie)) "Fry and Laurie." > (format-names '(bluebeard)) "Bluebeard."
FORMATã¯ãç»é¢ãžã®æšæºåºåãæååããŸãã¯ãã®ä»ã®ã¹ããªãŒã ã«ããããããçµæãæå®ãããã¹ããªãŒã ã«è»¢éããŸãã
é«é颿°
Lispã®é¢æ°ã¯æ¬åœã®ãã¡ãŒã¹ãã¯ã©ã¹ã®ãšã³ãã£ãã£ã§ãã æ©èœãªããžã§ã¯ãã¯ãåçã«äœæãããããã©ã¡ãŒã¿ãŒãšããŠæž¡ãããçµæãšããŠè¿ãããšãã§ããŸãã ãããã£ãŠã
é«é颿°ãã€ãŸãåŒæ°ãšæ»ãå€èªäœã颿°ã«ãªãåŸã颿°ããµããŒããããŠããŸãã
ããã§ã¯ãåŒæ°ããªã¹ããšå¥ã®é¢æ°ïŒãã®å Žåã¯ïŒ '<ïŒã§ããSORT颿°ã®åŒã³åºãã確èªã§ããŸãã
> (sort (list 4 2 3 1) #'<) (1 2 3 4)
æž¡ããã颿°ã®ååã®ä»£ããã«ãã©ã ãåŒãšãåŒã°ãã
å¿å颿°ã䜿çšã§ããŸãã ãããã¯ãäžèŠãªååã§ããã°ã©ã ãè©°ãŸãããããšãªãã1åéãã®äœ¿çšã®ããã®é¢æ°ãäœæããå Žåã«ç¹ã«åœ¹ç«ã¡ãŸãã äžè¬ã«ããããã¯åå¥ã¯ããŒãžã£ãäœæããããã«äœ¿çšã§ããŸãã
ãã®äŸã§ã¯ãMAPCARã®æåã®åŒæ°ãšããŠäœ¿çšããå¿å颿°ãäœæããŸãã
> (mapcar (lambda (x) (+ x 10)) '(1 2 3 4 5)) (11 12 13 14 15)
颿°ãäœæãããšããã³ã³ããã¹ãããã£ããã£ãããããå®å
šãªèªåœçã¯ããŒãžã£ãŒã䜿çšã§ããŸãã
(let ((counter 10)) (defun add-counter (x) (prog1 (+ counter x) (incf counter))))
> (mapcar #'add-counter '(1 1 1 1)) (11 12 13 14) > (add-counter 50) 64
ãªã¹ãåŠç
ãªã¹ãã¯Lispã®åºæ¬çãªçµã¿èŸŒã¿ããŒã¿åã§ããããããªã¹ããæäœããããã®åºç¯ãªæ©èœã»ããããããŸãã ãã®ãããªé¢æ°ãšãã¯ãã®ãããã§ããªã¹ãã䜿çšããŠä»ã®ããŒã¿æ§é ã®ãããã¿ã€ãããã°ããäœæã§ããŸãã
ããšãã°ãéåžžã®ãªã¹ãã䜿çšããŠæ¬¡ã®ããã«äœæ¥ã§ããŸãã
> (defvar *nums* (list 0 1 2 3 4 5 6 7 8 9 10 11 12)) *NUMS* > (list (fourth *nums*) (nth 8 *nums*)) (3 8) > (list (last *nums*) (butlast *nums*)) ((12) (0 1 2 3 4 5 6 7 8 9 10 11)) > (remove-if-not #'evenp *nums*) (0 2 4 6 8 10 12)
ãããŠ-飿³ãªã¹ãã䜿çšããŠ
> (defvar *capital-cities* '((NZ . Wellington) (AU . Canberra) (CA . Ottawa))) *CAPITAL-CITIES* > (cdr (assoc 'CA *capital-cities*)) OTTAWA > (mapcar #'car *capital-cities*) (NZ AU CA)
ã©ã ããªã¹ã
ã©ã ããªã¹ãã¯ã颿°ããã¯ãããã€ã³ãã£ã³ã°ãã©ãŒã ãããã³ãã®ä»ã®æ§é ã®ãã©ã¡ãŒã¿ãŒãå®çŸ©ããŸãã Lambdaãªã¹ãã¯ãå¿
é ããªãã·ã§ã³ãååä»ããããŒã«ïŒæ®ãïŒããã³ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒãããã³ããã©ã«ãå€ãªã©ãå®çŸ©ããŸãã ããã«ãããéåžžã«æè»ã§è¡šçŸåè±ããªã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ã§ããŸãã
ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã§ã¯ãåŒã³åºãå
ãå€ãæå®ããå¿
èŠã¯ãããŸããã ãããã«å¯ŸããŠããã©ã«ãå€ãå®çŸ©ã§ããŸãããã以å€ã®å ŽåãåŒã³åºãããã³ãŒãã¯å€ãæäŸãããŠãããã©ããã確èªããç¶æ³ã«å¿ããŠåäœã§ããŸãã
次ã®é¢æ°ã¯ããªãã·ã§ã³ã®åºåãæåãã©ã¡ãŒã¿ãŒãåãå
¥ããŸããããã©ã«ãå€ã¯ç©ºçœæåã§ãã
(defun explode (string &optional (delimiter #\Space)) (let ((pos (position delimiter string))) (if (null pos) (list string) (cons (subseq string 0 pos) (explode (subseq string (1+ pos)) delimiter)))))
EXPLODE颿°ãåŒã³åºããšãããªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒãæå®ããããçç¥ããããšãã§ããŸãã
> (explode "foo, bar, baz" #\,) ("foo " " bar " " baz")
> (explode "foo, bar, baz") ("foo," "bar," "baz")
ååä»ããã©ã¡ãŒã¿ãŒã¯ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒã«äŒŒãŠã
ãŸãã ãååã§å®çŸ©ãããŠãããããä»»æã®é åºã§æž¡ãããšãã§ããŸãã ååã䜿çšãããšãã³ãŒãã®å¯èªæ§ãåäžããè€æ°ã®ãã©ã¡ãŒã¿ãŒã䜿çšããŠåŒã³åºããè¡ãéã®äžçš®ã®ããã¥ã¡ã³ããšããŠæ©èœããŸãã
ããšãã°ã次ã®2ã€ã®é¢æ°åŒã³åºããæ¯èŒããŸãã
// In C: xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1)
ãã¡ãŒã¹ãã¯ã©ã¹ã®ãšã³ãã£ãã£ãšããŠã®ã·ã³ãã«
ã·ã³ãã«ã¯ãååã§å®å
šã«å®çŸ©ãããäžæã®ãªããžã§ã¯ãã§ãã ããšãã°ããfooã¯ååããFOOãã®ãã£ã©ã¯ã¿ãŒã§ãã ã·ã³ãã«ã¯ãèå¥åãŸãã¯ããã€ãã®æœè±¡çãªååãšããŠäœ¿çšã§ããŸãã æåã®æ¯èŒã¯ãäžå®æéã«ããã£ãŠè¡ãããŸãã
ã·ã³ãã«ã¯ã颿°ãšåæ§ã«ãäžæµã®ãšã³ãã£ãã£ã§ãã ãããã¯ãåçã«äœæãåŒçšïŒåŒçšãæªè©äŸ¡ïŒãä¿åãåŒæ°ãšããŠæž¡ãããæ¯èŒãæååã«å€æããšã¯ã¹ããŒãããã³ã€ã³ããŒãã§ããåç
§ã§ããŸãã
ããã§ãã* foo *ãã¯å€æ°ã®èå¥åã§ãã
> (defvar *foo* 5) *FOO* > (symbol-value '*foo*) 5
ãã¡ãŒã¹ãã¯ã©ã¹ãšã³ãã£ãã£ãšããŠã®ããã±ãŒãž
åå空éã®åœ¹å²ãæããããã±ãŒãžããã¡ãŒã¹ãã¯ã©ã¹ã®ãªããžã§ã¯ãã§ãã ããã°ã©ã ã®å®è¡äžã«äœæãä¿åãçµæãšããŠè¿ããããããã³ã³ããã¹ããåçã«åãæ¿ããããåå空éãåçã«å€æãããããããšãã§ããŸãã
次ã®äŸã§ã¯ãINTERNã䜿çšããŠããã±ãŒãžã«æåãå«ããŸãã
> (intern "ARBITRARY" (make-package :foo :use '(:cl))) FOO::ARBITRARY NIL
Lispã«ã¯ãçŸåšã®ããã±ãŒãžãæãç¹å¥ãªå€æ°* package *ããããŸãã çŸåšã®ããã±ãŒãžãFOOã§ããå Žåãæ¬¡ãå®è¡ã§ããŸãã
> (in-package :foo) #<PACKAGE "FOO"> > (package-name *package*) "FOO"
ç¹å¥ãªå€æ°
Lispã¯ãåå¥ã³ã³ããã¹ãã«å ããŠå€æ°ã®åçã³ã³ããã¹ãããµããŒãããŸãã åç倿°ã¯ããã€ãã®å Žåã«åœ¹ç«ã€å¯èœæ§ãããããããã®ãµããŒãã«ããæå€§éã®æè»æ§ãåŸãããŸãã
ããšãã°ãäžéšã®ã³ãŒãã®åºåããã¡ã€ã«ãªã©ã®éæšæºã¹ããªãŒã ã«ãªãã€ã¬ã¯ãããç¹å¥ãªå€æ°* standard-output *ã®ãã€ãããã¯ãªã³ã¯ãäœæã§ããŸãã
(with-open-file (file-stream #p"somefile" :direction :output) (let ((*standard-output* file-stream)) (print "This prints to the file, not stdout.")) (print "And this prints to stdout, not the file."))
*æšæºåºå*ã«å ããŠãlispã«ã¯ã*æšæºå
¥å*ã*ããã±ãŒãž*ã*èªã¿åãå¯èœ*ã*å°å·å¯èœ*ã*å°å·åãªã©ããªãœãŒã¹ãšãã©ã¡ãŒã¿ãŒãå«ãããã°ã©ã ã®ç¶æ
ãæ ŒçŽããããã€ãã®ç¹æ®å€æ°ãå«ãŸããŸãããªã©
ã³ã³ãããŒã«è»¢é
Lispã«ã¯ãå¶åŸ¡ãåŒã³åºãéå±€ã®äžäœã«ãããã€ã³ãã«ç§»ã2ã€ã®æ¹æ³ããããŸãã ãã®å Žåãèªåœé åãŸãã¯åçé åã¯ãããããããŒã«ã«é·ç§»ããã³éããŒã«ã«é·ç§»ã«èæ
®ããããšãã§ããŸãã
ååä»ããããã¯ã«ããããã¹ãããããã©ãŒã ã¯ãBLOCKããã³RETURN-FROMã䜿çšããŠãååä»ãã®èŠªãã©ãŒã ããã³ã³ãããŒã«ãè¿ãããšãã§ããŸãã
ããšãã°ãããã§ãã¹ããããã«ãŒãã¯ãå€åŽã®ã«ãŒãããã€ãã¹ããŠãåæãããã¯ãããªã¹ããè¿ããŸãã
> (block early (loop :repeat 5 :do (loop :for x :from 1 :to 10 :collect x :into xs :finally (return-from early xs)))) (1 2 3 4 5 6 7 8 9 10)
ãã£ãã/ã¹ããŒã¯ãéããŒã«ã«gotoã®ãããªãã®ã§ãã THROWã¯ãæåŸã«æ€åºãããCATCHã«ãžã£ã³ããããã©ã¡ãŒã¿ãŒãšããŠæå®ãããå€ãæž¡ããŸãã
åã®äŸã«åºã¥ããTHROW-RANGE颿°ã§ã¯ãããã°ã©ã ã®åçç¶æ
ã䜿çšããŠãTHROWãšCATCHãé©çšã§ããŸãã
(defun throw-range (ab) (loop :for x :from a :to b :collect x :into xs :finally (throw :early xs)))
> (catch :early (loop :repeat 5 :do (throw-range 1 10))) (1 2 3 4 5 6 7 8 9 10)
åçãªç¶æ
ãèæ
®ããå¿
èŠãããå Žåã«ãã¬ãã·ã«ã«ã¹ã³ãŒãã䜿çšããŠãã£ãã/ã¹ããŒããã ãã§ååãªå Žåã
æ¡ä»¶ã®åèµ·å
Lispã®æ¡ä»¶ã·ã¹ãã ã¯ãããã°ã©ã ã®éšåéã§ä¿¡å·ãéä¿¡ããããã®ã¡ã«ããºã ã§ãã
èããããäœ¿çšæ³ã®1ã€ã¯ãJavaãŸãã¯Pythonã§è¡ãã®ãšã»ãŒåãæ¹æ³ã§ãäŸå€ãã¹ããŒããŠåŠçããããšã§ãã ããããä»ã®èšèªãšã¯ç°ãªããLispã§ã®ã·ã°ãã«éä¿¡äžã«ã¹ã¿ãã¯
ã¯æ¡åŒµããªããã ããã¹ãŠã®ããŒã¿ãä¿åãããã·ã°ãã«ãã³ãã©ãŒã¯ã¹ã¿ãã¯äžã®ä»»æã®ãã€ã³ãããããã°ã©ã ãåèµ·åã§ããŸãã
äŸå€ãåŠçãããã®ã¢ãããŒãã«ãããã¿ã¹ã¯ã®åé¢ãæ¹åãããããæ§é åãããã³ãŒããå®çŸã§ããŸãã ãããããã®ãããªã¡ã«ããºã ã¯ãããã°ã©ã ã®åéšåéã§ïŒãšã©ãŒã ãã§ãªãïŒä»»æã®ã¡ãã»ãŒãžãéä¿¡ãããªã©ãããåºãç¯å²ãæã£ãŠããŸãã
æ¡ä»¶ã·ã¹ãã ã®äœ¿çšäŸã¯ãèšäº
Common LispïŒA Tutorial on Conditions and Restartsã§èŠãããšãã§ããŸãã
äžè¬åããã颿°
Common Lispãªããžã§ã¯ãã·ã¹ãã ïŒCommon Lisp Object SystemãCLOSïŒã¯ãã¡ãœãããã¯ã©ã¹ã«ãã€ã³ãããŸããããäžè¬åããã颿°ã®äœ¿çšãèš±å¯ããŸãã
æ±çšé¢æ°ã¯ãããã€ãã®ç°ãªãã¡ãœãããæºããããšãã§ãã眲åãå®çŸ©ããŸãã åŒã³åºããããšãåŒæ°ã«æãäžèŽããã¡ãœãããéžæãããŸãã
ããã§ãããŒããŒãããã®ã€ãã³ããåŠçããäžè¬åããã颿°ãå®çŸ©ããŸãã
(defgeneric key-input (key-name))
次ã«ãç°ãªãKEY-NAMEå€ãæºããããã€ãã®ã¡ãœãããå®çŸ©ããŸãã
(defmethod key-input (key-name)
ã¢ã¯ã·ã§ã³ã®ã¡ãœããåŒã³åºããèŠãŠã¿ãŸãããïŒ
> (key-input :space) "Space key pressed" > (key-input :return) "No keybinding for RETURN" > (defmethod key-input ((key-name (eql :return))) (format nil "Return key pressed")) > (key-input :return) "Return key pressed"
ç§ãã¡ã¯ãã³ã³ã¹ãã©ã¯ã·ã§ã³ãªãã§ãã¹ã€ãããšã¡ãœããã®ããŒãã«ã䜿çšããæç€ºçãªäœæ¥ãè¡ããŸããã ãããã£ãŠãæ°ããç¹å¥ãªã±ãŒã¹ã®åŠçããå¿
èŠã«å¿ããŠç¬ç«ããŠãåçã«ãéåžžã¯ããã°ã©ã ã®ã©ãã«ã§ã远å ã§ããŸãã ããã«ãããç¹ã«ããã ã¢ããã®Lispããã°ã©ã ã®éçºãä¿èšŒãããŸãã
äžè¬å颿°ã¯ãã¡ãœããã®ã°ã«ãŒãã®ããã€ãã®å
±éã®ç¹æ§ãå®çŸ©ããŸãã ããšãã°ãã¡ãœããã®çµã¿åããã®ã¡ãœãããç¹æ®åãªãã·ã§ã³ãããã³ãã®ä»ã®ããããã£ã¯ãæ±çšé¢æ°ã«ãã£ãŠæå®ã§ããŸãã
Lispã¯å€ãã®äŸ¿å©ãªæšæºæ±çšé¢æ°ãæäŸããŸãã ããšãã°ãPRINT-OBJECTã¯ãããã¹ã衚çŸãå®çŸ©ããããã«ä»»æã®ã¯ã©ã¹ã«ç¹åã§ããŸãã
ã¡ãœããã®çµã¿åãã
ã¡ãœããã®çµã¿åããã«ãã
ãã¡ãœãããåŒã³åºããšãã«ãããé åºã§ããŸãã¯äžéšã®é¢æ°ãä»ã®é¢æ°ã®çµæãåŠçããããã«ãã¡ãœããã®
ãã§ãŒã³å
šäœãå®è¡ã§ããŸãã
ç¹å®ã®é åºã§ã¡ãœãããé
眮ããã¡ãœãããçµåããããã®çµã¿èŸŒã¿ã¡ãœããããããŸãã ããŒã¯ãŒãbefore ã: afterããŸãã¯aroundã§æäŸãããã¡ãœããã¯ãåŒã³åºããã§ãŒã³ã®é©åãªå Žæã«é
眮ãããŸãã
ããšãã°ãåã®äŸã§ã¯ãåKEY-INPUTã¡ãœããã¯ããããŒãæŒãããŸããããšãããã¬ãŒãºã®åºåãç¹°ãè¿ããŸãã æ¬¡ã®ãããªçµã¿åããã§ã³ãŒããæ¹åã§ããŸãïŒaround
(defmethod key-input :around (key-name) (format nil "~:(~a~) key pressed" (call-next-method key-name)))
ãã®åŸãKEY-INPUTã¡ãœãããåå®çŸ©ããŠãããããã«1è¡ã®ã¿ãæå®ããŸãã
(defmethod key-input ((key-name (eql :escape))) "escape")
KEY-INPUTãåŒã³åºããšã次ã®ããšãèµ·ãããŸãã
- ã¡ãœããã¯ã©ãã«ã§åŒã³åºãããŸãïŒaround
- 次ã®ã¡ãœãããã€ãŸãKEY-INPUTã®ç¹æ®ããŒãžã§ã³ã®1ã€ãåŒã³åºããŸãã
- æååãè¿ããŸãããã®æååã¯ãaroundã§ã¡ãœããããã©ãŒãããããŸãã
ããã©ã«ãã®ãªãã·ã§ã³ã¯ç°ãªãæ¹æ³ã§åŠçã§ããããšã«æ³šæããŠãã ããã THROW / CATCHãã¢ã䜿çšããã ãã§ãïŒããé«åºŠãªå®è£
ã§ã¯æ¡ä»¶ã䜿çšã§ããŸãïŒã
(defmethod key-input (key-name) (throw :default (format nil "No keybinding for ~a" key-name))) (defmethod key-input :around (key-name) (catch :default (format nil "~:(~a~) key pressed" (call-next-method key-name))))
ãã®çµæãçµ±åãããã¡ãœããã®çµã¿åããã¡ãœããã«ãããããŒããŒãããã®ã€ãã³ãã®åŠçãã¢ãžã¥ãŒã«åãããæ¡åŒµå¯èœãªç°¡åã«å€æŽå¯èœãªã¡ã«ããºã ã«äžè¬åããããšãã§ããŸãã ãã®ææ³ã¯ããŠãŒã¶ãŒå®çŸ©ã®çµã¿åããæ¹æ³ã䜿çšããŠè£è¶³ã§ããŸãã ããšãã°ãã¡ãœããã®çµæãåèšãŸãã¯ãœãŒãããçµã¿åããã¡ãœããã远å ã§ããŸãã
å€éç¶æ¿
ã©ã®ã¯ã©ã¹ã«ãå€ãã®ç¥å
ãå«ããããšãã§ããŸããããã«ãããããè±å¯ãªã¢ãã«ãäœæããããå¹ççãªã³ãŒãã®åå©çšãå®çŸã§ããŸãã åã¯ã©ã¹ã®åäœã¯ãå
ç¥ã¯ã©ã¹ã®å®çŸ©ã«åŸã£ãŠæ§ç¯ãããã·ãŒã±ã³ã¹ã«åŸã£ãŠæ±ºå®ãããŸãã
ã¡ãœããã®çµã¿åãããã¡ã¿ãªããžã§ã¯ããããã³ã«ãããã³ãã®ä»ã®CLOSæ©èœã䜿çšãããšãåŸæ¥ã®å€éç¶æ¿ã®åé¡ïŒfork-joinãªã©ïŒãåé¿ã§ããŸãã
ã¡ã¿ãªããžã§ã¯ããããã³ã«
ã¡ã¿ãªããžã§ã¯ããããã³ã«ïŒMOPïŒã¯ãCLOSã䜿çšããŠå®è£
ãããCLOSããã°ã©ãã³ã°ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã MOPã䜿çšãããšãããã°ã©ãã¯CLOSèªäœã䜿çšããŠå
éšCLOSããã€ã¹ã調æ»ã䜿çšãããã³å€æŽã§ããŸãã
ãã¡ãŒã¹ãã¯ã©ã¹ã®ãšã³ãã£ãã£ãšããŠã®ã¯ã©ã¹
ã¯ã©ã¹èªäœããªããžã§ã¯ãã§ãã MOPã䜿çšãããšãã¯ã©ã¹ã®å®çŸ©ãšåäœã倿Žã§ããŸãã
FOOã¯ã©ã¹ãBARã¯ã©ã¹ã®åå«ãšããENSURE-CLASS颿°ã䜿çšããŠãããšãã°BAZã¯ã©ã¹ãFOOå
ç¥ã®ãªã¹ãã«è¿œå ã§ããŸãã
(defclass bar () ()) (defclass foo (bar) ()) (defclass baz () ())
> (class-direct-superclasses (find-class 'foo)) (#<STANDARD-CLASS BAR>) > (ensure-class 'foo :direct-superclasses '(bar baz)) #<STANDARD-CLASS FOO> > (class-direct-superclasses (find-class 'foo)) (#<STANDARD-CLASS BAR> #<STANDARD-CLASS BAZ>)
ã¯ã©ã¹ã®ç¥å
ã«é¢ããæ
å ±ãååŸããããã«ãCLASS-DIRECT-SUPERCLASSES颿°ã䜿çšããŸããã ãã®å ŽåãFIND-CLASSããåãåã£ããªããžã§ã¯ãã®åœ¢åŒã®ã¯ã©ã¹ãåŒæ°ãšããŠåãåããŸãã
äžèšã®äŸã¯ãããã°ã©ã ã®å®è¡äžã«ã¯ã©ã¹ã倿Žã§ããã¡ã«ããºã ã瀺ããŠããŸããããã«ããããšãããã¯ã©ã¹ã«ããã¯ã¹ã€ã³ãåçã«è¿œå ã§ããŸãã
åçãªãªãŒããŒã©ã€ã
Lispã¯éåžžã«ã€ã³ã¿ã©ã¯ãã£ãã§ãã€ãããã¯ãªç°å¢ã§ãã 颿°ããã¯ããã¯ã©ã¹ãããã±ãŒãžããã©ã¡ãŒã¿ãŒããªããžã§ã¯ãã¯ã»ãŒãã€ã§ãåå®çŸ©ã§ããçµæã¯é©åã§äºæž¬å¯èœã§ãã
ãããã£ãŠãããã°ã©ã ã®å®è¡äžã«ã¯ã©ã¹ãåå®çŸ©ãããšã倿Žã¯ãã®ã¯ã©ã¹ã®ãã¹ãŠã®ãªããžã§ã¯ããšãµãã¯ã©ã¹ã«ããã«é©çšãããŸãã
radiusããããã£ãšãã®ãµãã¯ã©ã¹TENNIS-BALLã§BALLã¯ã©ã¹ãå®çŸ©ã§ããŸãã > (defclass ball () ((%radius :initform 10 :accessor radius))) #<STANDARD-CLASS BALL> > (defclass tennis-ball (ball) ()) #<STANDARD-CLASS TENNIS-BALL>
TENNIS-BALLã¯ã©ã¹ã®ãªããžã§ã¯ãã¯æ¬¡ã®ãšããã§ããradiusããããã£çšã®ã¹ãããããããŸãã > (defvar *my-ball* (make-instance 'tennis-ball)) *MY-BALL* > (radius *my-ball*) 10
ãããŠãå¥ã®ããªã¥ãŒã ã¹ãããã远å ããããšã§ãBALLã¯ã©ã¹ããªãŒããŒã©ã€ãã§ããŸãã > (defclass ball () ((%radius :initform 10 :accessor radius) (%volume :initform (* 4/3 pi 1e3) :accessor volume))) #<STANDARD-CLASS BALL>
ãããŠ* MY-BALL *ã¯èªåçã«æŽæ°ãããå
ç¥ã¯ã©ã¹ã§å®çŸ©ãããæ°ããã¹ããããååŸããŸãã > (volume *my-ball*) 4188.790204786391d0
å®è¡æã®ã³ã³ãã€ã©ãŒãžã®ã¢ã¯ã»ã¹
COMPILEããã³COMPILE-FILE颿°ã®ãããã§ãLispã³ã³ãã€ã©ã¯å®è¡å¯èœããã°ã©ã ããçŽæ¥äœ¿çšã§ããŸãããããã£ãŠãããã°ã©ã ã®å®è¡äžã«äœæãŸãã¯å€æŽããã颿°ãã³ã³ãã€ã«ã§ããŸããããã°ã©ã ã¯æ®µéçã«ã³ã³ãã€ã«ã§ãããããéçºãã€ã³ã¿ã©ã¯ãã£ãã§åçãã€é«éã«ãªããŸããèµ·åããããã°ã©ã ã¯ãåŸã
ã«å€æŽããããã°ãããã³æé·ã§ããŸããã³ã³ãã€ã«ãã¯ã
ã³ã³ãã€ã«ãã¯ãã¯ã颿°ãŸãã¯ãã¯ããã³ã³ãã€ã«ããããã®ä»£æ¿æŠç¥ãå®çŸ©ããŸããéåžžã®ãã¯ããšã¯ç°ãªããã³ã³ãã€ã«ãã¯ãã¯èšèªã®æ§æãæ¡åŒµãããã³ã³ãã€ã«æã«ã®ã¿é©çšã§ããŸãããããã£ãŠããããã¯äž»ã«ã³ãŒãèªäœãšã¯å¥ã«ã³ãŒããæé©åããæ¹æ³ã決å®ããããã«äœ¿çšãããŸããåå®çŸ©
Lispã¯åçã«åä»ããããèšèªã§ãããã©ããããããã¿ã€ãã³ã°ã«ã¯éåžžã«äŸ¿å©ã§ãããããã°ã©ãã¯å€æ°ã®åãæç€ºçã«æå®ã§ããŸããããã¯ãä»ã®ãã£ã¬ã¯ãã£ããšåæ§ã«ãã³ã³ãã€ã©ãŒãèšèªãéçã«åæå®ãããŠãããã®ããã«ã³ãŒããæé©åã§ããããã«ããŸããããšãã°ã次ã®ããã«EXPLODE颿°ã§ãã©ã¡ãŒã¿ã¿ã€ããå®çŸ©ã§ããŸãã (defun explode (string &optional (delimiter #\Space)) (declare (type character delimiter) (type string string)) ...)
ããã°ã©ããã«ããŒãµãŒ
LispããŒãµãŒã䜿çšãããšãå
¥åããŒã¿ãç°¡åã«è§£æã§ããŸããå
¥åã¹ããªãŒã ããããã¹ããååŸããéåžžã¯SåŒãšåŒã°ããLispãªããžã§ã¯ããäœæããŸããããã«ãããå
¥åããŒã¿ã®åæã倧å¹
ã«ç°¡çŽ åãããŸããããŒãµãŒã¯ãREADãREAD-CHARãREAD-LINEãREAD-FROM-STRINGãªã©ã®ããã€ãã®é¢æ°ãéããŠäœ¿çšã§ããŸããå
¥åã¹ããªãŒã ã«ã¯ããã¡ã€ã«ãããŒããŒãå
¥åãªã©ã䜿çšã§ããŸãããããã«ãé©åãªé¢æ°ã䜿çšããŠæååãŸãã¯æåã·ãŒã±ã³ã¹ããããŒã¿ãèªã¿åãããšãã§ããŸããREAD-FROM-STRINGã䜿çšããèªã¿åãã®æãç°¡åãªäŸã¯ãæååãïŒ400 500 600ïŒããããªããžã§ã¯ãïŒ400 500 600ïŒãã€ãŸããªã¹ããäœæããŸãã > (read-from-string "(400 500 600)") (400 500 600) 13 > (type-of (read-from-string "t")) BOOLEAN
ãªãŒããŒãã¯ãã䜿çšãããšãç¹å®ã®æ§æã«ç¹å¥ãªã»ãã³ãã£ã¯ã¹ãå®çŸ©ã§ããŸããããã¯ãLispããŒãµãŒãããã°ã©ã å¯èœãªããå¯èœã§ãããã¯ãã®èªã¿åãã¯ãèšèªã®æ§æãæ¡åŒµããå¥ã®æ¹æ³ã§ãïŒãã¯ãã¯äžè¬çã«æ§æç³ã远å ããããã«äœ¿çšãããŸãïŒãããã€ãã®æšæºçãªèªã¿åããã¯ãïŒ- ïŒ 'foo-颿°ã
- ïŒ\\-æåïŒæåïŒã
- #cïŒ4 3ïŒ-è€çŽ æ°ã
- #p "/ path /"-ãã¡ã€ã«ãã¹ã
ããŒãµãŒã¯ãèªã¿åãã«ãŒã«ãå®çŸ©ãããŠãããªããžã§ã¯ããçæã§ããŸããç¹ã«ããããã®ã«ãŒã«ã¯èªã¿åããã¯ãã䜿çšããŠèšå®ã§ããŸããå®éãåé¡ã®ããŒãµãŒã¯å¯Ÿè©±åã€ã³ã¿ãŒããªã¿ãŒïŒèªã¿åã-è©äŸ¡-å°å·ã«ãŒããREPLïŒã«ã䜿çšãããŸããããã¯ãæšæºã®èªã¿åããã¯ãã䜿çšããŠ16é²è¡šèšã§æ°å€ãèªã¿åãæ¹æ³ã§ãã > (read-from-string "#xBB") 187
ããã°ã©ã å¯èœãªå°å·
Lispã®ããã¹ãåºåã·ã¹ãã ã¯ãæ§é ããªããžã§ã¯ãããŸãã¯ä»ã®ããŒã¿ãç°ãªã圢åŒã§å°å·ããæ©èœãæäŸããŸããPRINT-OBJECTã¯ãåŒæ°ãšããŠãªããžã§ã¯ããšã¹ããªãŒã ãåãåãçµã¿èŸŒã¿ã®äžè¬åããã颿°ã§ãã察å¿ããã¡ãœããã¯ãæå®ããããªããžã§ã¯ãã®ããã¹ã衚çŸãã¹ããªãŒã ã«åºåããŸãããããã«ããããªããžã§ã¯ãã®ããã¹ã衚çŸãå¿
èŠãªå Žåã¯ãFORMATãPRINTãREPLãªã©ã®ãã®é¢æ°ã䜿çšãããŸããJOURNEYã¯ã©ã¹ãæ€èšããŠãã ããã (defclass journey () ((%from :initarg :from :accessor from) (%to :initarg :to :accessor to) (%period :initarg :period :accessor period) (%mode :initarg :mode :accessor mode)))
ã¯ã©ã¹JOURNEYã®ãªããžã§ã¯ããå°å·ããããšãããšã次ã®ãããªãã®ã衚瀺ãããŸãã > (defvar *journey* (make-instance 'journey :from "Christchurch" :to "Dunedin" :period 20 :mode "bicycle")) *JOURNEY* > (format nil "~a" *journey*) "#<JOURNEY {10044DCCA1}>"
JOURNEYã¯ã©ã¹ã®PRINT-OBJECTã¡ãœãããå®çŸ©ããããã䜿çšããŠãªããžã§ã¯ãã®äœããã®ããã¹ã衚çŸãèšå®ã§ããŸãã (defmethod print-object ((j journey) (s stream)) (format s "~A to ~A (~A hours) by ~A." (from j) (to j) (period j) (mode j)))
ãªããžã§ã¯ãã¯æ°ããããã¹ããã¥ãŒã䜿çšããŸãã > (format nil "~a" *journey*) "Christchurch to Dunedin (20 hours) by bicycle."