Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
今からはじめるScheme入門
Search
ayato
August 03, 2013
Programming
3
1.7k
今からはじめるScheme入門
ayato
August 03, 2013
Tweet
Share
More Decks by ayato
See All by ayato
Clojureという言語が私逹にもたらしたもの
ayato0211
6
2.9k
3年間考え続けてきたWebアプリケーションにおけるテストの話
ayato0211
3
230
Re:REPL-Driven Development
ayato0211
3
1.2k
Meta Template Engine
ayato0211
2
1k
超変換! Hiccup data structure!!
ayato0211
2
560
About Integrant
ayato0211
0
510
Muscle Assert
ayato0211
0
230
Clojureを用いたWebアプリケーション開発
ayato0211
2
3k
翻訳にまつわるエトセトラ
ayato0211
6
1.2k
Other Decks in Programming
See All in Programming
歴史と現在から考えるスケーラブルなソフトウェア開発のプラクティス
i10416
0
290
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
210
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
290
Beyond ORM
77web
11
1.5k
非ブラウザランタイムとWeb標準 / Non-Browser Runtimes and Web Standards
petamoriken
0
420
php-conference-japan-2024
tasuku43
0
410
テストケースの名前はどうつけるべきか?
orgachem
PRO
1
290
Androidアプリの One Experience リリース
nein37
0
950
AppRouterを用いた大規模サービス開発におけるディレクトリ構成の変遷と問題点
eiganken
1
420
20241217 競争力強化とビジネス価値創出への挑戦:モノタロウのシステムモダナイズ、開発組織の進化と今後の展望
monotaro
PRO
0
250
Stackless и stackful? Корутины и асинхронность в Go
lamodatech
0
1.3k
コンテナをたくさん詰め込んだシステムとランタイムの変化
makihiro
1
190
Featured
See All Featured
Visualization
eitanlees
146
15k
Embracing the Ebb and Flow
colly
84
4.5k
VelocityConf: Rendering Performance Case Studies
addyosmani
327
24k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
230
Mobile First: as difficult as doing things right
swwweet
222
9k
Optimizing for Happiness
mojombo
376
70k
Designing for Performance
lara
604
68k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.5k
Automating Front-end Workflow
addyosmani
1366
200k
Gamification - CAS2011
davidbonilla
80
5.1k
Code Reviewing Like a Champion
maltzj
521
39k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Transcript
今からはじめるSCHEME入門 なれる!Little Schemer #10LISP @ayato_p
`̀(@ayato_p) (今日の主催者 The Land of Lisp => The Town
of Lisp Emacsが美しいから仕事したくない だいたいプログラマ 最近ブログがScheme色な人 ハッシュタグは #10LISP)
突然ですが
Q. Lispについて どう思っていますか?
Lispに対する悪いイメージ 括弧の数が合わなくてデバッグ に一日かかる ...))))))))))))))))))))))))))))))) 熟練Lisperが括弧を 投げてくる 魔術師本を読まないと一人前の Lisperになれない Lispを書くとモテない Lispやってる人は頭おかしい
現実 ...)) 近代的なエディタの支援もあり括弧に負けない Lispコミュニティはゆるふわ 魔術師本はコンピューターサイエンスの本 Lispを書くとモテる Lispやってる人は頭おかしい
ちなみに
何故、Lisperは Lispを勉強したの?
ハッカーと画家を読んだから Lispの国に住んでいたから SICPを読みたくて Photoshopがどう動いているのか興味があったので 関数型言語が流行っていると聞いたので 世界はS式で出来ていると洗脳されたから
なので、今日は洗脳します☆
Lispを書くと... プログラミングの筋がよくなります モテるようになります たのしい!✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌ 関数型言語へのとっかかりができる…かもしれない S式への愛を語るようになります Land of
Lispに住みたくなります
と、いうわけで
なれる! Little Schemer
intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階
手続き End
http://exploringdata.github.io/vis/programming-languages-influence-network/
Lispとは John McCarthyが1958年に”発見”した 数学から連なる独自の系譜を持っている シンプルな構文と強力なマクロを持っている LISt Processing => LISP
Schemeとは 1975年に作られたLisp方言のひとつ λ計算を基盤に持つ言語 LispとAlgolの能力と気品を統合しようとしたもの 言語仕様が50ページしかない(R5RS) (R6RSで3倍くらいまで仕様が膨れたのは内緒)
Scheme処理系について Racket => Schemeの後継にあたる言語 BiwaScheme => JavaScriptによる実装 IronScheme => .NETでの実装
Kawa => JVMでの実装 Scheme48 => 海外でそこそこの人気を誇る処理系
Q. どの処理系を使ったらいいの?
A. 好きなものを使って下さい ※ただし、Racketについては 注意が必要 僕はGaucheが好きです
Gaucheの紹介
知名度が高い
日本語のドキュメントがある
開発が活発
バグの対応が早い
素晴らしい処理系だと思うので Gauche入れましょう ※個人的な宗教の問題がある場合この限りではない
処理系のインストール
intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階
手続き End
Lispはとても簡単だよ
次の式を評価して ください
(+ 3 (* 4 2)) 次の式を評価して ください
(+ 3 (* 4 2)) 次の式を評価して ください 11になった?
Lispの基本的なこと (+ 3 (* 4 2))
Lispの基本的なこと (+ 3 (* 4 2)) 演算子
Lispの基本的なこと (+ 3 (* 4 2)) 演算子 被演算子
(+ 3 (* 4 2)) Lispの基本的なこと
(+ 3 (* 4 2)) Lispの基本的なこと
評価 (+ 3 (* 4 2)) Lispの基本的なこと
(+ 3 8 ) 評価 (+ 3 (* 4 2))
Lispの基本的なこと
(+ 3 8 ) 評価 (+ 3 (* 4 2))
Lispの基本的なこと
(+ 3 8 ) 評価 (+ 3 (* 4 2))
Lispの基本的なこと 評価
(+ 3 8 ) 評価 (+ 3 (* 4 2))
Lispの基本的なこと 評価 11
(+ 3 (* 4 2)) ちなみにこういう書き方を 「前置記法」って言うよ!
ね?簡単でしょ?
四則演算をさらっと
次の式をREPLで 確認してください (- 10 3) (- 100 43 5) (*
9 3) (* 5 6 7) (/ 27 3) (/ 27 3 3) (/ 9 6) (exact->inexact (/ 31 2))
基本的なことの続き
S式(Symbolic expression) 基本要素(数値や演算子など)、もしくは S式を並べて括弧でくくったもの
S式(Symbolic expression) 1は数値ひとつからなるS式 *は記号ひとつからなるS式 (* 2 3)は記号*、数値2、数値3からなるS式
つまり、LispはS式と前置記法 で出来ていた!
基本的なことの続きの続き
(+ 3 (* 4 2))
(+ 3 (* 4 2)) これはリストです
(+ 3 (* 4 2)) これはリストです !?
リスト 括弧でくくったもの リストの中は他のリスト(!?)、シンボル、 数値、文字列とか。 ()は0個のS式からなる空のリスト
REPLで確認しましょう list?は受け取った引数がリストであるか 確認する為の手続きです (list? ‘(+ 3 (* 4 2))) (list?
‘(1 2 3)) (list? ‘((1 2 3) 456 hoge “fuga”))
リストはどうやって できているの?
リストはコンスセルをつ なぎあわせたものだよ リストはどうやって できているの?
リストはコンスセルをつ なぎあわせたものだよ リストはどうやって できているの? コンスセル?
コンスセル 2つの小さなくっついた箱。 それぞれの箱が別のものを指すことができる。 この仕組を使えばリストを作ることができる。
1 (1 . 2)となり、ドット対と呼ばれる特別な形。 2
(1)となります。 (1 . ())とも書けるが空リストは省略できます。 1 ‘()
1 2 3 ‘() (1 2 3)を考えた場合
コンスセルを扱う手続き3つ cons (コンス) car (カー) cdr (クダー)
(cons 1 ‘())
(cons 1 ‘()) この結果を想像して ください
(cons 1 ‘()) この結果を想像して ください (1)ですね
(car ‘(1 2 3))
(car ‘(1 2 3)) これはどうですか
(car ‘(1 2 3)) これはどうですか 1だと思います
(cdr‘(1 2 3))
(cdr‘(1 2 3)) これではどうでしょう
(cdr‘(1 2 3)) これではどうでしょう (2 3)?
‘(1 2 3) car部 cdr部
(1 2 3)は (cons 1 (cons 2 (cons 3 ‘())))
となりますか?
そう書くこともで きるけど、大抵のLispには listという手続きが用意され ているよ!
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))
intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階
手続き End
ようやく自分で手続きを定義 できますね!
(define (square n) (* n n)) まずは書いてみましょう 使い方は普通の組み込み手続きと同じ (square 10)
;;=> 100
(define (square n) (* n n)) 手続きを定義するための構文 手続きの名前 仮引数名 手続きの中身
前のページのdefineは次の 定義の省略記法です
(define square (lambda (n) (* n n))) 手続きを定義するための構文 手続きの名前 仮引数名
手続きの中身
defineの定義を一般化すると変 数を束縛できそうですね
defineの定義を一般化すると変 数を束縛できそうですね 実際にそうすることができます
(define pi 3.14) 定義するための構文 名前 名前に束縛したいもの
前述の省略しない記法は lambdaで手続きを作って手続き を名前に束縛しているというこ とだね!
(lambda (n) (* n n)) lambda式は手続きを作ることができる ((lambda (n) (* n
n)) 10) 下のように書けばそのまま使えます
REPLで次の手続きを 書いてみましょう 引数に1を足して返す手続きinc 引数から1を引いて返す手続きdec 引数から受け取った名前を使って”Hello, name”と返す 手続きhello(string-appendは任意個の文字列を引数に とり、それらをつなぎあわせた文字列を返します) 引数を3乗して返す手続きcube
intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階
手続き End
Lispは再帰的なデータ構造(リ スト)を持っているから再帰する 手続きと相性がいいんだ
(define (fact n) (if (= n 1) 1 (* n
(fact (- n 1))))) まずは一般形
(define (fact n) (if (= n 1) 1 (* n
(fact (- n 1))))) 停止条件 再帰呼び出し
(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)))) 再帰のイメージ
再帰ってコスト高い気がするけ ど、普通のループ構文ないんですか? (forとかwhileとか)
再帰ってコスト高い気がするけ ど、普通のループ構文ないんですか? (forとかwhileとか) ありますが、ほとんど使いません。 コストに関してはSchemeでは「末尾再帰の 最適化」を取り入れることと仕様で決まっ ているため問題ありません。
とりあえずコード
末尾再帰 (define (fact n) (define (iter m ans) (if (=
m 1) ans (iter (- m 1) (* ans m)))) (iter n 1))
もう少し見やすくかけないの?
名前付きlet版 (define (fact n) (let loop ((m n) (ans 1))
(if (= m 1) ans (loop (- m 1) (* ans m)))))
今日のメインは末尾再帰 ではないので説明は省略します ♪
REPLで次の手続きを 書いてみましょう リストとシンボルを引数にとり、シンボルと一致するものが リストの中にあれば#tを返しなければ#fを返すmember? 手続きを書いて下さい。 可変長引数を取り、リストを返すlist手続きを再定義してく ださい。可変長引数を取るときは(define (f . args)
body...)のように書いて下さい。 リストを1つ引数に取り、リストの要素の数を返すlength手 続きを再定義してください。
intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階
手続き End
高階手続きってなんですか?
高階手続きってなんですか? 手続きを引数に取る手続きです(キリッ
高階手続きってなんですか? 手続きを引数に取る手続きです(キリッ それって何がうれしい んですか?
高階手続きってなんですか? 手続きを引数に取る手続きです(キリッ それって何がうれしい んですか? コードを見ていきましょう
高階関数の例 (map (lambda (x) (* x x)) '(1 2 3
4 5)) lambdaで手続きをつくって渡している
高階関数の例 (filter (lambda (x) (< x 5)) '(1 2 3
4 5 6 7 8 9 10)) lambdaで手続きをつくって渡している
高階手続きを書けること によって汎用的な手続きを書く ことができるよ!
REPLで次の手続きを 書いてみましょう リストの中から条件を満たす要素だけを抜き出したリスト を返す手続きfilterを書いて下さい 上のfilter手続きを使って「数値とそれ以外のものが混ざっ ているリストを受け取り、その中の数値だけについて手続き を適用する手続きfor-each-numbersを書いてみて下さい 同様に、数値だけに手続きを適用してその結果をリストに するmap-numbersも書いて下さい
intro 進行表 Lispと Scheme 基本的 なこと 手続き 再帰 処理 高階
手続き End
まとめ
Lispたのしい!
Lispで楽しい プログラミングライフを!!