Slide 1

Slide 1 text

最強JVM系関数型 論理プログラミング言語、 その名は Flix 第五関数型プログラミング(仮)の会 2024-01-26 The Flix Programming Language knih

Slide 2

Slide 2 text

最強JVM系関数型 論理プログラミング言語、 その名は Flix 第五関数型プログラミング(仮)の会 2024-01-26 The Flix Programming Language knih 注:個人主観

Slide 3

Slide 3 text

3 The Flix Programming Language Next-generation reliable, safe, concise, and functional-first programming language.

Slide 4

Slide 4 text

4 Flix ● 中心的な開発者はオーフス大学のMagnus Madsen先生 https://cs.au.dk/~magnusm/ 開発にはOSSコミュニティや研究者らが関わっている ● Aarhus University(デンマーク) ● the University of Waterloo(カナダ) ● the University of Tübingen(ドイツ) ● the University of Copenhagen(デンマーク)

Slide 5

Slide 5 text

5 Flixのなにがすごいの?

Slide 6

Slide 6 text

バランスがすごい 6 代数的データ型はもちろん、拡張可能レコードや高階カインド、多相エフェクト、はたまたDatalogもサポート Flix aims to offer a unique combination of features that no other programming language “


Slide 7

Slide 7 text

Flixが提供する代表機能 7 拡張可能レコードと多相エフェクトが!!!!! 拡張可能レコード トレイト(型クラス) 高階カインド JVMバイトコードへのコンパイル 多相エフェクトシステム region-based local mutation Purity reflection 第一級Datalog constraint 多言語にある特徴 ユニークな機能 これ以外にもおもしろ機能がたくさん

Slide 8

Slide 8 text

Hello WorldからみるFlix 8 def main(): Unit \ IO = println("Hello World!") 戻りの型 エフェクト def main(): String \ {} = "Hello World!" def main(): String = "Hello World!" エフェクトがないので Emptyになる エフェクトがない場合 は省略できる

Slide 9

Slide 9 text

もちろんある、代数的データ型 9 enum Shape { case Circle(Int32), case Square(Int32), case Rectangle(Int32, Int32) } def area(s: Shape): Int32 = match s { case Shape.Circle(r) => 3 * (r * r) case Shape.Square(w) => w * w case Shape.Rectangle(h, w) => h * w } def main(): Unit \ IO = println(area(Shape.Rectangle(2, 4)))

Slide 10

Slide 10 text

レコード 10 let p1 = { x = 1, y = 2 }; let p2 = { x = 3 | p1 }; p1.x + p2.x def f(r: {x = Int32, y = Int32}): Int32 = r.x + r.y def g(r: {x = Int32, y = Int32 | s}): Int32 = r.x + r.y g({x=1,y=2,z=3})

Slide 11

Slide 11 text

レコード 11 def withAccountId(r: {| a}, aid: AccountId): {id = AccountId | a} = {+accountId=aid | r} def withoutName(r: {name = String | a}): {| a} = {-name | r}

Slide 12

Slide 12 text

オブジェクト指向の機能を取り入れていない 12 Flixでは、これまでとは違う方向性で、まっさらな 状態から始めたいと思いました。私の経験では、 Scalaでの関数型プログラミングは、Scalaの型推論 の制限により、時に面倒に感じることがあります。 さらに重要なことに、オブジェクト指向プログラミ ングは間違った方向に進んでいると確信することが 多くなりました。特にオブジェクト指向の古典的な 特徴(あるいは価値)である、オブジェクトの同一 性、変更可能な状態、クラス継承は、プログラムを 構成し考えるための正しい方法ではないと私は感じ ています。 “
 Johan Janssen (2022). Interview with Magnus Madsen about the Flix Programming Language. InfoQ. https://www.infoq.com/news/2022/02/flix-programming-language/

Slide 13

Slide 13 text

Region-based Local Mutation 局所的に破壊的変更ができる!パフォーマンスのいいプログラムが安全に書ける! 13 def toString(someList: List[a]): String with ToString[a] = region r { let sb = StringBuilder.new(r); foreach (x <- someList) { StringBuilder.appendString!("${x} :: ", sb) }; StringBuilder.appendString!("Nil", sb); StringBuilder.toString(sb) }

Slide 14

Slide 14 text

