BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース プログラミング言語Flixに関するMagnus Madsen氏へのインタビュー

プログラミング言語Flixに関するMagnus Madsen氏へのインタビュー

原文(投稿日:2022/02/25)へのリンク

Flixは多くのプログラミング言語にインスパイアされたオープンソースのプログラミング言語であり、開発者は関数型、命令型、論理型のスタイルでコードを書くことが可能である。FlixはScalaに似ており、Hindley-Milnerに基づく型システムとGoにインスパイアされた並行処理モデルを採用している。JVM言語はポリモーフィックエフェクトシステムやDatalog制約などのユニークな機能をサポートしている。

FlixのプログラムはJVMバイトコードにコンパイルされ、開発者はFlix Visual Studio Code拡張機能を使用するか、online playgroundを使用して言語を評価することができる。

コミュニティはいくつかの原則に基づいて言語を開発している。例えば、NULL値を使わない、デフォルトでprivate、リフレクションを使わない、pureとimpureなコードの分離、パフォーマンスよりも正確さ、グローバル状態無し、などである。

以下のmain関数は、println関数が副作用を持つためimpureとみなされる。Flixコンパイラはそれぞれの式の純度を記録し、pureな式が副作用を持たないことを保証している。

def main(_args:Array[String]):Int32 & Impure =
    println("Hello world!");
    0 // exit code

Flix言語はポリモーフィックエフェクトをサポートしており、純粋な関数型プログラムと副作用を持つプログラムとを区別することができる。関数はデフォルトでpureだが、明示的にpureとマークすることもできる。

def add(x:Int32, y:Int32):Int32 & Pure  =
    x + y;

副作用のある関数は、impureとして明示的にマークすることができる。

def main(_args:Array[String]):Int32 & Impure =
println(add(21, 21));
0 // exit code

コンパイラは、明示的にマークされたpure関数で副作用が使用された場合、impure関数がpureとして宣言されているというエラーを表示する。

def add(x:Int32, y:Int32):Int32 & Pure  =
    x + y;
    println("Hello")

pureとimpureのコードを分離することで、開発者はpure関数について、副作用のない数学的な関数のように推論することができる。

宣言型論理プログラミング言語であるDatalogは、SQLのようなクエリ言語と見なせるかもしれないが、より高度なものである。FlixはDatalogを第一級市民としてサポートしており、Datalogの制約を関数の引数として使用したり、関数から返したり、データ構造に格納したりすることができる。FlixはDatalogと一緒に使って、先祖を決定するような不動点問題を表すことができる。

def getParents():#{ ParentOf(String, String) | r } = #{
    ParentOf("Mother", "GrandMother").
    ParentOf("Granddaughter", "Mother").
    ParentOf("Grandson", "Mother").
}

def withAncestors():#{ ParentOf(String, String),
                        AncestorOf(String, String) | r } = #{
    AncestorOf(x, y) :- ParentOf(x, y).
    AncestorOf(x, z) :- AncestorOf(x, y), AncestorOf(y, z).
}

def main(_args:Array[String]):Int32 & Impure =
    query getParents(), withAncestors()
        select (x, y) from AncestorOf(x, y) |> println;
    0

これにより、以下の結果が表示される。

[(Granddaughter, GrandMother), (Granddaughter, Mother),
    (Grandson, GrandMother), (Grandson, Mother), (Mother, GrandMother)]

Flixは、タプルとレコードに加え、代数的なデータ型とパターンマッチングのサポートを提供している。

enum Shape {
    case Circle(Int32),          // circle radius
    case Square(Int32),          // side length
    case Rectangle(Int32, Int32) // height and width
}

def area(s:Shape):Int32 = match s {
    case Circle(r)       => 3 * (r * r)
    case Square(w)       => w * w
    case Rectangle(h, w) => h * w
}

def main(_args:Array[String]):Int32 & Impure =
    println(area(Rectangle(2, 4)));
    0 // exit code

GitHubのリポジトリでは、さまざまな機能に関するより多くのを提供している。

InfoQはデンマークのオーフス大学コンピューターサイエンス学部助教授で、プログラミング言語Flixの設計・開発責任者であるMagnus Madsen氏に話を伺った。

InfoQ:Flixを作ろうと思ったきっかけは何ですか?

Madsen氏:プログラミング言語の世界で、何かが欠けていると感じていました。それは、主に関数型言語でありながら、命令型プログラミングを完全にサポートし、さらに論理プログラミングのひねりを加えた言語です。OCaml、Haskell、Scalaの最高のアイデアを取り入れた、デザイン空間におけるユニークなポイントにある言語です。

