Download - Frege, What a Non-strict Language
![Page 1: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/1.jpg)
Frege,What a Non-strict Language
チェシャ猫 (@y_taka_23)NL 名古屋 (2016/04/16)
![Page 2: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/2.jpg)
自己紹介
● 名前 : チェシャ猫
○ Twitter: @y_taka_23
○ GitHub: y-taka-23
● 好きなもの
○ Haskell
○ 形式手法 (Coq, Alloy, SPIN, etc...)
● 自称 Frege エバンジェリスト
![Page 3: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/3.jpg)
本日の内容
● JVM 言語 Frege の概要
○ 基本的な特徴
○ Haskell との比較
● Java コード生成と非正格評価
○ コンパイルの仕組み
○ 評価戦略のマッピング
![Page 4: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/4.jpg)
1. JVM 言語 Frege の概要
![Page 5: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/5.jpg)
“Frege is a Haskell for JVM”
![Page 6: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/6.jpg)
Frege のエッセンス
● 純粋・非正格評価な関数型言語
○ 本日のメイントピック
● 強い静的型付け
○ Hindley-Milner 型推論 + Rank-N types
● モナドによる Java の呼び出し
○ 歌舞伎座.tech #9 での発表スライド参照
○ 「すごい Frege たのしく学ぼう!」で検索
![Page 7: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/7.jpg)
Q: どんな文法?
![Page 8: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/8.jpg)
Hello, Frege
module Hello where
greeting :: String -> Stringgreeting name = “Hello, “ ++ name
main :: [String] -> IO ()main args = do putStrLn $ greeting “World”
![Page 9: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/9.jpg)
Hello, Frege
module Hello where
greeting :: String -> Stringgreeting name = “Hello, “ ++ name
main :: [String] -> IO ()main args = do putStrLn $ greeting “World”
![Page 10: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/10.jpg)
A: ほぼ Haskell
![Page 11: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/11.jpg)
『すごい Haskell』翻訳実験
● 全サンプルコードを Frege に○ https://github.com/y-taka-23/learn-you-a-frege
● だいたい丸写しでコンパイルが通る
○ 構文論的には Haskell 2010 互換
![Page 12: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/12.jpg)
2. Java コード生成と非正格評価
![Page 13: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/13.jpg)
Frege のコンパイル
● コンパイラ自身も Frege 実装
● JVM 系ビルドツールが利用可
○ Gradle, Maven, sbt. Leiningen, Bazel
● コンパイルすると Java ソースコードに
○ あくまでも中間生成コードで可読性低
○ 最新版 v3.24 で生成ロジックが変更
![Page 14: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/14.jpg)
Hello again, Frege
module Hello where
greeting :: String -> Stringgreeting name = “Hello, “ ++ name
main :: [String] -> IO ()main args = do putStrLn $ greeting “World”
![Page 15: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/15.jpg)
Hello again, Frege
module Hello where
greeting :: String -> Stringgreeting name = “Hello, “ ++ name
main :: [String] -> IO ()main args = do putStrLn $ greeting “World”
![Page 16: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/16.jpg)
Hello again, Frege
module Hello where
greeting :: String -> Stringgreeting name = “Hello, “ ++ name
main :: [String] -> IO ()main args = do putStrLn $ greeting “World”
public static void main(String[] args) {...}
![Page 17: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/17.jpg)
Frege の型 = Java の型?
![Page 18: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/18.jpg)
Frege によるたらい回し関数
tarai :: Int -> Int -> Int -> Inttarai x y z = if x <= y then y else tarai (tarai (x - 1) y z) (tarai (y - 1) z x) (tarai (z - 1) x y)
![Page 19: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/19.jpg)
予想される Java コード
static int tarai(int x, int y, int z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y)); }}
![Page 20: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/20.jpg)
コンパイルしてみる
![Page 21: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/21.jpg)
生成されるコードの骨子
static int tarai(int x, int y, Lazy<Integer> z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, (int)z.call(), Thunk.<Integer>lazy(x)), Thunk.<Integer>shared( (Lazy<Integer>)(() -> tarai( (int)z.call() - 1, x, Thunk.<Integer>lazy(y)))) ); }}
![Page 22: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/22.jpg)
意外と複雑だった
![Page 23: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/23.jpg)
評価戦略のマッピング
● Haskell の非正格評価を Java 上で再現
● ここで関連する要素は主に 3 つ
○ frege.run8.Lazy<T>
○ frege.run8.Box<T>
○ frege.run8.Thunk<T>
![Page 24: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/24.jpg)
frege.run8.Lazy<T>
● Callable のサブインタフェース
○ call() メソッドで値を取得
● R 型の式の評価を遅延させる
○ 役割は Supplier<R> に類似
● Frege の代数的データ型や関数は
デフォルトで Lazy の実装クラスに
![Page 25: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/25.jpg)
frege.run8.Lazy<T>
static int tarai(int x, int y, Lazy<Integer> z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, (int)z.call(), Thunk.<Integer>lazy(x)), Thunk.<Integer>shared( (Lazy<Integer>)(() -> tarai( (int)z.call() - 1, x, Thunk.<Integer>lazy(y)))) ); }}
![Page 26: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/26.jpg)
frege.run8.Lazy<T>
static int tarai(int x, int y, Lazy<Integer> z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, (int)z.call(), Thunk.<Integer>lazy(x)), Thunk.<Integer>shared( (Lazy<Integer>)(() -> tarai( (int)z.call() - 1, x, Thunk.<Integer>lazy(y)))) ); }}
![Page 27: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/27.jpg)
frege.run8.Box<T>
● Lazy の実装クラスその 1
● Thunk.<T>lazy(x) で生成
● Lazy になっていない型のラッパー
○ 役割は IntSupplier などと同様
○ call() されるとラップされている値を返す
![Page 28: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/28.jpg)
frege.run8.Box<T>
static int tarai(int x, int y, Lazy<Integer> z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, (int)z.call(), Thunk.<Integer>lazy(x)), Thunk.<Integer>shared( (Lazy<Integer>)(() -> tarai( (int)z.call() - 1, x, Thunk.<Integer>lazy(y)))) ); }}
![Page 29: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/29.jpg)
frege.run8.Box<T>
static int tarai(int x, int y, Lazy<Integer> z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, (int)z.call(), Thunk.<Integer>lazy(x)), Thunk.<Integer>shared( (Lazy<Integer>)(() -> tarai( (int)z.call() - 1, x, Thunk.<Integer>lazy(y)))) ); }}
![Page 30: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/30.jpg)
frege.run8.Thunk<T>
● Lazy の実装クラスその 2
● Thunk.<T>shared(x)で生成
● Call-by-need を実現
○ x が共有可能なら shared(x) は x を返す
○ 初めて call() されると内部に値を保持
○ 次に call() された際にはその値を返す
![Page 31: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/31.jpg)
frege.run8.Thunk<T>
static int tarai(int x, int y, Lazy<Integer> z) { if (x <= y) { return y; } else { return tarai( tarai(x - 1, y, z), tarai(y - 1, (int)z.call(), Thunk.<Integer>lazy(x)), Thunk.<Integer>shared( (Lazy<Integer>)(() -> tarai( (int)z.call() - 1, x, Thunk.<Integer>lazy(y)))) ); }}
![Page 32: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/32.jpg)
McCarthy による変種
tak :: Int -> Int -> Int -> Inttak x y z = if x <= y then z else tak (tak (x - 1) y z) (tak (y - 1) z x) (tak (z - 1) x y)
![Page 33: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/33.jpg)
McCarthy による変種
tak :: Int -> Int -> Int -> Inttak x y z = if x <= y then z else tak (tak (x - 1) y z) (tak (y - 1) z x) (tak (z - 1) x y)
![Page 34: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/34.jpg)
McCarthy 版から生成されるコード
static int tak(int x, int y, int z) { if (x <= y) { return z; } else { return tak( tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)); }}
![Page 35: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/35.jpg)
McCarthy 版から生成されるコード
static int tak(int x, int y, int z) { if (x <= y) { return z; } else { return tak( tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)); }}
![Page 36: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/36.jpg)
まとめ
● Frege は JVM のための Haskell○ 構文は Haskell そのまま
○ JVM 系ビルドツールが使用可能
● 非正格評価の Java へのマッピング
○ Lazy インタフェースによる評価の遅延
○ Box クラスによるプリミティブ型の Lazy 化
○ Thunk クラスによる結果の使いまわし
![Page 37: Frege, What a Non-strict Language](https://reader031.vdocuments.site/reader031/viewer/2022030317/586f715c1a28ab10258b4eff/html5/thumbnails/37.jpg)
Thunk You for Listening!Presented by
チェシャ猫 (@y_taka_23)