多相エフェクト mapのなかで副作用を起こしてしまう問題もこれで安心 14 def map(f: a -> b \ eff, xs: List[a]): List[b] \ eff = match l { case Nil => Nil case x :: xs => f(x) :: map(f, xs) }

Slide 15

Slide 15 text

型クラスの自動導出も便利 15 enum Month with Eq, Order, ToString { case January case February case March case April case May case June case July case August case September case October case November case December }

Slide 16

Slide 16 text

高階カインド 16 trait ForEach[t: Type -> Type] { pub def forEach(f: a -> Unit \ ef, x: t[a]): Unit \ ef } instance ForEach[List] { pub def forEach(f: a -> Unit \ ef, l: List[a]): Unit \ ef = match l { case Nil => () case x :: xs => f(x); ForEach.forEach(f, xs) } }

Slide 17

Slide 17 text

forM, forA 17 def validateUsername(name: String): Validation[Err, UserName] = ... def validateJobType(jobType: String): Validation[Err, JobType] = ... def createAccount(n: UserName, j: JobType): Validation[Err, Account] = forA ( name <- validateUsername(n); jobType <- validateJobType(j) ) yield Account(name, jobType)

Slide 18

Slide 18 text

第一級 Datalog constraint 18 def main(): Unit \ IO = let facts = #{ Interpreter("x86"). Compiler("Scala", "x86", "MiniScala"). Compiler("MiniScala", "C++", "C++"). Compiler("C++", "x86", "x86"). }; let rules = #{ Compiler(src1, dst1, dst2) :- Compiler(src1, dst1, lang1), Compiler(lang1, dst2, lang2), Interpreter(lang2). Compiler(src, dst, lang) :- Compiler(src, intermediate, lang), Compiler(intermediate, dst, lang), Interpreter(lang). }; query facts, rules select (src, dst) from Compiler(src, _, dst) |> println

Slide 19

Slide 19 text

第一級 Datalog constraint 19 def main(): Unit \ IO = let facts = #{ Interpreter("x86"). Compiler("Scala", "x86", "MiniScala"). Compiler("MiniScala", "C++", "C++"). Compiler("C++", "x86", "x86"). }; let rules = #{ Compiler(src1, dst1, dst2) :- Compiler(src1, dst1, lang1), Compiler(lang1, dst2, lang2), Interpreter(lang2). Compiler(src, dst, lang) :- Compiler(src, intermediate, lang), Compiler(intermediate, dst, lang), Interpreter(lang). }; query facts, rules select (src, dst) from Compiler(src, _, dst) |> println Vector#{ (C++, x86), (MiniScala, C++), (MiniScala, x86), (Scala, C++), (Scala, MiniScala), (Scala, x86) }

Slide 20

Slide 20 text

20 Flixの思想がすごい

Slide 21

Slide 21 text

Flixの思想(一部) 21 ● No NULL ● No reflection ● すべては式 ● ヒューマンリーダブルなエラー ● 暗黙の強制(coercion)をしない ● 純粋コードと不純(impure)コードを分離 ● コンパイル結果にWarningはない、エラーのみ ● 未使用の変数なし ● 不要な宣言は不要 ● グローバル状態なし ● 構文の一貫性

Slide 22

Slide 22 text

22 Flixのおもしろ機能

Slide 23

Slide 23 text

bug? 23 match userAccount { case RegularAccount(v) => doSomething(v) case SpecialAccount(v,tag) => bug!("The value of inputValue cannot be empty. tag: " + a) }

Slide 24

Slide 24 text

24 Flixをローカルで

Slide 25

Slide 25 text

ローカルでflix 25 ~/tmp/flix via ☕ v17.0.9 took 7s ❯ java -jar ./flix.jar init Creating '/tmp/flix/src'. Creating '/tmp/flix/test'. Creating '/tmp/flix/flix.toml'. Creating '/tmp/flix/.gitignore'. Creating '/tmp/flix/LICENSE.md'. Creating '/tmp/flix/README.md'. Creating '/tmp/flix/src/Main.flix'. Creating '/tmp/flix/test/TestMain.flix'. 用意するもの ● java 21 ● flix.jar ○ https://github.com/flix/flix/releases ❯ java -jar ./flix.jar run Found `flix.toml'. Checking dependencies... Resolving Flix dependencies... Downloading Flix dependencies... Resolving Maven dependencies... Running Maven dependency resolver. Downloading external jar dependencies... Dependency resolution completed. Hello World!