2010/10/30

第5回ありえるえりあ勉強会 〜「Lisp脳」勉強会 〜

第5回ありえるえりあ勉強会 〜「Lisp脳」勉強会 〜 に行ってきた。

受付でおやつもらった。ありがとうございました。

いや、いろいろ面白かった。うん、本当に面白かったよ。

例のかけてたすやつ。普通 Common Lisp なら loop で書く。個人的には series でも書きたい。関数にするとあれなのでべたにする。

;; loop
(loop for x in '(10 20 30 40 50) for i from 0 sum (* x i))
;; => 400

;; series
(require :series)
(series::install)
(collect-sum (#M* (scan '(10 20 30 40 50)) (scan-range)))
;; => 400

これは Lisp 脳? 関数的? 手続的?

マクロ展開してみると正体が分かる。

;; (loop for x in '(10 20 30 40 50) for i from 0 sum (* x i))
(BLOCK NIL
(COMMON-LISP:LET ((X NIL) (#:LOOP-LIST-981 '(10 20 30 40 50)))
(DECLARE (TYPE LIST #:LOOP-LIST-981))
(COMMON-LISP:LET ((I 0))
(DECLARE (TYPE NUMBER I))
(COMMON-LISP:LET ((#:LOOP-SUM-982 0))
(DECLARE (TYPE NUMBER #:LOOP-SUM-982))
(TAGBODY
(SETQ X (CAR #:LOOP-LIST-981))
(SETQ #:LOOP-LIST-981 (CDR #:LOOP-LIST-981))
SB-LOOP::NEXT-LOOP
(SETQ #:LOOP-SUM-982 (+ #:LOOP-SUM-982 (* X I)))
(IF (ENDP #:LOOP-LIST-981)
(PROGN (GO SB-LOOP::END-LOOP))
NIL)
(SETQ X (CAR #:LOOP-LIST-981))
(SETQ #:LOOP-LIST-981 (CDR #:LOOP-LIST-981))
(SETQ I (1+ I))
(GO SB-LOOP::NEXT-LOOP)
SB-LOOP::END-LOOP
(RETURN-FROM NIL #:LOOP-SUM-982))))))

;; (collect-sum (#M* (scan '(10 20 30 40 50)) (scan-range)))
(COMMON-LISP:LET* (#:ELEMENTS-991
(#:LISTPTR-992 '(10 20 30 40 50))
(#:NUMBERS-997 (COERCE (- 0 1) 'NUMBER))
#:ITEMS-989
(#:SUM-984 0))
(DECLARE (TYPE LIST #:LISTPTR-992)
(TYPE NUMBER #:NUMBERS-997)
(TYPE NUMBER #:SUM-984))
(TAGBODY
#:LL-1000
(IF (ENDP #:LISTPTR-992)
(GO SERIES::END))
(SETQ #:ELEMENTS-991 (CAR #:LISTPTR-992))
(SETQ #:LISTPTR-992 (CDR #:LISTPTR-992))
(SETQ #:NUMBERS-997 (+ #:NUMBERS-997 (COERCE 1 'NUMBER)))
(SETQ #:ITEMS-989
((LAMBDA (#:V-986 #:V-985) (* #:V-986 #:V-985)) #:ELEMENTS-991
#:NUMBERS-997))
(SETQ #:SUM-984 (+ #:SUM-984 #:ITEMS-989))
(GO #:LL-1000)
SERIES::END)
#:SUM-984)

字面こそ GO だけど、構造化以前の GOTO 文。そして SETQ は代入。あと IF もあるね。

分岐、代入、ジャンプ。。。アセンブラ?

まさに http://www.geekpage.jp/blog/?id=2006/12/13 ということだね。

0 件のコメント: