GleamプロジェクトからElixirパッケージを呼び出してみる
GleamプロジェクトからElixirパッケージを呼び出してみる
以前にこんな記事を書きました。
上記の記事ではmix_gleamというパッケージを使い、ElixirプロジェクトにGleamプロジェクトを作成し、GleamとElixirで相互に呼び出しあうというものでした。
この連携方法はElixirをプロジェクトの主体として使用しているプロジェクトにおいて、コードの一部にGleamを使用する際に効果を発揮します。
例えば「Phoenixフレームワークで構築されているWebアプリのコントローラーにGleamを使用する」などが挙げられます。
この記事ではGleamプロジェクトからElixirのライブラリを呼び出す方法を解説していきます。
プロジェクトの用意
これは通常のプロジェクトと同じです。
今回はElixirのFlowという並列計算ライブラリを使ってみます。
Flowについて
gleam new my_package
cd my_package
次にFlowを追加していきます。
gleam add flow
gleam add
コマンドはhex.pm上にあるパッケージをインストールすることが出来ます。
このコマンドを用いてインストールされたパッケージは、Gleam以外の言語で書かれていても実行時又はビルト時に自動的にコンパイルされます。(もちろん対応している処理系は必要になります。)
GleamからElixirライブラリの関数を呼び出してみる
ここからはGleamからFlowの関数を呼び出してみます。
始めに与えられたリストを2倍にする処理を書いてみます。
Elixirだとこうなります。
1..1000
|> Flow.from_enumerable
|> Flow.map(fn x -> x * 2 end)
|> Enum.to_list
次にGleamで書いてみます。
まずFlowの関数を呼び出せるよう、@external
を使ってFlowの関数を呼び出せるようにしてみます。
@external(erlang, "Elixir.Flow", "from_enumerable")
fn flow_from_enumerable(list: List(Int), a, Int) -> List(Int)
@external(erlang, "Elixir.Flow", "map")
fn flow_map(list: List(Int), fun: fn(a) -> Int) -> List(Int)
@external(erlang, "Elixir.Enum", "to_list")
fn elixir_enum_to_list(list: List(Int)) -> List(Int)
@external
の使い方については前回の記事を参照してください。
次に@externalの関数を呼び出してみます。
今回はgleam標準ライブラリのiteratorを使ってみます。
このライブラリは遅延評価される[1]シーケンスを定義していて、大きなリスト等を操作するのに便利です。
import gleam/io
import gleam/iterator
pub fn main() {
iterator.range(1, 100)
|> iterator.to_list
|> flow_from_enumerable
|> flow_map(fn(x) { x * 2 })
|> elixir_enum_to_list
|> io.debug // [2, 4, 6, ..., 200]
}
このようにgleam add
でパッケージを追加して@external
で呼び出すことで、Gleamから既存のBEAMエコシステムのパッケージを呼び出すことが出来ます。
余談
前回の記事で外部呼び出しについてあらかた解説してしまったので、今回の記事はあっさりとした解説になりました。
Gleamのパッケージも増えてきてはいますが、まだまだライブラリの数が少ないと感じているので、適宜BEAMのエコシステムに頼ってプログラムを書いていくのがオススメです。
参考文献
-
gleam shell
で呼び出してみると関数オブジェクトを持っているオブジェクトが返されることからも、遅延評価していることが確認出来ます。 ↩︎
Discussion