🦊

GleamプロジェクトからElixirパッケージを呼び出してみる

2024/03/20に公開

GleamプロジェクトからElixirパッケージを呼び出してみる

以前にこんな記事を書きました。

https://zenn.dev/comamoca/articles/interop-of-gleam-and-elixir

上記の記事ではmix_gleamというパッケージを使い、ElixirプロジェクトにGleamプロジェクトを作成し、GleamとElixirで相互に呼び出しあうというものでした。
この連携方法はElixirをプロジェクトの主体として使用しているプロジェクトにおいて、コードの一部にGleamを使用する際に効果を発揮します。

例えば「Phoenixフレームワークで構築されているWebアプリのコントローラーにGleamを使用する」などが挙げられます。

この記事ではGleamプロジェクトからElixirのライブラリを呼び出す方法を解説していきます。

プロジェクトの用意

これは通常のプロジェクトと同じです。
今回はElixirのFlowという並列計算ライブラリを使ってみます。

Flowについて

FlowというライブラリはElixirのGenStageというライブラリをラップするかたちで構築されています。

Flowを使うことで並列処理や分散処理を伴う計算処理をパイプとして直感的に記述できます。

FlowやGenStageのようなライブラリは他にもあって、例えばBroadwayなんかが挙げられます。

  • GenStageに関する資料はこちら
  • 他のGenStageを用いたライブラリはこちら

から見ることが出来ます。

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のエコシステムに頼ってプログラムを書いていくのがオススメです。

参考文献

https://qiita.com/shufo/items/59d1c3b0baac6751777f

脚注
  1. gleam shellで呼び出してみると関数オブジェクトを持っているオブジェクトが返されることからも、遅延評価していることが確認出来ます。 ↩︎

GitHubで編集を提案

Discussion