[Elixir]format syntax automatically

https://github.com/elixir-lang/elixir/pull/6639/files has been merged to master, and Elixir lang support formatting feature by default.

The following library is my experimental place and I’ve adapted the formatter to the library is create a pull-request.
https://github.com/KazuCocoa/http_proxy/pull/43/files

Advertisements

[Elixir]read “Craft GraphQL APIs in Elixir with Absinthe”

Craft GraphQL APIs in Elixir with Absintheを読んだ。Amazonからはこちらから購入可能になる予定らしい。

Beta配信されて購入できるようになったので、GraphQLを学ぶことも含めて購入、読み進めてみた。GraphQLは、ざっと情報を巷のBlogなどで見ているが、実際にサンプルアプリ以外でコードを書いてWebアプリを開発したことはない状態。

はじめにGraphQLの簡単な話があったのち、ElixirのAbsintheを題材にしてGraphQLを実際に作り、実装してみるという流れ。これにより、GraphQLのクエリの形や仕様を学びながら、実際のツールの使い方を学ぶことができる。この書籍を書いているBruce Williams氏とBen Wilson氏は実際にGraphQLを使いプロダクションの開発を行なっているらしく、その知見も少し味わうことができる。

デフォルトではAnsintheはこのブラウザツールが有効になっている状態で開発を行うことができる。一方、プロダクション向けには interface :simple という形式を router.ex などに指定すると良い。なお、本書ではAnsintheはPhoenixフレームワークを題材として、提供されるサンプルコードもそれを使っているがAnsinthe自体はPlugなど含めて別にPhoenixに限ったフレームワークではない。

GraphQL関係の他には、以下のようにパターンマッチを使うことができると知らず、本書でできるとしったことがよかった。新たな知見 🙂

# define `fn` with some pattern matching
f = fn
  1 -> 1
  2 -> 2
end

# Pattern match
f.(1) # 1
f.(2) # 2

ともあれ、ざっとGraphQLの概要を知りたいとかだけだとこの書籍は不要そう。実際にElixirを使いながら学ぶという形には良い。実際のサンプルコードもあり、そのコードはドキュメントなども豊富なので、コードリーディングの良い題材にもなると思う。

read “Learn Functional Programming with Elixir”

少し気になっていたLearn Functional Programming with Elixirがβ公開されたので、気になって読んでみた。

内容自体はすでになんらかのElixir本を学んでいると特に目新しいものにはでくわさないと思う内容だった。ただ、7、8章の Design Your Elixir Applications, Handle Impure Functions はまだ公開されていないが、この箇所は少し雰囲気がElixirの説明から実際のアプリケーションに話が寄っている感じがしている。

内容として、高級関数の他に、末尾最適化の話も触れていたし、そこは実際のプロセスモニタリングしながらmemory消費の優位性を明記していたところが良かった。

あとはeager/lazy関数のことも言及していて、以下のような無名関数を使い、lazyな関数宣言を適切にモジュール内で使っていたリファクタリングの話なんかは、少し新鮮で面白かった。

a = fn x -> IO.puts x end
a.(1) # 1, :ok

あと、 :ok, :error で結果を出し分ける言語文化(from Erlang)の話も触れていたり、コラムもほどほどに詳しいところに踏み込んでいて良かった。

最初の一冊よりは、少しチュートリアルをやった後にElixirらしい記述をするためのとっかかりとして学ぶとか、そういう書籍っぽい。

Read “Functional Programming: A PragPub Anthology”

Functional Programming: A PragPub Anthology を読んだ。まだβだったけれど、内容はだいぶまとまっててあとは微調整して発売という感じを受けた。

The Functional Paradigmから入り、Scala、Clojure、Elixir、Haskell、Swiftと関数型というテーマに絡めたそれぞれの言語の特性に触れながら話は進む。それらがひととおおり終わり、考え方を経験した後、Going Deeperということでそれらを再び題材に、より言語毎の特性、テスト(コード)の話、タイプシステム、The DCI architecture、そしてLuaと理解を深めていく。

この書籍をまるっと読むと、いくつかの言語から関数型言語、関数型な考え方に触れ、それらを学ぶことができる。さらには軽くそれらに触れることで、いわゆる写経もやりながら理解を深めることができるので、とっかかりとしても有用な内容だった。特に前半は、その言語に触れたことがある人からすると読み物的な内容に見えるので、考え方を整理するという形で触れることができると思う。

個人的にはElixirやSwift、Testing周りが関係が強いので、そこら辺は特に楽しむことができた。

例えば、ElixirやSwiftのProtocolの話。SwiftではProtocolはGlobalスコープに対して定義される一方で、Elixirでは特定の型に対して定義することができる。そのため、影響範囲を限定することができるのでより安全に利用することができるという話も。

