ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.

Slides:



Advertisements
Similar presentations
コンパイラ演習 第 6 回 2005/11/17 大山 恵弘 佐藤 秀明. 今回の内容 実マシンコード生成 – アセンブリ生成 (emit.ml) – スタブ、ライブラリとのリンク 末尾呼び出し最適化 – 関数呼び出しからの効率的なリターン (emit.ml) –[ 参考 ]CPS 変換 種々の簡単な拡張.
Advertisements

コンパイラ演習 第 6 回 (2011/11/17) 中村 晃一 野瀬 貴史 前田 俊行 秋山 茂樹 池尻 拓朗 鈴木 友博 渡邊 裕貴 潮田 資秀 小酒井 隆広 山下 諒蔵 佐藤 春旗 大山 恵弘 佐藤 秀明 住井 英二郎.
2.5 プログラムの構成要素 (1)文字セット ① ASCII ( American Standard Code for Interchange ) JIS コードと同じ ② EBCDIC ( Extended Binary Coded Decimal for Information Code ) 1.
プログラミング言語論 第10回(演習) 情報工学科 木村昌臣   篠埜 功.
2006/10/26 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
(Rubyistのための) 超音速:ML入門
2006/11/9 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
ML 演習 第 1 回 佐藤 春旗, 山下 諒蔵, 前田 俊行 May 30, 2006.
ML 演習 第 8 回 2007/07/17 飯塚 大輔, 後藤 哲志, 前田 俊行
1.1 C/C++言語 Hello.ccを作りコンパイルしてa.outを作り出し実行する
ソフトウェア基礎科学 授業資料: 論理関係(logical relations)のお話
言語処理系(4) 金子敬一.
2006/11/30 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
ML 演習 第 4 回 新井淳也、中村宇佑、前田俊行 2011/05/10.
2006/10/12 山下 諒蔵 佐藤 春旗 前田俊行 大山 恵弘 佐藤 秀明 住井 英二郎
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
アルゴリズムとデータ構造 2011年6月13日
2006/11/02 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
構造体.
条件式 (Conditional Expressions)
2006/11/16 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
~sumii/class/proenb2010/ml4/
2007/1/11 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井 英二郎
ML 演習 第 3 回 新井淳也、中村宇佑、前田俊行 2011/04/26.
プログラミング言語論 第12回 関数型プログラミング 情報工学科 篠埜 功.
プログラミング言語論 第2回 情報工学科 篠埜 功.
プログラミング言語入門 手続き型言語としてのJava
PROGRAMMING IN HASKELL
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
PROGRAMMING IN HASKELL
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
お仕事にまったく役にたたない内容のコードレビューやりたいと思います。
 型推論1(単相型) 2007.
第5回放送授業.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
0からわかるF# Part1 中 博俊 F# September 2008 CTP Base.
コンパイラ 2011年10月20日
 型推論3(MLの多相型).
2007/6/12(通信コース)2007/6/13(情報コース) 住井
JavaScriptを含んだHTML文書に対する データフロー解析を用いた構文検証手法の提案
アルゴリズムとプログラミング (Algorithms and Programming)
Type Systems and Programming Languages
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 2012年6月11日
Type Systems and Programming Languages ; chapter 13 “Reference”
PROGRAMMING IN HASKELL
~sumii/class/proenb2010/ml2/
~sumii/class/proenb2009/ml4/
2006/6/27(通信コース)2006/7/5(情報コース) 住井
2008/7/16(情報コース)2008/7/22(通信コース) 住井
プログラミング言語論 第2回 篠埜 功.
PROGRAMMING IN HASKELL
Eijiro Sumii and Naoki Kobayashi University of Tokyo
関数型言語の基礎 型なしl計算 型理論 構成的プログラミング GUIにあらわれる関数概念 PBD VL
18. Case Study : Imperative Objects
~sumii/class/proenb2010/ml5/
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
コンパイラ 2012年10月11日
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
PROGRAMMING IN HASKELL
参考:大きい要素の処理.
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
プログラミング演習I 2003年6月11日(第9回) 木村巌.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
第10回 関数と再帰.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
Presentation transcript:

ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31

言語処理系の作成 第 4 回~第 7 回の予定 第 4 回: 基本的なインタプリタの作成 第 5 回: 関数型言語への拡張 字句解析・構文解析・簡単な言語の処理系の作成 第 5 回: 関数型言語への拡張 関数を作成し呼び出せるように 第 6 回: 言語処理系と型システム ML 風の型推論の実装 第 7 回: インタプリタの様々な拡張 式の評価順序に関する考察 今ここ

今回の内容 式の評価戦略 (evaluation strategy) さまざまな評価戦略 Call by value Call by name Call by need

式の評価戦略とは 式の部分式を評価する順番・手法のこと (e1, e2)‏;; fst (e1, e2)‏;; let x = e1 in e2;; e1 e2 e3 e4 e5 e6;; どの式 (ei) を どのタイミングで 評価するか

評価戦略に関する関数型言語の性質 基本的には式の評価戦略は 評価結果に影響しない 例外 1: 副作用のある式 例外 2: 止まらない評価 fst (5, print_int 3) 例外 2: 止まらない評価 let rec loop x = loop x in fst (5, loop 1)‏

代表的な三つの評価戦略 Call by value Call by name Call by need 遅延評価 (lazy evaluation)

