fukuoka.ex/kokura.exのpiacereです
ご覧いただいて、ありがとうございます
Advent Calendarの季節ですねっ
今年のElixir関連のAdvent Calendarは、以下3本が毎日並走するという、なんとも贅沢な状況です
- Elixir Advent Calendar 2019
- NervesJP Advent Calendar 2019
- fukuoka.ex Advent Calendar 2019
更に、「ACCESS Advent Calendar 2019」や「ミクシィグループ Advent Calendar 2019」でも、Elixirネタがポコポコ出てくるので、アルケミストにとって、毎日が豊作なXmasシーズンですね
今回のコラムは、fukuoka.ex Advent Calendar 2019の1週目に挙がっていたネタを、紹介したり、コードあるものは、手元で試していこうかな、って企画です
内容が、面白かったり、役に立ったら、「いいね」よろしくお願いします
本コラムの検証環境、事前構築のコマンド
本コラムは、以下環境で検証しています(Windowsで実施していますが、Linuxやmacでも動作する想定です)
- Windows 10
- Elixir 1.9.1 ※最新版のインストール手順はコチラ
- Phoenix 1.4.10 ※最新版のインストール手順はコチラ
1日目:GraphCMSとAbsintheでGraphQLServerを作る
@Yoosuke さんの以下コラムです
GraphCMSからAbsintheを利用して作るElixirで体験的にGraphQLSeverを作る「ポエム」
https://qiita.com/Yoosuke/items/2346137ac39715b19cde
「GaphQLとElixirが普及したら、開発者は人間力で選ばれる」と、なかなかエモい内容に期待感上昇です
yarnインストール
GraphCMSの構築には、yarnが必要(その手前にnpmが必要)です
npmをインストールするには、Node.jsを下記サイトからインストールします
https://nodejs.org/ja/download/
コンソールを起動したままだと、npmが使えないので、一度、コンソールを再起動します
その後、yarnがインストールされていない方は、Node.jsインストール後、下記コマンドでインストールしてください
npm install -g yarn
Vue.js版GraphCMSの構築/起動
コラムでは、ReactバージョンのGraphCMSを使っていますが、ココでは、下記Vue.jsバージョンで試していきます
https://github.com/GraphCMS/graphcms-examples/tree/master/current/vue-apollo-blog
Vue.js版GraphCMSを、下記コマンドで構築/起動します
git clone https://github.com/GraphCMS/graphcms-examples.git && cd graphcms-examples/current/vue-apollo-blog && yarn && yarn dev
yarn install v1.21.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.4: The platform "win32" is incompatible with this module.
info "fsevents@1.2.4" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
Done in 229.97s.
yarn run v1.21.0
$ cross-env NODE_ENV=development webpack-dev-server --inline --hot
Project is running at http://localhost:8080/
webpack output is served from /dist/
404s will fallback to /index.html
ブラウザで、http://localhost:8080/
にアクセスし、起動したGraphCMSを見てみます
GraphCMSアカウント登録、GraphCMS PJ作成
下記サイトの「SIGN UP」からサインアップ(私はGitHub連携でしました)
アカウント登録が終わると、PJ作成ページが出るので、「Start Building」をクリックして、「Create new project」をクリックします
「Name」に「Sample blog」を入力し、「Select a region」で「Asia East」を選択し、「Create」をクリックします
最後に「Personal」内の「Continue」をクリックします
さて、長くなってきたのと、元コラムが次回に続編あるため、「4. Model を作りエンドポイントを変更する」以降は、次回にまとめて書くこととします
2日目:Elixirの急所…
@kikuyuta さんの以下コラムです
言語バトル時には秘匿しておきたい Elixir の急所
https://qiita.com/kikuyuta/items/9690e0905bf4fded937b
なんとも過激なタイトルですなぁ…
…うん、Atomと「:」、除算/剰余、連結演算子(<>)は、自分も含め、多くの方が違和感を持つところですね…
パイプ(|>)も、うん、シェルのパイプ(|)でたまに打ち間違える、分かるx2(終盤の量子物理ネタちょっと吹いた)
「全部無名関数でもいいじゃん」については、Haskellから関数型を覚えた私も、まったく同じことを思ってましたし、先日、海外エンジニアに混じって登壇してきた「関数型プログラミングカンファレンス」の登壇向けスライドを作っているときも、直交性高いHaskellの関数シンタックスと比べ、「なんでElixirの無名関数ってこんなに使いづらいんだろなぁ…」と悔しい気持ちを久しぶりに思い出しました
そして、最後のオチのIO.putsが、心の叫びになってて…あぅあぅ
んま、結論として、言語バトルは「もたず、つくらず、もちこませず」ですね
3日目:Elixirを書いていると将棋が強くなる?
@torifukukaiou さんの以下コラムです
Elixirを書いていると将棋が強くなります(新しいことをはじめよう)
https://qiita.com/torifukukaiou/items/c22e6d53b43ddc25923b
解説しちゃうとネタバレにしかならないので、エモい内容と、今年のアツイElixirイベント達の紹介を、どうかコラム本体で、読み物としてお楽しみください
4日目:SIMD&GPUドライバ「Pelamay」の内部構造
@hisaway さんの以下コラムです
Elixirでコード変換してみよう
https://qiita.com/hisaway/items/9200e453c69db4c2bef0
@zacky1972 さんと @hisaway さんが作り、海外のElixirConf USでも発表された、Elixirネイティブコードコンパイラ「Pelemay」ですが、試すのは、depsでインストールするだけの簡単手順になっています
まず、適当なElixir PJを作ります
mix new pelemay_test
cd pelemay_test
mix.exsに下記Pelemayのdepsを追加します
defmodule PelemayTest.MixProject do
…
defp deps do
[
{:pelemay, "~> 0.0"}, # <-add here
]
end
…
インストールします
mix deps.get
pelemay_test.exの中身を下記のようにPelemayを呼ぶコードに書き換えます
なお、map_square_originalは、Pelemayを呼ぶコードと等価なPelemayを呼ばないElixirコードです
defmodule PelemayTest do
def map_square_original( list ) do
list
|> Enum.map( & &1 * &1 )
end
require Pelemay
import Pelemay
defpelemay do
def map_square( list ) do
list
|> Enum.map( & &1 * &1 )
end
end
end
コンパイルして、iex起動します
mix compile
iex -S mix
iex内で、上記で作ったPelemayを呼ぶコードと、を実行します
iex> PelemayTest.map_square( [ 1, 2, 3 ] )
[1, 4, 9]
iex> PelemayTest.map_square_original( [ 1, 2, 3 ] )
[1, 4, 9]
こんな小さなサンプルだと、Pelemayの威力は実感できないので、もっと大きな計算をさせ、比較してみましょう
計測に、:timer.tcを噛ませてみます
iex> :timer.tc( fn -> PelemayTest.map_square( 1..10000000 ) end )
{235000,
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324,
361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089,
1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116,
2209, 2304, ...]}
iex> :timer.tc( fn -> PelemayTest.map_square_original( 1..10000000 ) end )
{907000,
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324,
361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089,
1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116,
2209, 2304, ...]}```
10万件の計算では、Elixirコードの3.8倍、Pelemayによるネイティブコードが性能が良かったです
では、100万件では、どうでしょう?
iex> :timer.tc( fn -> PelemayTest.map_square( 1..100000000 ) end )
{17891000,
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324,
361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089,
1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116,
2209, 2304, ...]}
iex> :timer.tc( fn -> PelemayTest.map_square_original( 1..100000000 ) end )
{170125000,
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324,
361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089,
1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116,
2209, 2304, ...]}
ナントElixirコードの9.5倍も、Pelemayによるネイティブコードが高速であることが分かります
これだけの性能差が出ると、作れるものの次元が変わってくる…特にデータサイエンス方面では…ということが実感できるかと思います
コラム自体は、このPelamayの内部構造について解説したものなので、ネイティブコードコンパイラやドライバー開発に興味あったり、Pelemayの開発に参加してみたいという方は、どうぞご覧ください
5日目:ElixirでMQTTクライアント
@tuchiro さんの以下コラムです
Elixir製MQTTクライアントtortoiseを使ってみた
https://qiita.com/tuchiro/items/e7fb5185f4ac191b94b5
「Tortoise」は、ElixirのMQTTクライアントで、AWS IoTに繋いでPubSubが簡単にできるようになります
https://github.com/gausby/tortoise
適当なElixir PJで試してみます
mix new mqtt_test
cd mqtt_test
mix.exsに下記Pelemayのdepsを追加します
defmodule MqttTest.MixProject do
…
defp deps do
[
{:tortoise, "~> 0.9"}, # <-add here
]
end
…
インストールします
mix deps.get
…と、手元にMQTT使える環境が無いことに気付いたので、続きはまた今度、スミマセン
お手元に環境ある方は、コラム読みながら、お試しくださいませ
6日目:Prologコンパイラを作る
@sym_num さんの以下コラムです
ElixirでPrologコンパイラを作ったお話
https://qiita.com/sym_num/items/b64e63d5b27ed298f41b
「Prolog」とは、Elixirを始めとする「関数型言語」と双璧をなす「論理型言語」の代表で、この2つをまとめて「宣言型言語」と呼びます
コラム終盤に出てくる「渕先生」とは、かつて日本が国家予算570億円を投じ、さまざまな功績と波乱を呼んだ37年前の国家PJ「第五世代コンピュータ開発」を指揮した渕一博先生のことで、このPJの成果物には、Prolog由来の並行論理言語「KL1」があります
さてそんな昔話はさておき、GitHubに、このPrologインタプリタ/コンパイラがアップされていたので、コチラを試してみます
https://github.com/sasagawa888/Elxlog
上記レポジトリをgit cloneで落としてきたら、下記でビルド/実行できます
git clone https://github.com/sasagawa888/Elxlog
cd Elxlog
mix elxlog
無事、起動すると、こんな感じで、Prologプロンプトが出てきます
Elxlog ver0.14
?-
早速、Prologをコーディングしてみましょう
リストの先頭にマッチ条件を書いて、検索してみます
?- member(piacere, [piacere, zacky, tuchiro, enpedasi, hideki, koga]).
true
?- member(hoge, [piacere, zacky, tuchiro, enpedasi, hideki, koga]).
false
おー、動いた、動いた
ジェネレータ表記も効くかな?
リストの先頭に変数を置くと、リストを巡回しながら、非決定性マッチができます(次を巡回するときは「;」を打ちます)
?- member(X, [piacere, zacky, tuchiro, enpedasi, hideki, koga]).
X = piacere;
X = zacky;
X = tuchiro
true
おー、出来た、出来た、ホンマPrologやー
他にも、外部ソースコードを読み込んだり、このREPLによるインタプリタ実行だけで無く、コンパイルもできたり、Elixirで動かすPrologならではの並行実行もできるので、元コラムと、Elxlog GitHubのREADME.mdを見ながら、色々遊んでみてください
7日目:Broadwayでのデータパイプライン作成
@koga1020 さんの以下コラムです
Broadwayを使ってデータ処理パイプラインを構築する
https://www.koga1020.com/posts/using-broadway
José Valimが作った「Broadway」というライブラリを使うと、このオレンジ色の部分みたいに、データから抽出した特定の値に応じて処理をスイッチする…なんてことが、パイプ中でいとも容易く可能になります
コチラのコラムは、昨日夜アップされたばかりで、未だ試し切れていない※ので、皆さんもご一緒に試してみましょー
※Broadway自体は、今年3月のファーストリリース時に個人的に試してはいます
終わり
今年のfukuoka.ex Advent Calendarの1週目を読んで、手元で試せるものは試してみました
Advent Calendarって、「なんか面白いね」で終わってしまうことが多いと思いますが、実際に試してみると、いろいろな発見があり、勉強になりますのでオススメです
それにしても、毎度のことながら、fukuoka.exのカオスなテイストがタップリと出たカレンダーでしたね
p.s.「いいね」よろしくお願いします
ページ左上のや
のクリックを、どうぞよろしくお願いします
ここの数字が増えると、書き手としては「ウケている」という感覚が得られ、連載を更に進化させていくモチベーションになりますので、もっとElixirネタを見たいというあなた、私達と一緒に盛り上げてください!