520 likes | 632 Views
式の評価順序,副作用. 【 キーワード 】 前置記法,式の入れ子,引数, begin 文での式の評価順序,副作用, ブール値,条件式, cond 文, cond 文での条件節の評価順序, ラムダ式. 1. 式の例. ■ 値 例えば 数値 0.2 や - 1/3 など 文字列 "I am Fine" など シンボル 'Red など 特別な意味を持つ語 true や false や empty など 関数名 sin など ■ (値でない) 普通の式 ・・・ 半角の括弧で囲む 例えば. DrScheme の動作画面. 式. 評価結果.
E N D
式の評価順序,副作用 【キーワード】前置記法,式の入れ子,引数,begin 文での式の評価順序,副作用,ブール値,条件式,cond 文,cond 文での条件節の評価順序,ラムダ式 1
式の例 ■ 値例えば 数値0.2や -1/3 など 文字列"I am Fine" など シンボル'Red など 特別な意味を持つ語 true や false や empty など 関数名sin など ■ (値でない)普通の式 ・・・ 半角の括弧で囲む 例えば DrScheme の動作画面 式 評価結果 DrScheme の動作画面 2
数の演算の例 quotient : 商 remainder : 剰余 add1 : 1足す sub1 : 1引く max : 最大 min : 最小 abs : 絶対値 DrScheme の動作画面 3
数の演算の例(続き) expt : 指数 log : 対数 sin, cos, tan: 三角関数 asin, acos, atan: 逆三角関数 およそ16桁で計算が 打ち切られている (近似計算) ※ 無限桁が得られる わけではない DrScheme の動作画面 4
前置記法 () Scheme の式は,次の形 <式>の並び <関数名> Scheme の式の例 数学の記法 sin(0.1)(sin0.1) 2 + 3(+2 3) ・・・ 引数が1個 ・・・ 引数が2個 処理を表す関数名(「+」など)が前に来て, 後に引数(関数に適用されるもの)が来る (前置記法という) 5
Scheme の式 () <式>の並び <関数名> 引数は 1個以上 (+ 3 2) 式の例 半角のスペース で区切る 半角の括弧 で囲む このルールを守らないと構文エラー 6
式の例 2 + 3 + 4 (+2 3 4) 2 * 3 * 4 (*2 3 4) 2x2 - 3x - 1 (+ (*2x x) (*-3x) -1)) +, -, *, /などは,引数の数は 2個以上(任意個)である
式の入れ子 数学の記法 例 (* (+1 2 3) 4) Scheme の式 式が入れ子になることがある 8
式の入れ子 例 数学の記法 (* (+2 2) (/ (* (+3 5) (/ 30 10)) 2)) Scheme の式 9
(* (+2 2) (/ (* (+3 5) (/30 10)) 2)) 入れ子になった式の評価順序 Scheme の式の例 括弧が,計算の「単位」を表現. 最も内側のものが最初に評価される 「最も内側」のものが複数のときは? 実は,どれを先に評価しても,式全体の 評価結果は同じ! 10
副作用の例 副作用: 何の役に立つの? 画面表示,キーボードからのデータ読み込み,データファイルの操作,グラフィックスなど <例> (display (* (+ 3 2) 3)) (display (+ 1 2 3 4)) ※ display 関数の評価結果は「何もない (void)」
begin 文 ■ 関数の本体式は「式1つ」だけ • 普通は困らない (例) ■ 画面表示などをある順序で行いたい,など 複数の副作用を所定の順序で! (begin …) で 複数の式を1つに まとめる
cond 文を本体式に持つ関数 3つの状況に分かれる xから yを求める関数を定義する 13
y 40 30 20 10 x 0 5 10
各状況ごとに,条件節(= Question +Answer) (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) 式 条件式または else Question Answer 15
条件節の評価順序 (cond [(<x0) 0] [(<x5) (*2x)] [(else(- (*4x) 10)] 一番上の 条件節から開始 true false true false 最後の elseに辿りつくと,対応する Answer が必ず評価される 16
もし x<0ならば 評価順 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) x < 0 のとき 評価される部分 ① 無視される x<0 のときは trueになる 17
もし 0≦x<5ならば 評価順 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) ① 無視される 0≦ x<5のときは falseになる 18
もし 0≦x<5ならば 評価順 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) 0≦x<5 のとき 評価される部分 ① ② 無視される 0≦ x<5 のときは trueになる 19
もし 5≦xならば 評価順 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) ① 無視される 5≦ xのときは falseになる 20
もし 5≦xならば 評価順 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) ① 無視される ② 5≦ xのときは falseになる 21
もし 5≦xならば 評価順 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) ① ② ③ 5≦xのとき 評価される部分 22
関数の本体式は xを含む Scheme の式 種々の引数を,関数 f1に適用した評価結果の例 23
条件節の評価順序 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) 1つの cond 文 ① ② ③ • cond 文の条件節の並びは上から順に評価 • ※ 上の例では①,②,③の順に評価が行われる • ①が成り立てば,②,③は評価されない • ②が成り立てば,③は評価されない • → ② の条件節で, • 「(and (<=0x) (<x5))」と書かずに, • 「(<x5)」 としているのは間違いではない • else に辿りつくと,その Answer が必ず評価される • ※ 当然 else が末尾になる 24
cond 文の一般形 (cond (cond [question answer] [question answer] ... または ... [question answer]) [else answer]) Question 部に書けるもの ■ 条件式 (odd? ...), (< ... ...), (<= ... ...) など ※評価結果がブール値 (true, false) になる式 25
else に関する補足説明 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [else (- (*4x) 10)])) • cond 文中に else を書く義務は無い • 但し,実行時エラーが出ないように,十分に注意する必要あり 同じ意味 (define (f1 x) (cond [(<x0) 0] [(<x5) (*2x)] [(>=x5) (- (*4x) 10)]))
Scheme処理系の実演 27
DrScheme の使用準備 DrScheme の起動 実演では「Advanced Student」に設定 言語 → 言語の選択 → Advanced Student → 「実行」ボタン 28 28
実演1.途中で改行された式 • 次の式を「対話ウインドウ」で評価 (* (+2 2) (/ (* (+3 5) (/ 30 10)) 2)) ※ ここでは Enterキーを4回押しているが,式の途中では評価結果は出力されない 29 29
この式は4行ある. ※ 式の途中で Enter を押しても 評価結果は出力されない Scheme の式を入力 (複数行の入力) 30 30
式の最後でEnter キーを押すと,式の評価結果 「48」が出力される 31 31
実演2. 元利の計算 • 元金と年利と年数から元利を求める 「元利 = 元金 × (1+年利)年数」 • 元金1000円、年利2%とし、50年後 • xの y乗の計算には expt を使う (expt x y)
実演3.円の描画 【事前準備】 ・DrScheme の起動 ・言語 (Language) → ティーチパックの追加 (Add Teachpack) で, hdtp\draw.ss を追加 ・言語の選択 (Choose Language) で Advanced Student を選択 ・実行ボタンを押す 【関数定義】 x y r キャンバスサイズ 縦: 2y 横: 2x 円の中心 (x, y) 円の半径 r 33
キャンバスを開く操作: 関数 start の副作用 円を描画する操作: 関数 draw-solid-disk の副作用
実演4.条件式を本体式とする関数の定義 • 「定義ウインドウ」で,次の関数定義を行う (define (is-child? age) (< age12)) 2. その後,次の式を「対話ウインドウ」で評価させ,評価結果を得る. (is-child?10) (is-child?11) (is-child?12) (is-child?13) true, false が得られる 35 35
関数定義を行う 式の評価結果として, true または falseが 得られる 36
実演5.簡単な cond 文 • 「定義ウインドウ」で,次の関数定義を行う • ;; f1: number -> number • ;; (f1 0) -> 0 • ;; (f1 2) -> 1 • (define (f1x) • (cond • [(<x1) 0] • [else (-x1)])) 2. その後,次の式を「対話ウインドウ」で評価させる (f10) (f12) 37 37
Answer 部に,Scheme の式を 書くことができる. 「[else x-1]」と書くのは 構文エラーなので,要注意 38 38
実演6.簡単な cond文(2) • 「定義ウインドウ」で,次の関数定義を行う (define (f2x) (cond [(< (logx) 1) (logx)] [else1])) 2. その後,次の式を「対話ウインドウ」で評価させる (f21) (f210) 39 39
Question 部には, 任意の条件式 (true, false を 評価結果とするような式) を書くことができる. 40 40
実演7.簡単な cond文(3) • 「定義ウインドウ」で,次の関数定義を行う (define (f3x) (cond [(even?x) 0] [(odd?x) x])) 2. その後,次の式を「対話ウインドウ」で評価させる (f31) (f32) 41
odd?, even?の「?」を 忘れやすいので,要注意 42
実演8.cond 文の入れ子の例 cond 文の 入れ子 (define (foo x y) (cond [(>=x0) x] [else (cond [(>=y0) y] [else0])])) ※ and を使う定義も考えられる 43
実習9.cond 文 • 「定義ウインドウ」で,次の関数定義を行う • 入力した後に,Run ボタンを押す (define (interest-rateamount) (cond [(<=amount1000) 0.040] [(<=amount5000) 0.045] [(>amount5000) 0.050])) 2. その後,次の式を「対話ウインドウ」で評価させる (interest-rate1500) (interest-rate6000) 45 45
定義ウインドウで,関数定義を行う 46 46
Run ボタンを押して, 関数定義を,読み込ませる このとき、対話ウインドウ の中身はクリアされる 読み込ませた関数 interest-rate を使ってみよう 47 47
対話ウインドウで、 (interest-rate1500) と入力して、Enter キーを押す ※ DrScheme は,関数 interest-rateのパラメータ amountを 1500 に置き換えた後,本体式を評価する 48 48
評価結果である「0.045」が 表示される 49 49
対話ウインドウで、 (interest-rate6000) と入力して、Enter キーを押す 50 50