私は、明確に表現されたアイデアと設計目標の理念に基づいた新しい言語を求めていました。単なる機能の寄せ集めではありません。私の考えでは、言語は万人のすべてになろうとするべきではありません。いくつかのコアとなるアイデアに集中し、それを得意とする方が良いのです。個人的には、代数的なデータ型、パターンマッチ、高階関数など、関数型プログラミングの強力な機能を備えた、使うのが楽しくなるような言語が欲しかったのです。

InfoQ:FlixはScalaからどの程度影響を受けているのでしょうか?

Madsen氏:Flixは、Haskell、OCaml、そしてScalaから多くのインスピレーションを受けています。私たちは、これらの言語の強固なアイデアの上に、それらを超えるものを構築したいと考えています。Flixの文法はScalaからヒントを得ています。つまり、キーワードと中括弧をベースにしており、多くのScalaプログラマーにとってすぐに馴染みのあるものになるでしょう。Flixの型システムは、OCamlやHaskellと同じHindley-Milnerをベースにしています。Flixには型推論機能があり、関数内で常に正しい型が推論されます。Scalaにはクラスとオブジェクトがありますが、FlixにはHaskellから借用した型クラスがあります。また、Scalaはimplicitに基づく型クラスの形式をとっています。Flixの型クラスはHaskellの型クラスに近く、型推論との統合もしやすいものです。

InfoQ:なぜScalaに機能を追加するのではなく、新しい言語を作るのですか?

Madsen氏:Scalaは、Javaとの優れた相互運用性を維持しながら、関数型プログラミングとオブジェクト指向プログラミングの境界を押し広げた、優れたプログラミング言語です。

Flixでは、これまでとは違う方向性で、まっさらな状態から始めたいと思いました。私の経験では、Scalaでの関数型プログラミングは、Scalaの型推論の制限により、時に面倒に感じることがあります。さらに重要なことに、オブジェクト指向プログラミングは間違った方向に進んでいると確信することが多くなりました。特にオブジェクト指向の古典的な特徴(あるいは価値)である、オブジェクトの同一性、変更可能な状態、クラス継承は、プログラムを構成し考えるための正しい方法ではないと私は感じています。

当時も今も、静的な型システムを持つプログラミング言語は、その多くの利点にもかかわらず、退潮していると感じています。特に大規模なソフトウェア開発では、JavaScriptとPythonしかない未来を恐れていました。しかしこれらの言語が魅力的なのは、その柔軟性と形式張っていないことだと認識しています。このことから、将来のプログラミング言語は、型推論を伴う表現力豊かな型システムに大きく投資する必要があると結論づけました。それにより静的型システムの利点、例えば型安全性やオートコンプリートやリファクタリングのための優れたツールサポートを維持しながら、同じ柔軟性を持つことができるのです。しかし残念なことに、型推論とサブタイピングは相性が悪いです。

このような理由から、Flixはオブジェクト指向ではないのです。とはいえFlixは、ミュータブルデータやレコードを用いた命令型プログラミングなど、プログラマがOOPから連想する多くの機能をサポートしています。

InfoQ:Flixが追加した言語機能の中で、最も重要だと思うものは何でしょうか?

Madsen氏:私たちは今も積極的にFlixの開発を進めていますが、現時点で他のプログラミング言語にはない独自の機能を3つ挙げることができます。

Flixはpureとimpureなコードを分離する型とエフェクトシステムを持っています。Flixではすべての式は、pure、impure、ポリモーフィックエフェクトのいずれかです。pureな式はいかなる副作用も持つことができず、その評価は常に同じ結果を返します。これはコンパイラによって強制される鉄壁の保証です。impureな式は副作用を持つ可能性があります。最後に、最も興味深いことに、ある種の式では、その純度は他の式の純度に依存します。例えば、List.mapの呼び出しでは、List.mapの引数関数がpureであれば、式全体がpureとなります。このような関数はポリモーフィックエフェクトとみなされます。

Flixプログラマ(通常はFlixライブラリ作成者)は型とエフェクトシステムを使って、効果を考慮した関数を書くことができます。これはメタプログラミングの一種で、高階関数(例えば Set.count)がその関数の引数の純度を反映できるようにするものです。この知識により、自動的な遅延評価や並列評価をサポートすることができます。例えば、Flix標準ライブラリでは、Set.count関数は純粋な関数を渡されると並列に実行され、不純な関数を渡されると順次に実行されるようになっています。

FlixはファーストクラスのDatalog制約をサポートしています。Datalogは論理プログラミング言語ですが、SQLのようなクエリ言語と考えることができます - が、より強靭なものです。どんなSQLクエリでもDatalogで表現するのは簡単ですが、Datalogではグラフに対してより複雑なクエリを書くことができます。例えば、2行のDatalogプログラムを使用して、道路網の中の2つの都市間の最短距離を計算することができます。いくつかのORMとは異なり、Datalogの統合はシームレスです。文字列の構築やデータ型のマッピングのような面倒なことはありません。DatalogのクエリはFlixと同じデータ型を使用します。最後に、Datalogはやみくもに使うべきではありませんが、いくつかの計算問題では本当に超強力な兵器です。

