Your SlideShare is downloading. ×

Lisp講義1

5,588

Published on

use in the Lisp lesson of NPCA

use in the Lisp lesson of NPCA

1 Comment
25 Likes
Statistics
Notes
  • 9ページ,演算子に先行して,ではなく演算子への適用に先行して,の方が正しそう
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
5,588
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
48
Comments
1
Likes
25
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. stibear (@stibear1996) LISP講義 PART Ⅰ
  • 2. LISPの文法 いきなり…
  • 3. と,その前に…
  • 4. Scheme • Lispには,たくさんの方言があります • 今回の講義では,その中でも,Schemeを使います • 理由としては,シンプルで理解しやすいと思われるためです
  • 5. • 3 • 3 • 6 • 2 • (+ 1 2) • (- 5 2) • (* 2 3) • (/ 8 4) LISPの文法 式(プログラム) 評価結果(実行後)
  • 6. 簡単にはこんな感じ
  • 7. 仕組み • 読み込み(READ) • 評価(EVAL) • 表示(PRINT) • これがループして行われる • REPL(Read-Eval-Print Loop)と呼ばれる
  • 8. LISPの式 (+ 1 2) 演算子 引数
  • 9. LISPの式 (+ 1 2) 演算子 引数 ※ 引数は演算子に先行して評価されます
  • 10. 文法に関してはこれだけ
  • 11. LISPの構文1 さて次は…
  • 12. • x • y • 30 • ERROR!! • (define x 10) • (define y 20) • (+ x y) • (* x z) define 式(プログラム) 評価結果(実行後)
  • 13. 仕組み • Lispの環境に記憶 • (define x 10)とすると,xは10と記憶される • 環境に記憶することを束縛という • xは10に束縛される,という
  • 14. 図解 環境 x=10 y=20 … … … (define x 10) x (define y 20) y 束縛 (+ x y) 30 評価 参照
  • 15. ならば…
  • 16. (+ x 40)とすると?
  • 17. 図解 (+ x 40) 50 評価 10 40
  • 18. 整数はそのまま整数に評価されます
  • 19. シンボル • xやyといったものは,シンボルと呼ばれます • シンボルはhoge,stibearなどなんでも良い • hideo54やsaiko-no-natsuもシンボルとして扱えます
  • 20. define • よって,defineはシンボルと値を結びつけます • つまり,束縛するということです
  • 21. アトムとリスト Lispといえば…
  • 22. リストとアトム • ()で囲われた式をリストといいます • そうでないものをアトムといいます • (+ 1 2) • (define hoge fuga) • (foo bar baz) • これらはすべてリスト • a • 200 • これらはすべてアトム
  • 23. LISPの構文2 try to eat...
  • 24. いきなりですが
  • 25. 40を評価すると40です
  • 26. では
  • 27. 何を評価すると シンボルxになるでしょう?
  • 28. 答え:quoteを使います
  • 29. • x • hoge • saiko-no-natsu • (quote foo) • (quote x) • (quote hoge) • (quote saiko-no-natsu) • (quote (quote foo)) quote 式(プログラム) 評価結果(実行後)
  • 30. quote • quoteを使うと,評価を1回止めることができます • 便利のため,(quote 何々)と書く代わりに,‘何々と書けます
  • 31. 評価のおさらい 環境 x=10 y=20 … … … (quote x) x x 10 評価 参照 評価
  • 32. (define husband ‘wife)として
  • 33. husbandを評価すると?
  • 34. 答え:シンボルwifeが返ります
  • 35. 特殊オペレータ すぺしゃる!
  • 36. 特殊オペレータ • quoteやdefineはすべての引数が必ずしも評価されません • これらが特殊オペレータであるためです • ほかにも,ifなどが特殊オペレータです • 特殊オペレータが成す式を特殊フォームといいます
  • 37. 関数 • 特殊オペレータに対して,+や-のような, 引数がすべて評価されるような演算子を関数といいます • (関数 引数0 引数1...)のような式を関数呼び出しといいます • 関数呼び出しを評価すると,関数の返り値が得られます
  • 38. 同図像性 ホモイコニシティ
  • 39. いきなりの難しいセクション!
  • 40. しかし, これぞLispの神髄であります
  • 41. 同図像性 • 簡単に言うと, • プログラムである式とデータである値が等価だということ
  • 42. ところで
  • 43. リスト • 括弧で囲われた式はリスト • コンスによって成ります
  • 44. コンス • コンスはcar部とcdr部という2つの記憶域を持ちます • コンスは関数consによって作ることができます • (cons ‘a ‘b)→(a . b) • (a . b)はcar部にシンボルa,cdr部にシンボルbを持ちます
  • 45. コンス car (cons 'a 'b) (a . b) cdr a b 評価
  • 46. コンス • 関数carや関数cdrでそれぞれcar部,cdr部が得られます • (car (cons ‘a ‘b))→a • (cdr (cons ‘a ‘b))→b • コンスは値へのアドレスを持っているだけ • なのでどんな値も格納できます • コンスのcdr部がコンスなら,ドットは省略されます • (cons 'a (cons 'b 'c))→(a b . c)
  • 47. コンス car (cons 'a (cons 'b 'c)) (a b . c) cdr a b 評価 c car cdr
  • 48. コンス • コンスのcdr部が空リスト()だった場合,cdr部の表示は省略 • (cons ‘a (cons ’b ‘())→(a b)
  • 49. コンス car (cons 'a (cons 'b '())) (a b) cdr a b 評価 car cdr
  • 50. リスト(再定義) • 空リスト • もしくは,cdr部にリストを格納したコンス
  • 51. リスト 空リスト 値 値 値
  • 52. リスト(a b c)を作るには • (cons ‘a (cons ‘b (cons ‘c ‘()))) • ‘(a b c) • (list ‘a ‘b ‘c)
  • 53. という訳で
  • 54. データと式は一緒ですね
  • 55. ちなみに
  • 56. リストのcdr • (car ‘(a b c))→a • (cdr ‘(a b c))→(b c)
  • 57. リストのcdr car cdr a b c car cdr car cdr このコンスのcdrを取る
  • 58. リストのcdr b c car cdr car cdr
  • 59. 関数 ふぁ,ふぁ,ふぁんくしょんっ
  • 60. 関数を作ってみましょう
  • 61. 関数 • 特殊オペレータlambdaを使って作ります • (lambda (n) (+ n 1)) • 上は引数を1つとって,それに1を足したものを返す関数です • 上の式で,nは仮引数で…とかいう話はCとかと一緒なので省略 • 呼び出す時は,リストの最初に置いて,その後に引数を続けます • (+ 10 20)→30 • 同様に • ((lambda (n) (+ n 1)) 10)→11
  • 62. • #<procedure> • 11 • 21 • (lambda (n) (+ n 1)) • ((lambda (n) (+ n 1)) 10) • ((lambda (n) (+ n 1)) 20) lambda 式(プログラム) 評価結果(実行後)
  • 63. 関数 • 関数も値 • よってdefineを使ってシンボルを束縛できる • (define plus1 (lambda (n) (+ n 1))) • これでplus1というシンボルを使って関数呼び出しができます • (plus1 29)→30
  • 64. 関数 • (lambda (仮引数...) 式...) • 仮引数は束縛変数とも呼ばれ,その関数内でのみ参照できます • つまり,束縛変数のスコープはその関数内ということです • 対して,どこでも参照できる変数を大域変数といいます • 束縛変数の,大域変数に対応する呼び方として, • 局所変数という呼び方もあります • 関数は,環境を新たに作ることで,束縛変数を実現しています
  • 65. 関数 環境 x=10 y=20 … … … ((lambda (x y) (+ x y)) 2 3) 束縛 新たな環境 x=2 y=3 参照
  • 66. LISPの構文3 Let It Be
  • 67. let • 局所変数を定義するために,let特殊オペレータを使います • (let ((a 2) (b 3)) (+ a b))→5 • 簡単ですね • let特殊オペレータは新たに環境を作ります
  • 68. let 環境 x=10 y=20 … … … (let ((x 2) (y 3)) (+ x y)) 束縛 新たな環境 x=2 y=3 参照
  • 69. lambdaの時とそっくりですね
  • 70. let • letはlambdaの構文糖衣として考えることができます • つまり,letはlambdaと等価です • (let ((a 2) (b 3)) (+ a b)) • ((lambda (a b) (+ a b)) 2 3)
  • 71. 構文糖衣 • syntax-sugerの訳語 • Wikipediaには,次のように書いてあります 糖衣構文(とういこうぶん)は、プログラミング言語において、読み 書きのしやすさのために導入される構文であり、既に定義されている 他の構文の(人間にとってより理解しやすい)書換えとして定義され るもののことである。構文糖(こうぶんとう)あるいは構文糖衣とも いう。
  • 72. 構文糖衣 • quoteの構文糖衣として,「’」があります • また,関数と定義するときの構文糖衣として,次のように書けます • (define hoge (lambda (foo) (bar baz))) • (define (hoge foo) (bar baz)) • どちらも正しい関数定義です
  • 73. スコープ ちょっと脱線
  • 74. スコープ • 関数の説明の時にも出てきました • その変数が見えている(=参照可能な)範囲のことです • トップレベルでdefineすると,変数のスコープはグローバルに • 関数の仮引数やletで定義された変数のスコープは,ローカルに なります • また,Schemeは,レキシカルスコープと呼ばれる種類のスコープ を持ちます
  • 75. レキシカルスコープ • 字句的,構文,静的スコープなどともいいます • これによってクロージャ(関数閉包)というものを成します
  • 76. • x • test • 100 • 100 • (define x 100) • (define (test) x) • (test) • (let ((x 10)) (test)) レキシカルスコープ 式(プログラム) 評価結果(実行後)
  • 77. クロージャ 骨を折ります
  • 78. クロージャ • Schemeにおいて,クロージャは無名関数と同義であるといえます [要出典] • カプセル化や遅延評価などのためによく使います
  • 79. • counter • c1 • 1 • 2 • 3 • (define (counter) (let ((c 0)) (lambda () (set! c (+ c 1)) c))) • (define c1 (counter)) • (c1) • (c1) • (c1) クロージャ 式(プログラム) 評価結果(実行後)
  • 80. 副作用 副作用使用罪だ!!
  • 81. 副作用 • set!は副作用をもたらす特殊オペレータです • その他,displayなども副作用をもたらします • 破壊的代入やI/O制御は副作用を伴います
  • 82. 再帰 私に還りなさい
  • 83. 再帰 • あるものについて記述する際に、記述しているものそれ自身への参 照が、その記述中にあらわれることをいう(Wikipediaより) • 再帰的に関数を呼び出すことを再帰呼び出しといいます • ある関数のなかでその関数が呼び出されているとき, それは再帰関数であるといえます
  • 84. • fact • 120 • (define (fact n) (if (= n 0) 1 (* n (fact (- n 1)))) • (fact 5) 再帰関数 式(プログラム) 評価結果(実行後)
  • 85. 末尾再帰 • 関数の末尾文脈での関数呼び出しは末尾呼び出しと呼ばれます • 再帰的な末尾呼び出しを末尾再帰といいます • Schemeでは,末尾呼び出しが最適化されます • ループ構造と等価なものに展開され,スタックを消費しないものに なります • 非常に簡単にいうと,無駄が少ないです
  • 86. • (define (fact n) (fact-tc n 1)) • (define (fact-tc n m) (if (= n 0) m (fact-tc (- n 1) (* n m)))) • (define (fact n) (if (= n 0) 1 (* n (fact (- n 1)))) 末尾再帰 非末尾再帰版fact 末尾再帰版fact
  • 87. 非末尾再帰版fact関数呼び出し (fact 5) (* 5 (fact 4)) (* 5 (* 4 (fact 3))) (* 5 (* 4 (* 3 (fact 2)))) (* 5 (* 4 (* 3 (* 2 (fact 1))))) (* 5 (* 4 (* 3 (* 2 (* 1 (fact 0)))))) (* 5 (* 4 (* 3 (* 2 (* 1 1)))))
  • 88. 非末尾再帰版fact関数呼び出し (* 5 (* 4 (* 3 (* 2 (* 1 1))))) (* 5 (* 4 (* 3 (* 2 1)))) (* 5 (* 4 (* 3 2))) (* 5 (* 4 6)) (* 5 24) 120
  • 89. 末尾再帰版fact関数呼び出し (fact 5) (fact-tc 5 1) (fact-tc 4 5) (fact-tc 3 20) (fact-tc 2 60) (fact-tc 1 120) (fact-tc 0 120) 120
  • 90. LISPの構文4 Let It Be再び
  • 91. named-let • 名前付きletというもので,ループを上手く書くことができます
  • 92. named-letを使ったfact関数 • (define (fact n) (let rec ((a n) (b 1)) (if (= a 0) b (rec (- a 1) (* a b))))) • letrecを使って似たように定義ができます
  • 93. 高階関数 今でもあなただけが 青春の...
  • 94. 高階関数 • 関数を引数として取ったり,返り値として返したりする関数
  • 95. map関数 • リストの各要素にマッピング • (map func list0 list1 ... listN)
  • 96. sort関数 • リストの要素をソート • (sort lst func)
  • 97. fold関数 • 畳み込み
  • 98. 演習 このセクションを書こうとした人は途中で寝てしまいました。
  • 99. 適当に演習
  • 100. 参考 • 今回このスライドを作るにあたって, http://lyrical.bugyo.tk/ (魔法言語 リリカル☆Lisp) を参考にしました • 非常に良い教材です
  • 101.

×