SlideShare une entreprise Scribd logo
1  sur  35
2017/07/12
(car (cdr ファンクション倶楽部)) LTエディション
やや関数型を意識した風
Elixir/Phoenixご紹介
1
そもそもElixirって
どんな言語?
2
1.Elixirは「データ変換」の言語
3
1.Elixirは「データ変換」の言語
Elixirは、CSVファイルやDBデータ、JSON、バイナリデータ等の
データを受け取り、パターンマッチし、加工・変換するのに適した、
動的型付けの関数型プログラミング言語です
上記の様々なデータフォーマットを、数値や文字列、リスト、マップ、
タプルに展開し、「パターンマッチ」でシンプルにコーディングできます
なお、扱うデータは、全てイミュータブルです
# iex
iex> 1+2
3
iex> list = [ 123, "abc", 456, true ]
[123, "abc", 456, true]
iex> map = %{ "key2" => "abc", "key1" => 123 }
%{"key1" => 123, "key2" => "abc"}
リストは[]で囲む マップは%{}で囲む
2種類書き方がある
①%{k1: "v1"…}
②%{"k1" => "v1"…}
REPLでElixirコードを試せる
4
1.Elixirは「データ変換」の言語:Enum
Enumモジュールで、リスト/マップ/タプルが操作できます
mapやfilter、reduce等、一通りあります
iex> Enum.sort( list )
[123, 456, true, "abc"]
iex> Enum.sort( map )
[{"key1", 123}, {"key2", "abc"}]
マップをソートするとタプルに変換される
(マップは順序を持てないため)
iex> Enum.map( list, fn( x ) -> IO.puts( "value=#{x}" ) end )
value=123
value=abc
value=456
value=true
iex> Enum.filter( list, fn( x ) -> x >= 124 end )
["abc", 456, true]
iex> Enum.reduce( list, fn( x, pre ) -> "#{x}, #{pre}" end )
"true, 456, abc, 123"
5
1.Elixirは「データ変換」の言語:パイプ
パイプを使い、シェルのように、データを前から後ろに繋いで処理
できます (パイプ後の関数の第1引数に前の結果が渡される)
この例はカンタン過ぎて、パイプの恩恵がイマイチ分かりにくいので、
中盤以降のコード例で、改めて紹介します
# iex
iex> list = [ 123, "abc", 456, true ]
iex> List.last( Enum.sort( list ) )
"abc"
iex> list |> Enum.sort |> List.last
"abc"
6
1.Elixirは「データ変換」の言語:パターンマッチ
パターンマッチは、Elixirの最もパワフルな一面です
プロジェクト配下のファイルを以下のように編集して、実行します
マップの”k2”キーの値抽出を、引数だけで実装できてしまいます
# mix new misc
# cd misc
lib/misc.ex
mixというビルドツールでプロジェクトが作成できます
defmodule Misc do
def match_sample( %{ k2: value } ), do: value
end
# iex -S mix
iex> Misc.match_sample( %{ k1: "v1", k2: "v2", k3: "v3" } )
"v2"
iex -S mixでプロジェクトのビルドが走り、iexに入ります
7
1.Elixirは「データ変換」の言語:パターンマッチ
キーだけで無く、キーと値の組み合わせでのマッチも可能です
各関数が、値に応じて、呼び分けされます
他の言語なら、関数呼び出し後にif文で分岐するような処理が、
引数でのパターンマッチで分岐できます
defmodule Misc do
def match( %{ Yes: "we can" } ), do: "Barack Obama"
def match( %{ Yes: need } ), do: need
…
iex> recompile()
iex> Misc.match( %{ No: "-", Yes: "we can", NA: "N/A" } )
"Barack Obama"
iex> Misc.match( %{ No: "-", Yes: "we do", NA: "N/A" } )
"we do"
iex内でリビルドするときはrecompile()
8
1.Elixirは「データ変換」の言語:パターンマッチ
該当キーがマップ内に存在しない場合、マッチエラーになります
引数に”_”を指定すると、その他としてマッチできるようになります
defmodule Misc do
def match( %{ Yes: "we can" } ), do: "Barack Obama"
def match( %{ Yes: need } ), do: need
def match( _ ), do: "Yes...NOT EXIST"
…
iex> Misc.match( %{ No: "-", NA: "N/A" } )
** (FunctionClauseError) no function clause matching in
Crawl.match/1
(crawl) lib/Qiita.ex:5: Crawl.match(%{NA: "N/A", No: "-"})
iex> recompile()
iex> Misc.match( %{ No: "-", NA: "N/A" } )
"Yes...NOT EXIST"
9
1.Elixirは「データ変換」の言語:パターンマッチ
もし、関数内でマッチさせるなら、以下のような書き方になります
(ただ、関数の引数でマッチする書き方の方が推奨です)
実行結果は、引数パターンマッチ版と同じです
defmodule Misc do
def match_in( input_map ) do
%{ Yes: need } = input_map
need
end
…
iex> recompile()
iex> Misc.match_in( %{ No: "-", Yes: "we can", NA: "N/A" } )
"we can"
10
1.Elixirは「データ変換」の言語:パターンマッチ
リストは、パターンマッチにより、「先頭」と「以降全て」で分割でき、
リスト要素の順次処理を組む土台となります
iex> [ head1 | tail1 ] = [ 5, 8, 3, 1 ]
[5, 8, 3, 1]
iex> head1
5
iex> tail1
[8, 3, 1]
iex> [ head2 | tail2 ] = tail1
[8, 3, 1]
iex> head2
8
iex> tail2
[3, 1]
…
iex> head4
[1]
iex> tail4
[]
11
1.Elixirは「データ変換」の言語:パターンマッチ
バイナリデータの分割/マップ化も、パターンマッチでとてもカンタン
に書けます
defmodule MP3 do
defstruct [ :header, :frames, :other_data ]
def analisis(
<<
tag :: bitstring-size( 24 ),
version :: bitstrint-size( 16 ),
flg :: bitstring-size( 8 ),
size :: unsigned-integer-size( 32 ),
data :: binary, # 以降のバイナリデータはここに集約される
>>
) do
%MP3
{
:header MP3Header( tag, version, flg, size )
}
end
end
12
1.Elixirは「データ変換」の言語:再帰(オマケ)
ループは再帰で書きます (末尾再帰は最適化される)
処理対象が残っている間、繰り返される関数と、処理対象が無
くなった際の完了処理の2つの関数を用意し、パターンマッチに
よって呼び分けが行われます
なお、Enumとパターンマッチで大抵の事は済むので、再帰を書く
機会は結構少ないです
defmodule Misc do
def nop( [ head | tail ], rows ), do: nop( tail, rows ++ [ head ] )
def nop( [], rows ), do: rows
…
# iex -S mix
iex> Misc.nop( [ 5, 8, 3, 1 ], [] )
[5, 8, 3, 1]
※一応、for構文はあるけど使う場面はほぼ無い
iex -S mixでプロジェクトのビルドが走り、iexに入ります
13
1.Elixirは「データ変換」の言語:高階関数
高階関数は、3種類の書き方があります
「&」と「&n」で、「fn()」と「end」は省略可能です
関数後の「/n」で、「&n」すらも省略可能です
iex> list = [ 123, "abc", true ]
iex> Enum.map( list, fn( x ) -> IO.puts( "#{x}" ) end )
123
abc
true
iex> Enum.map( list, &IO.puts( &1 ) )
iex> Enum.map( list, &IO.puts/1 )
14
2.【例】JSONパーサを作る
15
Elixirのアプリケーション例として、Qiita API呼出と、返ってくる
JSONのパースを行い、記事タイトルをリストアップしてみます
2.【例】JSONパーサを作る
16
2.【例】JSONパーサを作る
まず、ElixirのHTTPクライアント「HTTPoison」と、JSONパーサ
「Poison」を導入します
各モジュールは、ネットからインストールできます
defmodule Crawl.Mixfile do
…
defp deps do
[
{ :httpoison, "~> 0.7.2" },
{ :poison, "~> 1.5" }
]
end
end
# mix deps.get
mix.exs
17
Qiita APIを呼び出します
実行すると、Qiitaから取得したJSONが出力されます
(Body部以外に、StatusCode等も出力されます)
defmodule Crawl do
def get() do
HTTPoison.get!( "https://qiita.com/api/v2/items?query=Elixir" )
end
end
# iex –S mix
iex> Crawl.get
%HTTPoison.Response{body: "[{"rendered_body":"nu003ch2u003en
…
,"title":"AWS EC2にElixir/Phoenixをインストール","updated_at":"2017-02-10T13:08:41+09:00",
…(他記事が複数並ぶ)…
"twitter_screen_name":null,"website_url":null}}]",
…(Body部以外のHeader等が複数並ぶ)…
{"Content-Length", "4293"}, {"Connection", "keep-alive"}], status_code: 200}
2.【例】JSONパーサを作る
lib/crawl.ex
18
2.【例】JSONパーサを作る
StatusCodeが「200」のときだけ、Body部を抜き出します
(この後、パターンマッチしやすいよう、Poisonでリストマップへの
データ変換も行います)
Body部だけが出力されます
defmodule Crawl do
def get() do
response = HTTPoison.get!( "https://qiita.com/api/v2/items?query=
Elixir" )
body = body( response )
Poison.decode!( body )
end
def body( %{ status_code: 200, body: json_body } ), do: json_body
end
iex> recompile()
iex> Crawl.get
[%{"body" => "# ElasticBeanstalk Custom Platformとは?nn今までのElasticBeanstalkでは事前定義済み
…
"title" => "AWS EC2にElixir/Phoenixをインストール",
…(他記事が複数並ぶ)…
"twitter_screen_name" => nil, "website_url" => nil}}]
19
作ったget()を見ると、変数で受け渡しがまどろっこしいです
一方、変数を無くすと、処理順と逆になるため、読みにくいです
defmodule Crawl do
def get() do
response = HTTPoison.get!( "https://qiita.com/api/v2/items?query=
Elixir" )
body = body( response )
Poison.decode!( body )
end
…
2.【例】JSONパーサを作る:パイプで書く
defmodule Crawl do
def get() do
Poison.decode!( body( HTTPoison.get!( "https://qiita.com/api/v2/items?
query=Elixir" ) ) )
…
20
パイプで書くと、直感的かつスマートなコードとなり、ステキです
defmodule Crawl do
def get() do
"https://qiita.com/api/v2/items?query=Elixir"
|> HTTPoison.get!
|> body
|> Poison.decode!
end
…
2.【例】JSONパーサを作る:パイプで書く
21
タイトル抽出を追加し、URL周りをキレイにしたら完成です
こんな感じで、たった11行のコードで、「Qiita APIを呼び、記事
タイトルをリストアップ」するアプリケーションが書けました
2.【例】JSONパーサを作る
defmodule Crawl do
def get( query  "Elixir" ) do
url( query )
|> HTTPoison.get!
|> body
|> Poison.decode!
|> Enum.map( fn( %{ title: title } ) -> title end )
end
def url( query ), do: "https://qiita.com/api/v2/items?query=#{query}"
def body( %{ status_code: 200, body: json_body } ), do: json_body
end
iex> Crawl.get
["Advent Calendar 2016 投稿数の多いユーザランキング(上位50位)",
"スタートアップ企業の技術選定でPhoenix(Elixir)&React(JS)+時々Echo(go)を採用した",
"PhoenixでAPIによるログイン機能を実装する",
…(他記事が複数並ぶ)…
"Elixir/Phoenix環境をElasticBeanstalk Custom Platformで構築してみた"]
22
コードを改めて見ると、メインの処理は、以下の流れを書き下した
だけの形となっていて、直感的で分かりやすいコードとなっています
URL
→API呼出でJSON取得
→Body抽出
→JSONデコード
→タイトル抽出
2.【例】JSONパーサを作る
defmodule Crawl do
def get( query  "Elixir" ) do
url( query )
|> HTTPoison.get!
|> body
|> Poison.decode!
|> Enum.map( fn( %{ title: title } ) -> title end )
end
def url( query ), do: "https://qiita.com/api/v2/items?query=#{query}"
def body( %{ status_code: 200, body: json_body } ), do: json_body
end
23
3.応用:Qiita API以外のJSONパース
24
3.応用:Qiita API以外のJSONパース
Qiita API以外のAPIも、ほぼ同じコードでJSONパースできます
「はてなAPI」のJSONは、若干壊れている (笑) ので、デコード
前に文字列操作で補正をかけるパイプを追加します
defmodule Hatena do
def get( query  "Elixir" ) do
url( query )
|> HTTPoison.get!
|> body
|> String.slice( 1..-3 ) # そのままだとinvalidなJSONなので加工
|> Poison.decode!
|> Enum.map( fn( %{ title: title } ) -> title end )
end
def url( query ), do: "http://b.hatena.ne.jp/entrylist/json?sort=count&url=#{query}"
def body( %{ status_code: 200, body: json_body } ), do: json_body
end
# iex -S mix
iex> Hatena.get
["【翻訳】超高速なJSON APIをElixirフレームワークのPhoenixでビ...",
"2015/08/22/ElixirとPhoenixとMithrilのFFスタックでChatアプリを作っ...",
…(他記事が複数並ぶ)…
" Elixir ご紹介 // Speaker Deck"]
lib/hatena.ex
25
3.応用:Qiita API以外のJSONパース
「Wikipedia API」のJSONは、Qiita APIより2段、深い階層
構造なので、titleを抽出できる階層まで下るパイプを追加します
defmodule Wikipedia do
def get( query  "Elixir" ) do
url( query )
|> HTTPoison.get!
|> body
|> Poison.decode!
|> dig
|> Enum.map( fn( %{ title: title } ) -> title end )
end
def url( query ), do: "https://ja.wikipedia.org/w/api.php?format=json&action=query
&list=search&srsearch=#{query}"
def dig( %{ "query" => %{ "search" => search } } ), do: search
def body( %{ status_code: 200, body: json_body } ), do: json_body
end
# iex -S mix
iex> Wikipedia.get
["熊沢千絵",
"プログラミング言語一覧",
…(他記事が複数並ぶ)…
"エリクサー"]
lib/wikipedia.ex
26
3.応用:Qiita API以外のJSONパース
「Github API」は、検索パラメータの指定が異なるので、検索パ
ラメータに渡すデフォルト値を変えます
defmodule Github do
def get( query  "Elixir-lang/Elixir" ) do # 例.rails/rails
url( query )
|> HTTPoison.get!
|> body
|> Poison.decode!
|> Enum.map( fn( %{ title: title } ) -> title end )
end
def url( query ), do: "https://api.github.com/repos/#{query}/issues"
def body( %{ status_code: 200, body: json_body } ), do: json_body
end
# iex -S mix
iex> Wikipedia.get
["Use @optional_callbacks in GenServer",
"Improve no function clause error messages",
…(他記事が複数並ぶ)…
"Make Mix more friendly for newcomers"]
lib/github.ex
27
4.高速WebFW「Phoenix」
28
4.高速WebFW「Phoenix」
Elixirで組まれたWebFW「Phoenix」は、関数型でありながら、
Webページでのステートフルも持ち、Web+DBやJSON APIを
コマンド5発で構築でき、高い性能と並行分散も備えています
0
10000
20000
30000
40000
50000
60000
Throughput (req/s)
https://github.com/mroth/phoenix-showdown
http://postd.cc/websocket-shootout
Webページビュー性能比
WebSocket性能比
こんなWeb+DBのCRUD
アプリが、テーブル構築も含め、
コマンド5発で生成できてしまう
29
4.高速WebFW「Phoenix」
Phoenixは、Railsに似たビルドツールによる、Web (+DB)や
JSON API (+DB) の手軽な自動生成を実現しています
(RailsのコミッターがElixirの世界に参入し、RailsライクなPhoenixをコミットしている背景があります)
このコマンド5発で、Web+DBが、テーブルの構築も含め、実現
されます
JSON API+DBの場合は、上記コマンド中、下記1行が異なる
だけで、Web+DBとほぼ変わらない手順でJSON APIが構築
できます
# mix phoenix.new web --no-brunch
# cd web
# mix ecto.create
# mix phoenix.gen.html Post posts title:string body:text
# mix ecto.migrate
# iex -S mix phoenix.server
DB追加
DBに「title」「body」列を持つテーブルを定義
(同時にModelやController、Viewも定義)
DBへのテーブル構築とMVCモジュール生成
# mix phoenix.gen.json Post posts title:string body:text
30
4.高速WebFW「Phoenix」
更に、Elixir構文のAltJS「ElixirScript」や、Haskellライクな
関数型AltJS「Elm」と組み合わせ、フロントサイドもサーバサイド
も関数型なスタックを構成できます (ビルドツールも標準装備)
Model
Model
Model
関数型でMVCライクな「Elmアーキテクチャ」
31
5.副作用の分離
32
UIやステート、DBといった副作用は、サーバプロセスとして分離
し、メッセージパッシングでget/setします
「生きているプロセス」に、値保持やIO処理を閉じ込め、ロック無
通信で高速にやり取りするイメージです
たとえば、IO.puts()での画面表示は、「IOサーバプロセス」への
メッセージパッシングが裏では走っています
5.副作用の分離
iex> IO.puts( "hoge" )
メッセージパッシング
IO処理
IOサーバプロセス
33
ステートは幾つかの実現法ありますが、最もシンプルなパターンの
「Agent」で作る例をQiita人工無能コラム#5で紹介しています
5.副作用の分離
34
よりプリミティブなサーバプロセスとメッセージパッシングを作る例は、
Qiitaに入門スライドへのリンクと軽い解説あるので、ご覧ください
(この続編と、OTP/Redisでの分散・耐障害を今月書きます)
5.副作用の分離

Contenu connexe

Tendances

LINQ 概要 + 結構便利な LINQ to XML
LINQ 概要 + 結構便利な LINQ to XMLLINQ 概要 + 結構便利な LINQ to XML
LINQ 概要 + 結構便利な LINQ to XMLShinichiAoyagi
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
CodeIgniter入門
CodeIgniter入門CodeIgniter入門
CodeIgniter入門Sho A
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8y_taka_23
 
PHPの今とこれから2014
PHPの今とこれから2014PHPの今とこれから2014
PHPの今とこれから2014Rui Hirokawa
 
Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Taro Hirose
 
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LTNorikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LTMasahiro Nagano
 
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...なおき きしだ
 
How to contribute AWX
How to contribute AWXHow to contribute AWX
How to contribute AWXHideki Saito
 
Perl 非同期プログラミング
Perl 非同期プログラミングPerl 非同期プログラミング
Perl 非同期プログラミングlestrrat
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixirk1complete
 
PHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 とPHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 とdo_aki
 

Tendances (20)

LINQ 概要 + 結構便利な LINQ to XML
LINQ 概要 + 結構便利な LINQ to XMLLINQ 概要 + 結構便利な LINQ to XML
LINQ 概要 + 結構便利な LINQ to XML
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
CodeIgniter入門
CodeIgniter入門CodeIgniter入門
CodeIgniter入門
 
Terraform
TerraformTerraform
Terraform
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
実"戦"CakePHP Plugin
実"戦"CakePHP Plugin実"戦"CakePHP Plugin
実"戦"CakePHP Plugin
 
Embulk 20150411
Embulk 20150411Embulk 20150411
Embulk 20150411
 
Zabbix API
Zabbix APIZabbix API
Zabbix API
 
PHPの今とこれから2014
PHPの今とこれから2014PHPの今とこれから2014
PHPの今とこれから2014
 
Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)
 
PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5
 
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LTNorikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
Norikraで作るPHPの例外検知システム YAPC::Asia Tokyo 2015 LT
 
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
 
How to contribute AWX
How to contribute AWXHow to contribute AWX
How to contribute AWX
 
Perl 非同期プログラミング
Perl 非同期プログラミングPerl 非同期プログラミング
Perl 非同期プログラミング
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixir
 
LINQ in Unity
LINQ in UnityLINQ in Unity
LINQ in Unity
 
Em synchrony について
Em synchrony についてEm synchrony について
Em synchrony について
 
PHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 とPHP と SAPI と ZendEngine3 と
PHP と SAPI と ZendEngine3 と
 

Similaire à やや関数型を意識した風Elixir/Phoenixご紹介

asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesNoritada Shimizu
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsShogo Sensui
 
IdrisでWebアプリを書く
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書くHideyuki Tanaka
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.specKent Ohashi
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISPMasaomi CHIBA
 
実践 Reactive Extensions
実践 Reactive Extensions実践 Reactive Extensions
実践 Reactive ExtensionsShin Ise
 
Cookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming ParadigmCookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming ParadigmMinero Aoki
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーmganeko
 
J qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているかJ qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているかHisashi Aruji
 
Ext.directことはじめ
Ext.directことはじめExt.directことはじめ
Ext.directことはじめShuhei Aoyama
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional ProgrammingTomoharu ASAMI
 
VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門kamukiriri
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングTanUkkii
 

Similaire à やや関数型を意識した風Elixir/Phoenixご紹介 (20)

asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
 
Functional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.jsFunctional JavaScript with Lo-Dash.js
Functional JavaScript with Lo-Dash.js
 
IdrisでWebアプリを書く
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書く
 
Haskell で CLI
Haskell で CLIHaskell で CLI
Haskell で CLI
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
Lisp batton - Common LISP
Lisp batton - Common LISPLisp batton - Common LISP
Lisp batton - Common LISP
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
実践 Reactive Extensions
実践 Reactive Extensions実践 Reactive Extensions
実践 Reactive Extensions
 
MlnagoyaRx
MlnagoyaRxMlnagoyaRx
MlnagoyaRx
 
Ajax 応用
Ajax 応用Ajax 応用
Ajax 応用
 
Cookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming ParadigmCookpad Summer Intern 2015 - Programming Paradigm
Cookpad Summer Intern 2015 - Programming Paradigm
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
J qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているかJ qmobiはjqueryから軽量化しているか
J qmobiはjqueryから軽量化しているか
 
Xtext 紹介
Xtext 紹介Xtext 紹介
Xtext 紹介
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
Ext.directことはじめ
Ext.directことはじめExt.directことはじめ
Ext.directことはじめ
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
 
VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門
 
ECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミングECMAScript6による関数型プログラミング
ECMAScript6による関数型プログラミング
 

Plus de fukuoka.ex

AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」fukuoka.ex
 
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」fukuoka.ex
 
Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」fukuoka.ex
 
AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版あります
AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版ありますAI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版あります
AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版ありますfukuoka.ex
 
重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」
重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」
重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」fukuoka.ex
 
AI入門「第1回:AIの歴史とTensorFlow」
AI入門「第1回:AIの歴史とTensorFlow」AI入門「第1回:AIの歴史とTensorFlow」
AI入門「第1回:AIの歴史とTensorFlow」fukuoka.ex
 
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」fukuoka.ex
 

Plus de fukuoka.ex (7)

AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
 
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
 
Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」
 
AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版あります
AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版ありますAI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版あります
AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【旧版】※新版あります
 
重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」
重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」
重力プログラミング入門「第1回:地球の重力下で人工衛星を公転軌道に乗せる」
 
AI入門「第1回:AIの歴史とTensorFlow」
AI入門「第1回:AIの歴史とTensorFlow」AI入門「第1回:AIの歴史とTensorFlow」
AI入門「第1回:AIの歴史とTensorFlow」
 
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
 

やや関数型を意識した風Elixir/Phoenixご紹介