Submit Search
Lisp講義1
•
31 likes
•
8,643 views
stibear (stibear1996)
Follow
use in the Lisp lesson of NPCA
Read less
Read more
1 of 101
Download now
Downloaded 65 times
More Related Content
Lisp講義1
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.
終
Download