)の品格

906 views
856 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
906
On SlideShare
0
From Embeds
0
Number of Embeds
313
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

)の品格

  1. 1. ) の品格 @emasaka
  2. 2. どう見ても 出オチです 本当にありがとうございました
  3. 3. 自己紹介 ● @emasaka ● 本名:高橋正和 ● 駄洒落を検索結果にしてTwitterに流すメソッドの(たぶん)元祖 ● ja.wikipedia.orgで「Locator/Identifier Separation Protocol」の ページを立てた人 ● 代表作:Bash on Rails ● 40代 フリーター ● ブログ 「本を読む」http://emasaka.blog65.fc2.com/
  4. 4. 本題
  5. 5. 「Lispはカッコが多い」 などと申しまして
  6. 6. (defun fact (n)   (if (zerop n)       1     (* n (fact (­ n 1))) )) 階乗(factorial)をこんなふうに 書いたりします
  7. 7. これを より厳密に書くと
  8. 8. (defun . (fact . ((n .  nil) . ((if . ((zerop . (n  . nil)) . (1 . ((* . (n .  ((fact . ((­ . (n . (1 .  nil))) . nil)) . nil))) .  nil)))) . nil)))) 点対表記(Dotted pair notation)
  9. 9. たしかにカッコが多い! (拍手!)
  10. 10. 命令型プログラマーならfor文か 類似のループで問題を解く
  11. 11. (defun fact (n)   (let ((i 1) (r 1))     (while (<= i n)       (setq r (* r i)             i (+ i 1)) )     r )) ループで書くと
  12. 12. (defun . (fact . ((n . nil) .  ((let . (((i . (1 . nil)) .  ((r . (1 . nil)) . nil)) .  ((while . ((<= . (i . (n .  nil))) . ((setq . (r . ((* .  (r . (i . nil))) . (i . ((+ . (i  . (1 . nil))) . nil))))) .  nil))) . (r . nil)))) . nil)))) これを点対表記に
  13. 13. これではLispに 拒絶反応を示す人が いてもおかしくない
  14. 14. “Lisp? No!” の恐怖
  15. 15. でも、 Lisperなら
  16. 16. (3 (5 (7) 11)) このS式を見たとき
  17. 17. (3 . ((5 . ((7 .  nil) . (11 .  nil))) . nil)) これを飛ばして
  18. 18. こうイメージする nil nil nil 3 5 7 11
  19. 19. 木構造 (ツリー)
  20. 20. ツリーを巡回する ● 全要素を出力する ● 全要素を合計する ● 特定の要素を探す ● … ※ブログねたの焼き直しです
  21. 21. 方法1 ● car方向とcdr方向をそれぞれ再帰的に辿る ● いちばんシンプルな方法
  22. 22. (defun traverse­tree (tree func)   (if (atom tree)       (or (null tree) (funcall func tree))     (traverse­tree (car tree) func)     (traverse­tree (cdr tree) func) )) Emacs Lispで書くと
  23. 23. (defun traverse­tree (tree func)   (mapc #'(lambda (x)             (if (atom x)                 (or (null x) (funcall func x))               (traverse­tree x func) ))         tree )) cdr方向をmapやループにしても car方向は再帰が必要
  24. 24. 方法2 ● ループで辿る ● 戻る場所を外部のデータ構造に覚えておく ● 深さ優先ならスタック、幅優先ならキュー
  25. 25. 実装は割愛
  26. 26. 方法3 ● 再帰も外部データも使わない方法 ● 通ったコンスセルを破壊的に「120度回転」さ せながら進む ● 3方向(car方向、cdr方向、戻り) = 3回120度回転 = 360度回転 = 元に戻る
  27. 27. 図解
  28. 28. car cdr こっちに進む
  29. 29. car cdr こっち(元のcar) に進みながら 120度回転 戻ったら次 (新しいcar)
  30. 30. car cdr 戻ったら次 (新しいcar) こっち(元のcar) に進みながら 120度回転
  31. 31. car cdr こっち(元のcar) に進みながら 120度回転
  32. 32. carを辿っていくだけで ツリーを一巡する
  33. 33.          ,. -‐'''''""¨¨¨ヽ          (.___,,,... -ァァフ|          あ…ありのまま 今 起こった事を話すぜ!           |i i|    }! }} //|          |l、{   j} /,,ィ//|       『おれはcarを辿っていたと         i|:!ヾ、_ノ/ u {:}//ヘ        思ったらいつのまにかツリーを一周していた』         |リ u' }  ,ノ _,!V,ハ |        /´fト、_{ル{,ィ'eラ , タ人        な… 何を言ってるのか わからねーと思うが      /'   ヾ|宀| {´,)⌒`/ |<ヽトiゝ        おれも何をされたのかわからなかった…     ,゙  / )ヽ iLレ  u' | | ヾlトハ〉      |/_/  ハ !ニ⊇ '/:}  V:::::ヽ        頭がどうにかなりそうだった…     // 二二二7'T'' /u' __ /:::::::/`ヽ    /'´r -—一ァ‐゙T´ '"´ /::::/-‐  \    再帰だとかスタックだとか    / //   广¨´  /'   /:::::/´ ̄`ヽ ⌒ヽ    そんなチャチなもんじゃあ 断じてねえ   ノ ' /  ノ:::::`ー-、___/::::://       ヽ  } _/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::...       イ  もっと恐ろしいものの片鱗を味わったぜ…
  34. 34. (defun traverse­tree:spin (cns prev)   (let ((next (car cns)))     (rplaca cns (cdr cns))     (rplacd cns prev)     next )) (defun traverse­tree (tree func)   (let* ((marker "dummy")               ; unique object          (cns tree) (prev marker) next )     (while (not (eq (setq next                           (traverse­tree:spin cns prev) )                     marker ))       (if (consp next)           (setq prev cns cns next)         (or (null next) (funcall func next))         (setq prev next) )))) Emacs Lispで書くと
  35. 35. ● 元ネタは、20年ぐらい前に雑誌(bit?)の エッセイかなにかでアイデアを見た記憶 ● 詳細はぜんぜん覚えてない ● ご存知の方、教えてください
  36. 36. ● 実践的ではない ● いくら関数型じゃなくても、無駄な破壊的操作はい まどき流行らない?
  37. 37. DEMO
  38. 38. まとめ ● カッコは単なる格好 ● ツリーですた ● 【緩募】元ネタの情報

×