SlideShare ist ein Scribd-Unternehmen logo
1 von 42
Elixir入門 第2回
「PC間で通信するアプリを
サクっと書いてみる」
with Docker
2017/04/07 ver0.5作成
2017/04/18 ver0.9作成
1
1. オブジェクト指向からプロセス指向に
2. プロセスの起動
3. メッセージ送受信
4. 双方向のメッセージ送受信
5. PC間のメッセージ送受信
6. リモートPCを操作する
7. Elixirが提供する分散・並列サポート
8. プロセス指向の世界へようこそ
目次
※ページ最下部の章番号/ページは、Dave Thomas著「プログラミングElixir」の関連記載です。ご参考ください
2
1.オブジェクト指向からプロセス指向に
3
1.オブジェクト指向からプロセス指向に
オブジェクト指向プログラミングでは、様々な役割のオブジェクトを
生成し、オブジェクト内の状態を保持することで、高度な処理を
実現してきました
CPU単体の性能が伸び続ける間は、オブジェクト指向のままで
良かったのですが、2003年頃にCPU性能が頭打ちとなり、マル
チコアCPU/クラウドでの性能upが求められる中、オブジェクト指
向の状態保持は、分散・並列に向かず、裏目に出ています
Elixirでは、オブジェクトのようにプロセスを気軽に作り、通信する
ことで、スマートに分散・並列や状態管理を実現できます
一般的に、分散・並列のプログラミングは難しい、と言われますが、
Elixirなら、驚くほど簡単にスラスラ書けます
4
2.プロセスの起動
5
2.プロセスの起動
ElixirイメージをDockerで起動します
新たなElixirプロジェクトを作成します
プロジェクトをビルドします
lib/pass.exを、お好きなエディタで以下の通り、書き換えます
cd pass
# iex -S mix
> docker run --rm -v /c/piacere/code:/code -i -t trenpixster/elixir /bin/bash
# mix new pass
defmodule Pass do
def say( message  "こんにちは。" ), do: IO.puts( message )
end
6
2.プロセスの起動
ビルドし、通常の関数として実行すると、以下が表示されます
これが、spawnでプロセスを起動し、実行すると、以下のような、
関数の実行結果としての表示と、プロセスのIDが表示されます
iex> recompile()
iex> Pass.say
こんにちは。
:ok
iex> spawn( Pass, :say, [] )
こんにちは。
#PID<0.1805.0>
第1引数:モジュール名
第2引数:関数名 ※「:」を付ける
第3引数:関数に渡す引数のリスト
※参照:第14章 P162
7
3.メッセージ送受信
8
3.メッセージ送受信:受信プロセスの起動
さきほどは、メッセージ表示するプロセスを起動しましたが、今度は、
メッセージを待ち受け、メッセージを受信したら表示するプロセスを
起動します
受信プロセスを起動します
defmodule Pass do
…
def confirm() do
receive do
{ true, message } ->
IO.puts( "受信メッセージ'#{message}'。" )
end
IO.puts( "------ confirm() end ------" )
end
…
iex> recompile()
iex> pid = spawn( Pass, :confirm, [] )
#PID<0.1768.0>
見慣れない表記ですが後ほど解説します
※参照:第14章 P163
9
3.メッセージ送受信:メッセージ送信
受信プロセスのプロセスID宛に"hello"のメッセージを送信すると、
受け取ったメッセージを表示し、受信プロセスは終了します
受信プロセスは、一度受け取ると、プロセス終了するため、再送
しても受信しません
iex> send( pid, { true, "hello" } )
受信メッセージ'hello'。
{true, "hello"}
------ confirm() end ------
iex> send( pid, { true, "hello" } )
{true, "hello"}
「受信メッセージ'hello'。」が表示されない
※参照:第14章 P163~164
10
3.メッセージ送受信:受信(再帰)
繰り返し受信可能とするには、自身を再帰呼出します
これで再送しても、毎回メッセージを受信し、表示します
defmodule Pass do
…
def hear() do
receive do
{ true, message } ->
IO.puts( "受信メッセージ'#{message}'。再度メッセージを受け取れます。" )
end
hear()
IO.puts( "------ hear() end ------" )
…
# iex -S mix
iex> pid = spawn( Pass, :hear, [] )
#PID<0.496.0>
iex> send( pid, { true, "hello" } )
受信メッセージ'hello'。再度メッセージを受け取れます。
{true, "world"}
iex> send( pid, { true, "hello" } )
受信メッセージ'hello'。再度メッセージを受け取れます。
{true, "world"}
※参照:第14章 P164、166
11
3.メッセージ送受信:受信のパターンマッチング
受信プロセスは、第1引数として「true」のみ受け付けるパターン
マッチングになっています
true以外を送信すると、メッセージの受け取りがされません
iex> pid = spawn( Pass, :hear, [] )
#PID<0.387.0>
iex> send( pid, { "hoge", "hello" } )
{"hoge", "hello"}
iex> send( pid, { :ok, "hello" } )
{:ok, "hello"}
defmodule Pass do
…
def hear() do
receive do
{ true, message } ->
IO.puts( "受信メッセージ'#{message}'。" )
…
受け取ったメッセージが表示されない
受け取ったメッセージが表示されない
12
4.双方向のメッセージ送受信
13
4.双方向のメッセージ送受信
メッセージ受信後に、送信元へメッセージを返却する、双方向の
メッセージ送受信を行ってみます
defmodule Pass do
…
def hear_after_say() do
receive do
{ sender_pid, message } ->
IO.puts( "受信メッセージ'#{message}'。返信をご確認ください。" )
send( sender_pid, { true, "これは'#{message}'の受信に対する返信です" } )
end
hear_after_say()
IO.puts( "------ hear_after_say() end ------" )
end
…
※参照:第14章 P163
14
4.双方向のメッセージ送受信:受信後の返信確認
受信プロセスにメッセージを送り、受信したメッセージが表示され
るところまでは、これまでと同じですが、裏で返信をしています
自分宛に返ってきた返信を確認してみましょう
iex> recompile()
iex> pid = spawn( Pass, :hear_after_say, [] )
#PID<0.240.0>
iex> send( pid, { self(), "Yo, Yo" } )
受信メッセージ'Yo, Yo'。返信をご確認ください。
{#PID<0.209.0>, "Yo, Yo"}
返信先としての自分のPIDを渡します
iex> receive do { true, message } -> IO.puts message end
「Yo, Yo」受信の返信
:ok
※参照:第14章 P163~164
15
4.双方向のメッセージ送受信:返信確認②
receive~を手入力する代わりに、confirm()を使って、自分
宛に返ってきた返信を確認することもできます
なお、confirm()は、もし返信が無かった場合、ずっと待ち続け
てしまいます
iex> send( pid, { self(), "hear to me." } )
受信メッセージ'hear to me.'。返信をご確認ください。
{#PID<0.209.0>, "hear to me."}
iex> Pass.confirm()
受信メッセージ'「hear to me.」受信の返信'
------ confirm() end ------
:ok
iex> Pass.confirm
… sendしないときは返信も無いため
待ち続けてしまう
※参照:第14章 P164
16
4.双方向のメッセージ送受信:返信タイムアウト
チェックから5秒間、返信無なら、タイムアウトさせます
これで返信が無くても、待ち続けないようになります
defmodule Pass do
…
def confirm() do
receive do
{ true, message } ->
IO.puts( "受信メッセージ'#{message}'。" )
after 5000 ->
IO.puts( "Timeout..." )
end
IO.puts( "------ confirm() end ------" )
…
iex> recompile()
iex> Pass.confirm
Timeout...
------ confirm() end ------
:ok
※参照:第14章 P165
17
5.PC間のメッセージ送受信
18
5.PC間のメッセージ送受信:ノード1の起動
以下コマンドで、1つ目のノードに名前を付けてiexを起動します
ここでは、以下IPアドレスを確認した、と想定します
iexが起動したら、自分のノード名を確認します
説明上、これを「ノード1」とし、受信側を担当させます
# ifconfig
(IPアドレスを確認)
# iex --name node1@【IPアドレス】 --cookie elixir-example -S mix
iex(node1@172.17.0.2)> Node.self
:"node1@172.17.0.2"
# iex --name node1@172.17.0.2 --cookie elixir-example -S mix
※参照:第15章 P183~186
19
5.PC間のメッセージ送受信:ノード2の起動
別のシェルを起動し、もう1つのDockerを起動します
こちらを説明上「ノード2」とし、送信側を担当させます
※背景も青色にしてノード1と区別します
送信用の新たなElixirプロジェクトを作成します
2つ目のノードにも名前を付けてiexを起動します
ここでは、以下IPアドレスを確認した、と想定します
> docker run --rm -v /c/piacere/code:/code -i -t trenpixster/elixir /bin/bash
# ifconfig
(IPアドレスを確認)
# iex --name node2@【IPアドレス】 --cookie elixir-example -S mix
# iex --name node2@172.17.0.3 --cookie elixir-example -S mix
# mix new sender
20
5.PC間のメッセージ送受信:PC同士の接続
ノード2からノード1に接続し、trueが返ってくれば接続成功です
ノード1で受信プロセスを起動し、「passing」という名前で名前
登録します
iex(node2@172.17.0.3)> Node.connect :"node1@172.17.0.2"
true
iex(node2@172.17.0.3)> Node.list
[:"node1@172.17.0.2"]
iex(node1@172.17.0.2)> pid = spawn( Pass, :hear_after_say, [] )
#PID<0.591.0>
iex(node1@172.17.0.2)> :global.register_name( :passing, pid )
:yes
※参照:第15章 P186~187
21
5.PC間のメッセージ送受信:プロセス名検索
ノード2から、ノード1の受信プロセスを名前検索してみます
PIDの後半が、ノード1での受信プロセス起動時のPIDと一致し
ており、ノード2からの受信プロセスの特定に成功しています
では、ノード2から、ノード1の受信プロセス宛に、メッセージを送信
してみましょう
iex(node2@172.17.0.3)> send( :global.whereis_name( :passing ), { self(),
"inter-node" } )
{#PID<0.203.0>, "inter-node"}
iex(node2@172.17.0.3)> :global.whereis_name( :passing )
#PID<19536.591.0>
※参照:第15章 P187
22
5.PC間のメッセージ送受信:PC間の通信
ノード1を確認すると、ノード2から送信したメッセージが受信され
ています
受信したノード1がノード2に返信したことも確認できます
このように、異なるPC間のメッセージ送受信も、ローカル内通信
のコードからほぼ変更無しに、アッサリと実現できました
iex(node1@172.17.0.2)>
受信メッセージ'inter-node'。返信をご確認ください。
iex(node2@172.17.0.3)> Pass.confirm
受信メッセージ'「inter-node」受信の返信'。
------ confirm() end ------
:ok
23
6.リモートPCを操作する
24
6.リモートPCを操作する
さぁ、いよいよ、PC間のプロセス通信を使って、「リモートPC操作」
を行う、興味深いアプリを開発してみましょう
リモートPCのカレントフォルダを返すサーバをノード1に作ります
ビルドします
defmodule Pass do
…
def pwd_server() do
receive do
{ sender_pid, _ } ->
{ :ok, result } = File.cwd()
send( sender_pid, { true, result } )
end
pwd_server()
end
…
iex(node1@172.17.0.2)> recompile()
25
6.リモートPCを操作する
ノード2でconfirm()等を使い、メッセージを受信可能としたいの
ですが、Passモジュールは、ノード1にしか無いため、使えません
これをノード2で利用可能とするため、モジュールを配布します
(あらかじめ前述したノード間接続を済ませてから実施)
今度は成功します
iex(node1@172.17.0.2)> nl( pass )
{:ok, [{:"node1@172.17.0.4", :loaded, Pass}]}
iex(node2@172.17.0.3)> Pass.say
** (UndefinedFunctionError) function Pass.say/0 is undefined (module Pass is
not available)
Pass.say()
iex(node2@172.17.0.3)> Pass.say
こんにちは。
:ok
26
6.リモートPCを操作する
ノード1で、カレントフォルダを返すサーバを起動し、登録します
ノード2から、ノード1のカレントフォルダを取得することができます
iex(node1@172.17.0.2)> pid = spawn( Pass, :pwd_server, [] )
#PID<0.305.0>
iex(node1@172.17.0.2)> :global.register_name( :pwd, pid )
:yes
iex(node2@172.17.0.3)> send( :global.whereis_name( :pwd ), { self(), ""} )
{#PID<0.112.0>, ""}
iex(node2@172.17.0.3)> Pass.confirm
受信メッセージ'/code/pass'。
------ confirm() end ------
:ok
27
6.リモートPCを操作する
サーバ起動やメッセージ送受信を毎回記述するのを避けるため、
関数にまとめます
defmodule Pass do
…
def start_pwd_server() do
pid = spawn( Pass, :pwd_server, [] )
:global.register_name( :pwd, pid )
end
def pwd() do
send( :global.whereis_name( :pwd ), { self(), "" } )
listen()
end
def listen() do
receive do
{ true, message } -> IO.puts( message )
after 5000 -> IO.puts( ".....Timeout....." )
end
end
…
28
6.リモートPCを操作する
ビルドし、配布します
ノード1でサーバプロセスを起動します
ノード2から、ノード1上でのpwdを実施します
だいぶ呼び出しがスッキリしました
この調子で、ls/cd/catを実装してみましょう
iex(node1@172.17.0.2)> recompile()
iex(node1@172.17.0.2)> nl( Pass )
iex(node1@172.17.0.2)> Pass.start_pwd_server
:yes
iex(node2@172.17.0.3)> Pass.pwd
/code/pass
:ok
29
6.リモートPCを操作する
lsサーバ/クライアントの実装は以下の通りです
defmodule Pass do
…
def ls_server() do
receive do
{ sender_pid, path } ->
{ :ok, result } = File.ls( path )
send( sender_pid, { true, result } )
end
ls_server()
end
def start_ls_server() do
pid = spawn( Pass, :ls_server, [] )
:global.register_name( :ls, pid )
end
def ls( path  "." ) do
send( :global.whereis_name( :ls ), { self(), path } )
listen()
end
…
30
6.リモートPCを操作する
cdサーバ/クライアントの実装は以下の通りです
defmodule Pass do
…
def cd_server() do
receive do
{ sender_pid, path } ->
{ :ok, result } = File.cd( path )
send( sender_pid, { true, result } )
end
cd_server()
end
def start_cd_server() do
pid = spawn( Pass, :cd_server, [] )
:global.register_name( :cd, pid )
end
def cd( path  "/code/pass" ) do
send( :global.whereis_name( :cd ), { self(), path } )
listen()
end
…
31
6.リモートPCを操作する
catサーバ/クライアントの実装は以下の通りです
defmodule Pass do
…
def cat_server() do
receive do
{ sender_pid, path } ->
{ :ok, result } = File.read( path )
send( sender_pid, { true, result } )
end
cat_server()
end
def start_cat_server() do
pid = spawn( Pass, :cat_server, [] )
:global.register_name( :cat, pid )
end
def cd( path ) do
send( :global.whereis_name( :cat ), { self(), path } )
listen()
end
…
32
6.リモートPCを操作する
各サーバをまとめて起動・停止できるようにします
ビルドし、配布します
defmodule Pass do
…
def start_servers() do
Node.connect :"node2@172.17.0.3" # 手間を省くためで本来ここに書かない方が良い
start_pwd_server()
start_ls_server()
start_cd_server()
start_cat_server()
end
def stop_servers() do
if :global.whereis_name( :pwd ) != :undefined, do: Process.exit( :global.whereis_name( :pwd ), :normal )
if :global.whereis_name( :ls ) != :undefined, do: Process.exit( :global.whereis_name( :ls ), :normal )
if :global.whereis_name( :cd ) != :undefined, do: Process.exit( :global.whereis_name( :cd ), :normal )
if :global.whereis_name( :cat ) != :undefined, do: Process.exit( :global.whereis_name( :cat ), :normal )
:global.unregister_name( :pwd )
:global.unregister_name( :ls )
:global.unregister_name( :cd )
:global.unregister_name( :cat )
end
…
iex(node1@172.17.0.2)> recompile()
iex(node1@172.17.0.2)> nl( Pass )
33
6.リモートPCを操作する
ノード1でサーバプロセス群を起動します
ノード2から、ノード1上でのcdとlsを実施します
表示がヘンなので、後ほど修正しましょう
iex(node1@172.17.0.2)> Pass.start_servers
:yes
iex(node2@172.17.0.3)> Pass.cd "deps/poison/"
/code/pass/deps/poison
:ok
iex(node2@172.17.0.3)> Pass.ls
.gitignoreconfiglibmix.exsmix.lockREADME.mdtest_build
:ok
34
6.リモートPCを操作する
ノード2から、ノード1上でのcatを実施します
1UNIXコマンド1プロセスといった感じで、サーバプロセスを起動し、
クライアントから通信してリモートPCでの処理をする分散処理が
気軽に書ける、という雰囲気が伝わったでしょうか?
iex(node2@172.17.0.3)> Pass.cat "README.md"
# Poison
[![Travis](https://img.shields.io/travis/devinus/poison.svg?style=flat-square)…
[![Hex.pm](https://img.shields.io/hexpm/v/poison.svg?style=flat-square)…
[![Hex.pm](https://img.shields.io/hexpm/dt/poison.svg?style=flat-square)…
[![Gratipay](https://img.shields.io/gratipay/devinus.svg?style=flat-square)…
Poison is a new JSON library for Elixir focusing on wicked-fast **speed**
…(ファイル内容の表示が続く)…
[1]: http://www.erlang.org/euc/07/papers/1700Gustafsson.pdf
[2]: http://www.erlang.org/workshop/2003/paper/p36-sagonas.pdf
[3]: http://jlouisramblings.blogspot.com/2013/07/problematic-traits-in-erlang.html
[4]: http://prog21.dadgum.com/70.html
:ok
35
6.リモートPCを操作する:リスト1件ずつの処理
lsの表示を修正します
File.ls()の戻り値は、フォルダ内のファイルのリストになっており、
データとしては以下のような感じです
これをそのままIO.puts()に渡すと、区切りの無い文字列として
表示してしまいます
対策として、1件ずつ改行を入れる処理を施します
これをIO.puts()に渡すと、1行毎の表示が行われます
[".gitignore", "config", "libmix.exs", "mix.lock", "README.md"]
iex> [".gitignore", "config", "libmix.exs", "mix.lock", "README.md"] |>
Enum.map( fn( x ) -> x <> "n" end )
[".gitignoren", "confign", "libmix.exsn", "mix.lockn", "README.mdn"]
iex> [".gitignore", "config", "libmix.exs", "mix.lock", "README.md"] |> IO.puts
.gitignoreconfiglibmix.exsmix.lockREADME.md
:ok
※参照:第10章 P92
36
6.リモートPCを操作する
lsサーバにEnum.mapを追加します
ビルドし、配布します
defmodule Pass do
…
def ls_server() do
receive do
{ sender_pid, path } ->
{ :ok, result } = File.ls( path )
send( sender_pid, { true, result |> Enum.map( fn( x ) -> x <> "n" end ) } )
end
ls_server()
end
…
iex(node1@172.17.0.2)> recompile()
iex(node1@172.17.0.2)> nl( Pass )
37
6.リモートPCを操作する
lsの表示が直りました
なお、下記のように短縮表記できます
iex(node2@172.17.0.3)> Pass.ls
.gitignore
config
lib
mix.exs
mix.lock
README.md
:ok
defmodule Pass do
…
def ls_server() do
receive do
{ sender_pid, path } ->
{ :ok, result } = File.ls( path )
send( sender_pid, { true, result |> Enum.map( &( &1 <> "n" ) ) } )
end
ls_server()
end
…
※参照:第5章 P42
38
7.Elixirが提供する分散・並列サポート
39
7.Elixirが提供する分散・並列サポート
ここまでで説明した、分散・並列や状態管理は、しょっちゅう似た
ようなものを実装することになるため、既にパターン化されています
(OTP:Open Telecom Platformと総称されています)
以下に幾つかそのパターンを紹介しておきます
GenServer・・・汎用サーバIFパターン
状態の保持・参照のインタフェース※を規定する
※ビヘイビアと呼ばれる (Javaで言うところのinterface)
Supervisor・・・プロセス監視・再起動パターン
プロセスがエラー等でダウンしたとき、自身でリカバリーするのでは
無く、プロセス監視と事前に決めた手順でリカバリーする仕組み
他にも、プロセスモニターというGUIツールもあります
※参照:第16章 P193~208、台17章 P209~217
40
8.プロセス指向の世界へようこそ
41
8.プロセス指向の世界へようこそ
今回は、Elixirのプロセスと通信についてご説明しました
分散・並列のベースとなる、プロセス生成および通信による処理
の組み立てが「そこまで難しく無いかも?」と思っていただけたら、
この入門としては大成功です
今後ますますマルチコアCPU/クラウドでの性能upが求められる
のに対し、「いかに分散・並列が簡単にスラスラ書けるか?」は、
アプリ開発において最も重要となるでしょう
Elixirは、それをアッサリ叶えてくれるので、あなたが今後もアプリ
開発を続けていくのであれば、オブジェクト指向からプロセス指向
にシフトする機会をElixirからぜひ得て欲しいです
仕事でも趣味でも、プログラミングライフをエンジョイしてください!

Weitere ähnliche Inhalte

Was ist angesagt?

Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較
Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較
Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較KazuoSuzuki6
 
研究室における研究・実装ノウハウの共有
研究室における研究・実装ノウハウの共有研究室における研究・実装ノウハウの共有
研究室における研究・実装ノウハウの共有Naoaki Okazaki
 
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】Unity Technologies Japan K.K.
 
最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情Yuta Kikuchi
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方uchan_nos
 
NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日
NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日
NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日Kitsukawa Yuki
 
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15Shuyo Nakatani
 
SSII2018TS: 3D物体検出とロボットビジョンへの応用
SSII2018TS: 3D物体検出とロボットビジョンへの応用SSII2018TS: 3D物体検出とロボットビジョンへの応用
SSII2018TS: 3D物体検出とロボットビジョンへの応用SSII
 
WebRTCのオーディオ処理の謎、誰か教えて!
WebRTCのオーディオ処理の謎、誰か教えて!WebRTCのオーディオ処理の謎、誰か教えて!
WebRTCのオーディオ処理の謎、誰か教えて!mganeko
 
Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?Takayuki Shimizukawa
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話torisoup
 
【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models
【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models
【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language ModelsDeep Learning JP
 
Probabilistic face embeddings
Probabilistic face embeddingsProbabilistic face embeddings
Probabilistic face embeddingsKazuki Maeno
 
大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成
大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成
大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成MobileRoboticsResear
 
Pythonではじめるロケーションデータ解析
Pythonではじめるロケーションデータ解析Pythonではじめるロケーションデータ解析
Pythonではじめるロケーションデータ解析Hiroaki Sengoku
 
ソフトウェアテストの歴史と近年の動向
ソフトウェアテストの歴史と近年の動向ソフトウェアテストの歴史と近年の動向
ソフトウェアテストの歴史と近年の動向Keizo Tatsumi
 
バーチャルリアリティ(VR)概要
バーチャルリアリティ(VR)概要バーチャルリアリティ(VR)概要
バーチャルリアリティ(VR)概要Kurata Takeshi
 

Was ist angesagt? (20)

Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較
Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較
Azure OpenAI ServiceのChatGPT API と OpenAIのChatGPT APIの比較
 
研究室における研究・実装ノウハウの共有
研究室における研究・実装ノウハウの共有研究室における研究・実装ノウハウの共有
研究室における研究・実装ノウハウの共有
 
MLOpsはバズワード
MLOpsはバズワードMLOpsはバズワード
MLOpsはバズワード
 
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
点群を使いこなせ! 可視化なんて当たり前、xRと点群を組み合わせたUnityの世界 【Interact , Stipple】
 
最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情最近のDeep Learning (NLP) 界隈におけるAttention事情
最近のDeep Learning (NLP) 界隈におけるAttention事情
 
30分で分かる!OSの作り方
30分で分かる!OSの作り方30分で分かる!OSの作り方
30分で分かる!OSの作り方
 
NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日
NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日
NDTスキャンマッチング 第1回3D勉強会@PFN 2018年5月27日
 
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
画像をテキストで検索したい!(OpenAI CLIP) - VRC-LT #15
 
SSII2018TS: 3D物体検出とロボットビジョンへの応用
SSII2018TS: 3D物体検出とロボットビジョンへの応用SSII2018TS: 3D物体検出とロボットビジョンへの応用
SSII2018TS: 3D物体検出とロボットビジョンへの応用
 
WebRTCのオーディオ処理の謎、誰か教えて!
WebRTCのオーディオ処理の謎、誰か教えて!WebRTCのオーディオ処理の謎、誰か教えて!
WebRTCのオーディオ処理の謎、誰か教えて!
 
ゼロから始める転移学習
ゼロから始める転移学習ゼロから始める転移学習
ゼロから始める転移学習
 
数式からみるWord2Vec
数式からみるWord2Vec数式からみるWord2Vec
数式からみるWord2Vec
 
Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?Pythonはどうやってlen関数で長さを手にいれているの?
Pythonはどうやってlen関数で長さを手にいれているの?
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話
 
【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models
【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models
【DL輪読会】Hyena Hierarchy: Towards Larger Convolutional Language Models
 
Probabilistic face embeddings
Probabilistic face embeddingsProbabilistic face embeddings
Probabilistic face embeddings
 
大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成
大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成
大域マッチングコスト最小化とLiDAR-IMUタイトカップリングに基づく三次元地図生成
 
Pythonではじめるロケーションデータ解析
Pythonではじめるロケーションデータ解析Pythonではじめるロケーションデータ解析
Pythonではじめるロケーションデータ解析
 
ソフトウェアテストの歴史と近年の動向
ソフトウェアテストの歴史と近年の動向ソフトウェアテストの歴史と近年の動向
ソフトウェアテストの歴史と近年の動向
 
バーチャルリアリティ(VR)概要
バーチャルリアリティ(VR)概要バーチャルリアリティ(VR)概要
バーチャルリアリティ(VR)概要
 

Ähnlich wie Elixir入門「第2回:PC間で通信するアプリをサクっと書いてみる」

Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」fukuoka.ex
 
Elixirだ 第3回
Elixirだ 第3回Elixirだ 第3回
Elixirだ 第3回Joe_noh
 
10080分でPythonからIP Messeneger
10080分でPythonからIP Messeneger10080分でPythonからIP Messeneger
10080分でPythonからIP MessenegerSatoshi Yamada
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するKiyoshi Sawada
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するKiyoshi Sawada
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixirk1complete
 
EWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させる
EWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させるEWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させる
EWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させるKiyoshi Sawada
 
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖Kiyoshi Sawada
 
Step-Oriented Programming による任意コード実行の可能性
Step-Oriented Programming による任意コード実行の可能性Step-Oriented Programming による任意コード実行の可能性
Step-Oriented Programming による任意コード実行の可能性kozossakai
 
Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮
Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮
Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮CODE BLUE
 
第1回鹿児島node.jsの会資料_内村
第1回鹿児島node.jsの会資料_内村第1回鹿児島node.jsの会資料_内村
第1回鹿児島node.jsの会資料_内村Koichi Uchimura
 
Tech-circle #4 Consulハンズオンセミナー
Tech-circle #4 ConsulハンズオンセミナーTech-circle #4 Consulハンズオンセミナー
Tech-circle #4 Consulハンズオンセミナー隼人 渡邉
 
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップEWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップKiyoshi Sawada
 
[Basic 6] DNS / ソケット通信 / その他
[Basic 6] DNS / ソケット通信 / その他[Basic 6] DNS / ソケット通信 / その他
[Basic 6] DNS / ソケット通信 / その他Yuto Takei
 
サーバー実装いろいろ
サーバー実装いろいろサーバー実装いろいろ
サーバー実装いろいろkjwtnb
 
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成Kiyoshi Sawada
 
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成Kiyoshi Sawada
 

Ähnlich wie Elixir入門「第2回:PC間で通信するアプリをサクっと書いてみる」 (20)

Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」Elixir入門「第5回:Visualixirで見るマルチプロセス」
Elixir入門「第5回:Visualixirで見るマルチプロセス」
 
Elixirだ 第3回
Elixirだ 第3回Elixirだ 第3回
Elixirだ 第3回
 
10080分でPythonからIP Messeneger
10080分でPythonからIP Messeneger10080分でPythonからIP Messeneger
10080分でPythonからIP Messeneger
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
 
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用するEWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
EWD 3トレーニングコース#7 ewd-xpressメッセージ・パターンを適用する
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixir
 
EWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させる
EWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させるEWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させる
EWD 3トレーニング・コース #29 ewd-xpress を Linux systemdでサービスとして稼働させる
 
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
EWD 3トレーニングコース#8 ewd-xpressメッセージ・サイクルの解剖
 
Hbstudy41 auto scaling
Hbstudy41 auto scalingHbstudy41 auto scaling
Hbstudy41 auto scaling
 
Step-Oriented Programming による任意コード実行の可能性
Step-Oriented Programming による任意コード実行の可能性Step-Oriented Programming による任意コード実行の可能性
Step-Oriented Programming による任意コード実行の可能性
 
Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮
Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮
Step-Oriented Programming による任意コード実行の可能性 by 坂井 弘亮
 
第1回鹿児島node.jsの会資料_内村
第1回鹿児島node.jsの会資料_内村第1回鹿児島node.jsの会資料_内村
第1回鹿児島node.jsの会資料_内村
 
Monit
MonitMonit
Monit
 
エコSmalltalk
エコSmalltalkエコSmalltalk
エコSmalltalk
 
Tech-circle #4 Consulハンズオンセミナー
Tech-circle #4 ConsulハンズオンセミナーTech-circle #4 Consulハンズオンセミナー
Tech-circle #4 Consulハンズオンセミナー
 
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップEWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
EWD 3トレーニングコース#5 ewd-xpressアプリ開発第1ステップ
 
[Basic 6] DNS / ソケット通信 / その他
[Basic 6] DNS / ソケット通信 / その他[Basic 6] DNS / ソケット通信 / その他
[Basic 6] DNS / ソケット通信 / その他
 
サーバー実装いろいろ
サーバー実装いろいろサーバー実装いろいろ
サーバー実装いろいろ
 
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
EWD 3トレーニング・コース #4 ewd-xpressのインストールと構成
 
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
EWD 3トレーニングコース#4 ewd-xpressのインストールと構成
 

Mehr von 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
 
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」fukuoka.ex
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」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
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介fukuoka.ex
 
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」fukuoka.ex
 
Elixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版あります
Elixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版ありますElixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版あります
Elixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版ありますfukuoka.ex
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますfukuoka.ex
 

Mehr von fukuoka.ex (11)

AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
AI入門「第4回:ディープラーニングの中身を覗いて、育ちを観察する」
 
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
【macOSにも対応】AI入門「第3回:数学が苦手でも作って使えるKerasディープラーニング」
 
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
【LT版】Elixir入門「第7回:Python/KerasをElixirから繋いでアレコレする」
 
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
Elixir入門「第3回:Phoenix 1.3で高速webアプリ & REST APIアプリをサクッと書いてみる」
 
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」
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介
 
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
AI入門「第2回:Scala/Spark/Mahoutでレコメンドエンジンを作る」
 
Elixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版あります
Elixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版ありますElixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版あります
Elixir入門「第1回:パターンマッチ&パイプでJSONパースアプリをサクっと書いてみる」【旧版】※新版あります
 
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版ありますElixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
Elixir入門「第3回:Phoenix 1.2で高速Webアプリ & REST APIをサクッと書いてみる」【旧版】※新版あります
 

Elixir入門「第2回:PC間で通信するアプリをサクっと書いてみる」