テストの話としては、Elixir、Haskellが題材になっていてよかった。Elixirの話では、TrueStoryを題材にして、可読性の高い(テストしたいシナリオ・ストーリーを理解しやすい)テストコードの書き方に対しても言及している。その中で、パイプ演算子を使った関数型としての書き方に触れながら話を進めている。

Haskellでは、型システムのほか、C言語で書かれたコードをHaskellでラップしてテストコードを書いていく方法を載せている。ほかの言語をテストするためにHaskellを使う形は興味深かった。

やー。思いの外、Elixirに関する話が多かったのとHaskellを使った説明も多く、個人的にはそれだけで満足度が高かった。Haskellはがっつり触れたことはなく、考え方を学ぶために触れている側面が強いけれど、触れる機会が増えてきたらまたこの書籍でさっとHaskellは頭の中を整理したい気分。

[Elixir]What’s new in Ecto2.0

Elixirの開発元であるPlatformatecからEcto2.0に関するフリーペーパーが正式に公開された。

http://blog.plataformatec.com.br/wp-content/uploads/2016/12/whats-new-in-ecto-2-0-1.pdf

いくつかEctoの特性(Ecto is not your ORMといったこととか)が書かれていて、解決したい問題とその対策として2.0や2.1で入ったことを書いている。

1つ、気になったところをメモとして残しておく。
Ecto2.1からdynamicを使って簡易に動的にwhere句を制御することができるようになった。コードは以下。

https://github.com/elixir-ecto/ecto/blob/v2.1.1/lib/ecto/query.ex#L381

