38
) の品格 @emasaka

)の品格

  • Upload
    emasaka

  • View
    838

  • Download
    1

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: )の品格

) の品格@emasaka

Page 2: )の品格

どう見ても出オチです

本当にありがとうございました

Page 3: )の品格

自己紹介● @emasaka● 本名:高橋正和● 駄洒落を検索結果にしてTwitterに流すメソッドの(たぶん)元祖● ja.wikipedia.orgで「Locator/Identifier Separation Protocol」の

ページを立てた人● 代表作:Bash on Rails● 40代 フリーター● ブログ

「本を読む」http://emasaka.blog65.fc2.com/

Page 4: )の品格

本題

Page 5: )の品格

「Lispはカッコが多い」などと申しまして

Page 6: )の品格

(defun fact (n)  (if (zerop n)      1    (* n (fact (­ n 1))) ))

階乗(factorial)をこんなふうに書いたりします

Page 7: )の品格

これをより厳密に書くと

Page 8: )の品格

(defun . (fact . ((n . nil) . ((if . ((zerop . (n . nil)) . (1 . ((* . (n . ((fact . ((­ . (n . (1 . nil))) . nil)) . nil))) . nil)))) . nil))))

点対表記(Dotted pair notation)

Page 9: )の品格

たしかにカッコが多い!

(拍手!)

Page 10: )の品格

命令型プログラマーならfor文か類似のループで問題を解く

Page 11: )の品格

(defun fact (n)  (let ((i 1) (r 1))    (while (<= i n)      (setq r (* r i)            i (+ i 1)) )    r ))

ループで書くと

Page 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))))

これを点対表記に

Page 13: )の品格

これではLispに拒絶反応を示す人がいてもおかしくない

Page 14: )の品格

“Lisp? No!”

の恐怖

Page 15: )の品格

でも、Lisperなら

Page 16: )の品格

(3 (5 (7) 11))

このS式を見たとき

Page 17: )の品格

(3 . ((5 . ((7 . nil) . (11 . nil))) . nil))

これを飛ばして

Page 18: )の品格

こうイメージする

nil

nil

nil

3

5

7 11

Page 19: )の品格

木構造(ツリー)

Page 20: )の品格

ツリーを巡回する● 全要素を出力する● 全要素を合計する● 特定の要素を探す● …

※ブログねたの焼き直しです

Page 21: )の品格

方法1● car方向とcdr方向をそれぞれ再帰的に辿る● いちばんシンプルな方法

Page 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で書くと

Page 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方向は再帰が必要

Page 24: )の品格

方法2● ループで辿る● 戻る場所を外部のデータ構造に覚えておく● 深さ優先ならスタック、幅優先ならキュー

Page 25: )の品格

実装は割愛

Page 26: )の品格

方法3● 再帰も外部データも使わない方法● 通ったコンスセルを破壊的に「120度回転」さ

せながら進む● 3方向(car方向、cdr方向、戻り)

= 3回120度回転 = 360度回転 = 元に戻る

Page 27: )の品格

図解

Page 28: )の品格

car cdr

こっちに進む

Page 29: )の品格

car

cdr

こっち(元のcar)に進みながら120度回転

戻ったら次(新しいcar)

Page 30: )の品格

car

cdr

戻ったら次(新しいcar)

こっち(元のcar)に進みながら120度回転

Page 31: )の品格

car cdr

こっち(元のcar)に進みながら120度回転

Page 32: )の品格

carを辿っていくだけでツリーを一巡する

Page 33: )の品格

         ,. -‐'''''""¨¨¨ヽ         (.___,,,... -ァァフ|          あ…ありのまま 今 起こった事を話すぜ!          |i i|    }! }} //|         |l、{   j} /,,ィ//|       『おれはcarを辿っていたと        i|:!ヾ、_ノ/ u {:}//ヘ        思ったらいつのまにかツリーを一周していた』        |リ u' }  ,ノ _,!V,ハ |       /´fト、_{ル{,ィ'eラ , タ人        な… 何を言ってるのか わからねーと思うが     /'   ヾ|宀| {´,)⌒`/ |<ヽトiゝ        おれも何をされたのかわからなかった…    ,゙  / )ヽ iLレ  u' | | ヾlトハ〉     |/_/  ハ !ニ⊇ '/:}  V:::::ヽ        頭がどうにかなりそうだった…    // 二二二7'T'' /u' __ /:::::::/`ヽ   /'´r -—一ァ‐゙T´ '"´ /::::/-‐  \    再帰だとかスタックだとか   / //   广¨´  /'   /:::::/´ ̄`ヽ ⌒ヽ    そんなチャチなもんじゃあ 断じてねえ  ノ ' /  ノ:::::`ー-、___/::::://       ヽ  }_/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::...       イ  もっと恐ろしいものの片鱗を味わったぜ…

Page 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で書くと

Page 35: )の品格

● 元ネタは、20年ぐらい前に雑誌(bit?)のエッセイかなにかでアイデアを見た記憶● 詳細はぜんぜん覚えてない● ご存知の方、教えてください

Page 36: )の品格

● 実践的ではない● いくら関数型じゃなくても、無駄な破壊的操作はい

まどき流行らない?

Page 37: )の品格

DEMO

Page 38: )の品格

まとめ

● カッコは単なる格好● ツリーですた●【緩募】元ネタの情報