Call by value 関数などの引数を適用の前に評価 let double n = n + n in double (2 * 3) → double 6 → 6 + 6 → 12

Call by value の利点 効率のよい実装が可能 関数に渡されるのは評価後の値のみ 評価順がわかりやすい 副作用が扱いやすい

Call by value の欠点 他の評価戦略では評価が止まる式でも 評価が止まらないことがある let rec loop x = loop x in fst (5, loop 1) → 発散 if や || などを関数としては表現できない if や || などに対しては通常の関数とは異なる 特別なプリミティブを用意しないといけない

Call by name 関数適用を引数より先に評価 let double n = n + n in

Call by name の利点 不要な評価を避けることができる if を関数として実装できる let rec loop x = loop x in fst (5 + 3, loop 1) → 5 + 3 → 8 if を関数として実装できる 他の評価戦略で評価が止まる式は call by name でも必ず評価が止まる

Call by name の欠点 式の評価の効率が悪くなる 式の評価回数やタイミングが制御困難 常に「式」の形で評価を進める必要がある 関数に直接式を渡さなければならない 同じ式を何回も評価する 式の評価回数やタイミングが制御困難 副作用がある言語では使いづらい

(2 * 3) は 元々一つの式なので 一度しか評価されない Call by need 関数適用を引数より先に評価 ただし式は一度だけ評価し、結果を使い回す let double n = n + n in double (2 * 3) → (2 * 3) + (2 * 3) → 6 + 6 → 12 Haskell が採用している評価戦略 (2 * 3) は 元々一つの式なので 一度しか評価されない

Call by need の利点 同じ式を何度も評価しない点では効率が良い 不要な評価を避けられる Call by name と同じ

Call by need の欠点 式の評価の実装が依然複雑 式の評価のタイミングが依然制御困難 常に「式」の形で評価を進める必要がある 関数に直接式を渡さなければならない 式の評価のタイミングが依然制御困難 Call by name より更に複雑

Call by value で call by name の 真似をするには λ 抽象を評価順の制御に使えばよい (例) if を関数として定義する let if_cbn c t f = if c () then t () else f () if_cbn (fun () -> true) (fun () -> 1) (fun () -> 2) → if (fun …) () then (fun …) () else (fun …) () → if true then (fun …) () else (fun …) () → (fun () -> 1) () → 1 評価の タイミング を明示 λ抽象式で 評価を遅延 OCaml で遅延評価を用いる方法については以下を参照: http://caml.inria.fr/pub/docs/manual-ocaml/manual021.html#toc73 http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lazy.html

第 7 回 課題 締切: 6/14 13:00 (日本標準時)

課題 1 (15点) 第 5 回または第 6 回のインタプリタを改造して call by name で評価を行うようにせよ タプル・リストには (まだ) 対応しなくてよい

課題 1 (続き) 実装法の一例: 関数適用 (呼出) で引数を評価しないようにする 「環境」を改造する 「変数」から「値」ではなく 「変数」から thunk への写像とする Thunk = 「(遅延評価される)式」と評価される「環境」の組 「環境」から「変数」を取りだすときに thunk の中身を評価する

課題 1 (続き) 例: 環境 E における式「e1 e2」の評価 e1 を評価して値を得る もし値がクロージャでなかったらエラー 引数名と thunk (e2, E) との対応を クロージャに含まれる環境に追加して拡張する e2 は評価せずにそのまま環境に入れる 拡張した環境でクロージャの本体を評価する let 式も同様に評価できる 「let x = e1 in e2 」は 「(fun x -> e2) e1 」と同等とみなせるので

課題 2 (15点) 課題 1 のインタプリタを改造して タプル・リストに関する操作を call by name で評価するようにせよ

課題 2 (続き) 実装法の一例: タプル・リストを表す値の定義を変更する タプル・リスト値中の要素を 「値」ではなく「thunk」にする

課題 3 (20点) 課題 2 のインタプリタ上で 全ての素数を小さい順に一つずつ含む 無限リスト primes を作れ イメージとしては 整数演算のオーバーフロー等は無視してもよい

課題 4 (20点) 第 5 回または第 6 回または 課題 1 または課題 2 のインタプリタを改造して call by need で評価を行うようにせよ タプル・リストにも対応せよ

課題 5 (20点) 課題 2 または課題 4 のインタプリタ上で 全ての無限長 2 進数列からなる無限集合 cantor_space を作れ

課題 6 (20点) 第 5 回または第 6 回または 課題 1 または課題 2 のインタプリタを改造して 以下のような演算子 (|||) を扱えるようにせよ e1 ||| e2  true (if e1  true or e2  true) false (if e1  false and e2  false) (例) # let rec loop x = loop x in (true ||| loop false, loop false ||| true) - : bool * bool = (true, true)

課題 7 (20点) 以下の整数の無限リストの型の定義 type stream = | Cons of int * stream と同様の型を再帰型を用いずに定義せよ またその型の値や値に対する操作も定義せよ

課題 7 のヒント type 'a t' = | Cons of int * 'a module E = EXIST(struct type 'a t = ('a -> 'a t') * 'a end) type stream = E.t val conv : ('a -> 'b) -> 'a t' -> 'b t' val unfold : ('a -> 'a t') -> 'a -> stream val out : stream -> stream t' val head : stream -> int val tail : stream -> stream (ここでモジュールEXIST は、第 4 回の課題 6 のもの)