Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Frege, What a Non-strict Language

2 448 vues

Publié le

NL 名古屋の発表スライドです。Haskell ライクな JVM 言語 Frege を題材に、非正格な評価戦略を Java 上で実現する方法について解説します。なお、スライド中に登場するサンプルコードの詳細は、ブログ記事 http://ccvanishing.hateblo.jp/entry/2016/04/17/201842 を参照のこと。

Publié dans : Technologie
  • Identifiez-vous pour voir les commentaires

Frege, What a Non-strict Language

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

×