Upgrade to Pro — share decks privately, control downloads, hide ads and more …

今からはじめるScheme入門

ayato
August 03, 2013

 今からはじめるScheme入門

ayato

August 03, 2013
Tweet

More Decks by ayato

Other Decks in Programming

Transcript

  1. 今からはじめるSCHEME入門 なれる!Little  Schemer #10LISP @ayato_p

  2. `̀(@ayato_p) (今日の主催者    The  Land  of  Lisp  =>  The  Town

     of  Lisp    Emacsが美しいから仕事したくない    だいたいプログラマ    最近ブログがScheme色な人    ハッシュタグは  #10LISP)
  3. 突然ですが

  4. Q. Lispについて どう思っていますか?

  5. Lispに対する悪いイメージ 括弧の数が合わなくてデバッグ に一日かかる ...))))))))))))))))))))))))))))))) 熟練Lisperが括弧を 投げてくる 魔術師本を読まないと一人前の Lisperになれない Lispを書くとモテない Lispやってる人は頭おかしい

  6. 現実 ...)) 近代的なエディタの支援もあり括弧に負けない Lispコミュニティはゆるふわ 魔術師本はコンピューターサイエンスの本 Lispを書くとモテる Lispやってる人は頭おかしい

  7. ちなみに

  8. 何故、Lisperは Lispを勉強したの?

  9. ハッカーと画家を読んだから Lispの国に住んでいたから SICPを読みたくて Photoshopがどう動いているのか興味があったので 関数型言語が流行っていると聞いたので 世界はS式で出来ていると洗脳されたから

  10. なので、今日は洗脳します☆

  11. Lispを書くと... プログラミングの筋がよくなります モテるようになります たのしい!✌('ω'✌  )三✌('ω')✌三(  ✌'ω')✌ 関数型言語へのとっかかりができる…かもしれない S式への愛を語るようになります Land  of

     Lispに住みたくなります
  12. と、いうわけで

  13. なれる! Little Schemer

  14. intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階

    手続き End
  15. http://exploringdata.github.io/vis/programming-languages-influence-network/

  16. Lispとは John  McCarthyが1958年に”発見”した 数学から連なる独自の系譜を持っている シンプルな構文と強力なマクロを持っている LISt  Processing  =>  LISP

  17. Schemeとは 1975年に作られたLisp方言のひとつ λ計算を基盤に持つ言語 LispとAlgolの能力と気品を統合しようとしたもの 言語仕様が50ページしかない(R5RS) (R6RSで3倍くらいまで仕様が膨れたのは内緒)

  18. Scheme処理系について Racket  =>  Schemeの後継にあたる言語 BiwaScheme  =>  JavaScriptによる実装 IronScheme  =>  .NETでの実装

    Kawa  =>  JVMでの実装 Scheme48  =>  海外でそこそこの人気を誇る処理系
  19. Q. どの処理系を使ったらいいの?

  20. A. 好きなものを使って下さい ※ただし、Racketについては 注意が必要 僕はGaucheが好きです

  21. Gaucheの紹介

  22. 知名度が高い

  23. 日本語のドキュメントがある

  24. 開発が活発

  25. バグの対応が早い

  26. 素晴らしい処理系だと思うので Gauche入れましょう ※個人的な宗教の問題がある場合この限りではない

  27. 処理系のインストール

  28. intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階

    手続き End
  29. Lispはとても簡単だよ

  30. 次の式を評価して ください

  31. (+ 3 (* 4 2)) 次の式を評価して ください

  32. (+ 3 (* 4 2)) 次の式を評価して ください 11になった?

  33. Lispの基本的なこと (+ 3 (* 4 2))

  34. Lispの基本的なこと (+ 3 (* 4 2)) 演算子

  35. Lispの基本的なこと (+ 3 (* 4 2)) 演算子 被演算子

  36. (+ 3 (* 4 2)) Lispの基本的なこと

  37. (+ 3 (* 4 2)) Lispの基本的なこと

  38. 評価 (+ 3 (* 4 2)) Lispの基本的なこと

  39. (+ 3 8 ) 評価 (+ 3 (* 4 2))

    Lispの基本的なこと
  40. (+ 3 8 ) 評価 (+ 3 (* 4 2))

    Lispの基本的なこと
  41. (+ 3 8 ) 評価 (+ 3 (* 4 2))

    Lispの基本的なこと 評価
  42. (+ 3 8 ) 評価 (+ 3 (* 4 2))

    Lispの基本的なこと 評価 11
  43. (+ 3 (* 4 2)) ちなみにこういう書き方を 「前置記法」って言うよ!

  44. ね?簡単でしょ?

  45. 四則演算をさらっと

  46. 次の式をREPLで 確認してください (- 10 3) (- 100 43 5) (*

    9 3) (* 5 6 7) (/ 27 3) (/ 27 3 3) (/ 9 6) (exact->inexact (/ 31 2))
  47. 基本的なことの続き

  48. S式(Symbolic  expression) 基本要素(数値や演算子など)、もしくは S式を並べて括弧でくくったもの

  49. S式(Symbolic  expression) 1は数値ひとつからなるS式 *は記号ひとつからなるS式 (*  2  3)は記号*、数値2、数値3からなるS式

  50. つまり、LispはS式と前置記法 で出来ていた!

  51. 基本的なことの続きの続き

  52. (+ 3 (* 4 2))

  53. (+ 3 (* 4 2)) これはリストです

  54. (+ 3 (* 4 2)) これはリストです !?

  55. リスト 括弧でくくったもの リストの中は他のリスト(!?)、シンボル、 数値、文字列とか。 ()は0個のS式からなる空のリスト

  56. REPLで確認しましょう list?は受け取った引数がリストであるか 確認する為の手続きです (list? ‘(+ 3 (* 4 2))) (list?

    ‘(1 2 3)) (list? ‘((1 2 3) 456 hoge “fuga”))
  57. リストはどうやって できているの?

  58. リストはコンスセルをつ なぎあわせたものだよ リストはどうやって できているの?

  59. リストはコンスセルをつ なぎあわせたものだよ リストはどうやって できているの? コンスセル?

  60. コンスセル 2つの小さなくっついた箱。 それぞれの箱が別のものを指すことができる。 この仕組を使えばリストを作ることができる。

  61. 1 (1 . 2)となり、ドット対と呼ばれる特別な形。 2

  62. (1)となります。 (1 . ())とも書けるが空リストは省略できます。 1 ‘()

  63. 1 2 3 ‘() (1 2 3)を考えた場合

  64. コンスセルを扱う手続き3つ cons  (コンス) car  (カー) cdr  (クダー)

  65. (cons 1 ‘())

  66. (cons 1 ‘()) この結果を想像して ください

  67. (cons 1 ‘()) この結果を想像して ください (1)ですね

  68. (car ‘(1 2 3))

  69. (car ‘(1 2 3)) これはどうですか

  70. (car ‘(1 2 3)) これはどうですか 1だと思います

  71. (cdr‘(1 2 3))

  72. (cdr‘(1 2 3)) これではどうでしょう

  73. (cdr‘(1 2 3)) これではどうでしょう (2 3)?

  74. ‘(1 2 3) car部 cdr部

  75. (1  2  3)は (cons  1  (cons  2  (cons  3  ‘())))

    となりますか?
  76. そう書くこともで きるけど、大抵のLispには listという手続きが用意され ているよ!

  77. REPLで確認しましょう (cons 1 2) (cons 1 ‘()) (cons 1 (cons

    2 (cons 3 ‘()))) (list 1 2 3) (car ‘(peanut butter and jelly)) (cdr ‘(peanut butter and jelly)) (car ‘(peanut))
  78. intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階

    手続き End
  79. ようやく自分で手続きを定義 できますね!

  80. (define (square n) (* n n)) まずは書いてみましょう 使い方は普通の組み込み手続きと同じ (square 10)

    ;;=> 100
  81. (define (square n) (* n n)) 手続きを定義するための構文 手続きの名前 仮引数名 手続きの中身

  82. 前のページのdefineは次の 定義の省略記法です

  83. (define square (lambda (n) (* n n))) 手続きを定義するための構文 手続きの名前 仮引数名

    手続きの中身
  84. defineの定義を一般化すると変 数を束縛できそうですね

  85. defineの定義を一般化すると変 数を束縛できそうですね 実際にそうすることができます

  86. (define pi 3.14) 定義するための構文 名前 名前に束縛したいもの

  87. 前述の省略しない記法は lambdaで手続きを作って手続き を名前に束縛しているというこ とだね!

  88. (lambda (n) (* n n)) lambda式は手続きを作ることができる ((lambda (n) (* n

    n)) 10) 下のように書けばそのまま使えます
  89. REPLで次の手続きを 書いてみましょう 引数に1を足して返す手続きinc 引数から1を引いて返す手続きdec 引数から受け取った名前を使って”Hello,  name”と返す 手続きhello(string-­appendは任意個の文字列を引数に とり、それらをつなぎあわせた文字列を返します) 引数を3乗して返す手続きcube

  90. intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階

    手続き End
  91. Lispは再帰的なデータ構造(リ スト)を持っているから再帰する 手続きと相性がいいんだ

  92. (define (fact n) (if (= n 1) 1 (* n

    (fact (- n 1))))) まずは一般形
  93. (define (fact n) (if (= n 1) 1 (* n

    (fact (- n 1))))) 停止条件 再帰呼び出し
  94. (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)))) 再帰のイメージ
  95. 再帰ってコスト高い気がするけ ど、普通のループ構文ないんですか? (forとかwhileとか)

  96. 再帰ってコスト高い気がするけ ど、普通のループ構文ないんですか? (forとかwhileとか) ありますが、ほとんど使いません。 コストに関してはSchemeでは「末尾再帰の 最適化」を取り入れることと仕様で決まっ ているため問題ありません。

  97. とりあえずコード

  98. 末尾再帰 (define (fact n) (define (iter m ans) (if (=

    m 1) ans (iter (- m 1) (* ans m)))) (iter n 1))
  99. もう少し見やすくかけないの?

  100. 名前付きlet版 (define (fact n) (let loop ((m n) (ans 1))

    (if (= m 1) ans (loop (- m 1) (* ans m)))))
  101. 今日のメインは末尾再帰 ではないので説明は省略します ♪

  102. REPLで次の手続きを 書いてみましょう リストとシンボルを引数にとり、シンボルと一致するものが リストの中にあれば#tを返しなければ#fを返すmember? 手続きを書いて下さい。 可変長引数を取り、リストを返すlist手続きを再定義してく ださい。可変長引数を取るときは(define  (f  .  args)

      body...)のように書いて下さい。 リストを1つ引数に取り、リストの要素の数を返すlength手 続きを再定義してください。
  103. intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階

    手続き End
  104. 高階手続きってなんですか?

  105. 高階手続きってなんですか? 手続きを引数に取る手続きです(キリッ

  106. 高階手続きってなんですか? 手続きを引数に取る手続きです(キリッ それって何がうれしい んですか?

  107. 高階手続きってなんですか? 手続きを引数に取る手続きです(キリッ それって何がうれしい んですか? コードを見ていきましょう

  108. 高階関数の例 (map (lambda (x) (* x x)) '(1 2 3

    4 5)) lambdaで手続きをつくって渡している
  109. 高階関数の例 (filter (lambda (x) (< x 5)) '(1 2 3

    4 5 6 7 8 9 10)) lambdaで手続きをつくって渡している
  110. 高階手続きを書けること によって汎用的な手続きを書く ことができるよ!

  111. REPLで次の手続きを 書いてみましょう リストの中から条件を満たす要素だけを抜き出したリスト を返す手続きfilterを書いて下さい 上のfilter手続きを使って「数値とそれ以外のものが混ざっ ているリストを受け取り、その中の数値だけについて手続き を適用する手続きfor-­each-­numbersを書いてみて下さい 同様に、数値だけに手続きを適用してその結果をリストに するmap-­numbersも書いて下さい

  112. intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階

    手続き End
  113. まとめ

  114. Lispたのしい!

  115. Lispで楽しい プログラミングライフを!!