例えば、以下の場合は dynamic で指定した箇所をその引数の状態によって動的に切り替えることができる。
(http://blog.plataformatec.com.br/wp-content/uploads/2016/12/whats-new-in-ecto-2-0-1.pdf より)

これにより、SQLの発行を静的に数多くのパターン実装する必要のある箇所を、限られた少数の実装で表現することができるようになる。個人的に、特にfilter系の関数用意しようとしたら必要以上に行数が増える状態になっていたのでとてもありがたい。時間見つけて適用してみよう。

[Elixir]timestamp in Ecto2.1

Ecto2.1が着々とrcとして改修されていますね。
この中で、Calendar typeの導入が書かれています。

defaultでは、従来は timestamp() などの Ecto.Scheme に設定する値には Ecto.DateTime が格納されていたのですが、ここがデフォルトで NaiveDateTime になるよう。これにより、このSchemeを使っているところは基本的に NativeDateTime でEctoから今まで Ecto.DateTime で受け取っていた時間を扱う必要がありますね。 Ecto.DateTime とかはEcto2.2で完全に削除されるそうな。

https://github.com/elixir-ecto/ecto/blob/e3077b99c24086d5b93580228b1daa6bb0ee0b5a/CHANGELOG.md#integration-with-elixir-13-calendar-types

Schemeの設定としては以下になるそうですね。(ここ@timestamps_opts より。)

[type: :naive_datetime, usec: true]

ちなみに、これが導入PR
https://github.com/elixir-ecto/ecto/commit/12d67912ddddb39ff79cb53d3098569cb427b521

~N[] のsigilとか使われてて、個人的には Map だけで表現されるより読みやすくなった。

[Elixir]handle_infoとreply

GenServerなんかにある handle_info/2 の使い方をど忘れしてしまったので、メモ。

自身のブログを検索すると、 [Elixir in Action]OTP/GenServerを学んで非同期/並行処理を学ぶ にすでにメモってたのですが。

以下のような簡単なコールバックを実装し、スクリプトを実行してみます。

まずはGrnServerを持つプロセスを生成します。そのあと、 callcast で定義されていないメッセージを send してあげると、ここでは handle_info/2 に拾われて処理を行います。

defmodule MyInfo do
  use GenServer

  # Callbacks

  def handle_info({:reply, msg}, state) do
    IO.inspect msg
    IO.inspect state
    {:noreply, state}
  end
  def handle_info(_msg, state) do
    {:noreply, state}
  end
end
# Start the server
{:ok, pid} = GenServer.start_link(MyInfo, ["hello"])

# send message to the process
Process.send_after pid, {:reply, "message"}, 1_000

# "message"
# ["hello"]

少し話がそれて、非同期通信の時に何らかの処理を終えた時に通知を受け取りたい場合、そういえば以下のように reply/2 を使って処理を非同期にプロセスに投げることできるのでしたね。上に貼ったリンク先を読み直してて思い出した…

def hanldle_call(....) do
  spawn(fn ->
    data = # 処理
    GenServer.reply(caller, data) # 処理が終われば、GenServerの機構でメッセージを送る
  end)

  {:noreply, do_folder} # まずは非同期的に応答する
end

handle_infoも使うと、以下の通りにも書くことができる、と。
ここの、GenServerのドキュメントにも載っているやり方です。

def handle_cast(:reply_in_one_second, from, state) do
  Process.send_after(self(), {:reply, from}, 1_000)
  {:noreply, state}
end

def handle_info({:reply, from}, state) do
  GenServer.reply(from, :one_second_has_passed)
end

[Elixir]Registerを覗く

key-value processとしてElixir1.4に入れる予定の Register というものが公開されました。

付属のベンチマークによると、以下のように高い性能が出ていることがわかります。

このベンチマークの内容は以下

https://github.com/elixir-lang/registry/blob/master/bench/shared.exs

プロセスを起動して、登録して。それを10000回登録する間の時間を計測しているみたいですね。
各ベンチマークの最後で登録した名前をチェックして、その欠損がないことを確認して終わり、と。

register/3 周りは以下

https://github.com/elixir-lang/registry/blob/master/lib/registry.ex#L535

ここら辺を見て回ると、 :ets テーブルを複数に分割(sharding)しているぽい。
同じようなことをしているものがあるのかなと調べてみると、以下のライブラリがすでに。

https://github.com/cabol/shards
https://github.com/cabol/exshards

プロセスを気軽に使えるように便利機能を拡充していく、という感じですかね。


おまけ

テストコード、繰り返しには以下のように fordescribetest を囲むことができるのですね。こう言う書き方もあるのねーという学びでした。

https://github.com/elixir-lang/registry/blob/master/test/registry_test.exs

Download precompiled package and execute library with its binary

I’d like to run http_proxy without install package management for Elixir as portable aspect.
So, I prepare simple shell script to help the problem.

It is that downloading precompiled package and unzip it, run http_proxy with the precompiled mix.

Example

https://github.com/KazuCocoa/run_http_proxy

[Elixir]read GenStage and try a bit

GenStageの0.3.0がリリースされたと合わせて、GenStageに関してのアナウンスがされたので触ってみました。合わせて、GenEventの問題点や解決したい問題がかかれているので参考になると思います。

http://elixir-lang.org/blog/2016/07/14/announcing-genstage/

GenStageとは

https://github.com/elixir-lang/gen_stage#genstage

に書いている通り、producerとconsumerの別れた役割を持つプロセスの間のイベントをやりとりするためのライブラリです。

GenEventだとイベントを1つの1つのプロセスで処理していたので、何かエラーが発生した時にsupervisorを再起動するというような戦略が取れないことだったりなど、データの流れを考える上で平行処理やその周辺に開発者が気を配らないといけない、と手間がかかっていました。そのため、開発者がデータの処理に集中できるように、そこら辺をいい感じにしてくれるものを用意するために作られたものがこれのようです。

3つの役割

GenStageは、0.3.0現在は3つの役割を持つことができます。

  1. producer
  2. consumer
  3. producer_consumer

1は、callbackの実装時に handle_demand/2 を実装する必要があります。これは、2や3から要求が来た時に行う処理を書きます。2と3は handle_events/3 を実装する必要があります。これは、イベントを得た時に行う処理を書きます。

関係性の定義

GenStage.sync_subscribe c, to: b のように書くことで、このcとbの間にはconsumer(c)とproducer(b)の関係ができます。つまり、cからbに要求が送られ、それに対して行われた要求が処理されcに対して応答として帰ってきます。ここでは sync_subscribe/3 なので、同期的な挙動を行います。一定時間応答がなかったらtimeoutに成るし、そうなるまでcはbから返答を待ちます。

他にも async_subscribe/2 も存在して、これはこの関係が非同期的に行われる、ということですね。

https://hexdocs.pm/gen_stage/Experimental.GenStage.html#async_subscribe/2
https://hexdocs.pm/gen_stage/Experimental.GenStage.html#sync_subscribe/3

これらの関係性がわかるサンプル実装が以下にあります。
https://github.com/elixir-lang/gen_stage/blob/master/examples/producer_consumer.exs

最後に

GenStageはまだ開発中で、 Experimental.GenStage.Flow の実装を控えているそうです。今はまだプロトタイプとしてのドキュメントが以下にあるだけですが、外部データの流れをうまく扱う Flow を練っているようですね。

https://hexdocs.pm/gen_stage/Experimental.GenStage.Flow.html

ここら辺は以下のような使い方に寄与するみたいです。

Developers who maintain libraries that integrate with external data sources, be it a RabbitMQ, Redis or Apacha Kafka, can explore GenStage as an abstraction for consuming data from those sources. Library developers must implement producers and leave it up for their users to plug the consumer stages.

私のお試し。
https://github.com/KazuCocoa/my_gen_stage