InfoQ:Flixはどのようなアプリケーションに特に適していると考えていますか?

Madsen氏:私たちは、Flixを汎用的なプログラミング言語として設計しています。Java、Kotlin、Scala、OCaml、Haskellを使うような場所でFlixを使うことができます。私たちは 「batteries included:バッテリー同梱」のアプローチをとっており、Flixの標準ライブラリは現在3万行以上のコードと2,000以上の関数から構成されています。もし標準ライブラリの機能が不足しても、プログラマはいつでもJavaライブラリや外部JARに頼ることができます。正しさと安定性にはかなり気を遣っています。特に、Flixのコンパイラと標準ライブラリは、12,500以上の手書きのユニットテストを行っています。また、APIドキュメント、ウェブサイト、「Programming Flix」マニュアル、言語サーバプロトコルの大部分を実装したVisual Studio Code拡張機能が用意されています。さらに、新進気鋭のパッケージマネージャもあります。

InfoQ:Flixの当面の目標は何でしょうか、また現在のコミュニティの規模は?

Madsen氏:Madsen氏:現時点では、言語そのもの、コンパイラ、標準ライブラリ、ドキュメントなど、アーリーアダプターのための準備が整った段階です。私たちはソフトウェア開発者がFlixを使い始めることを望んでおり、Gitter channelを通じて支援を提供する準備が整っています。反復し、前進するために、私達は設計に関するフィードバックを求めています。Flixはすでにいくつかの企業で実運用されています。私たちはこの数を劇的に増やしたいと思っています。

現在、5〜8人ほどのプログラマがFlixの開発に積極的に取り組んでいます。プログラミング言語の研究者が2人、博士課程の学生が1人、学生プログラマが2人、そしてオープンソースのコントリビューターが数人います。

Flixプロジェクトは、約6年ちょっとの歴史があります。ほとんどの活動は直近の2年間に起こりました。Flixコンパイラ・プロジェクトは、40人以上の開発者から提供された約17万行のコードで構成されています。

InfoQ:Flixの言語機能の中で一番気に入っているものは何ですか?

Madsen氏:個人的には、代数的なデータ型、パターンマッチング、関数を使ったプログラミングがとても好きです。Flixの簡潔なシンタックスと型推論を使えば、これらの機能を使ったプログラムを簡単に書くことができます。必要なときに、他のプログラムの機能的な純粋さを損なうことなく、面倒な命令形のコードを書くことができるのは便利ですね。エフェクトシステムは、私のコードをpureとimpureな部分に分けて構造化するのを助けてくれます。通常、コアとなる計算はpureで、その周りのものは外界(例えばファイル等)を扱います。型シグネチャは、引数や戻り値の型、必要な型クラスのインスタンス、関数がpureかimpureかなど、関数について知る必要があることをほぼ全て教えてくれるのが気に入っています。最後に、Visual Studio Codeの拡張機能はまだ完璧ではありませんが、本物のFlixコンパイラを使用しているため、快適に使用することができます。

InfoQ:Flixのどのような部分を改善したいですか?

Madsen氏:この1年間で、言語、コンパイラ、標準ライブラリに磨きをかけ、大きな進歩を遂げました。Flixはすぐにでも使える状態ですが、まだ改善したい部分がいくつかあります。

Flixの型とエフェクトシステムを拡張し、関数がpureなままローカルミューテーションを使用できるようにしたいと考えています。例えば、内部的にはミュータブルな配列を使用してインプレースソートを行うが、外部からはpureな関数として見えるソート関数を想像してみてください。

ファイルI/O、OSとの連携、ネットワーク、JSONなどの構文解析をJavaのライブラリに依存することなくサポートし、標準ライブラリを拡張したいです。

さらに、Javaとの相互運用性をあまり犠牲にすることなく向上させたいと考えています。

InfoQ:既に決まっているFlixの今後の方向性について、何かお聞かせいただけますか?

Madsen氏:私たちは、約束は控えめにして結果は期待以上にすることを目指しています。今ある機能、すぐに使える機能について話すことを優先しています。とはいえFlixは最近、Amazon ScienceDIRECから、型とエフェクトシステムの表現力を高めるための研究資金を獲得しているので、それがヒントになるかもしれませんね

Madsen氏は、Bruce Eckel氏とJames Ward氏によるHappy Path ProgrammingポッドキャストのセッションDesigning a principled programming languageで、さらなる洞察を示している。

作者について

この記事に星をつける

おすすめ度
スタイル

BT