同僚である@myfinderさんが登壇した、Tech Compass【Vol.07】に出席してきました。マイナビさんにレポートをあげていますので、興味のある方がいらっしゃいましたらご覧ください。
合わせて読みたい
さらなる詳細な内容の書き起こしは、以下のエントリが詳しいです。
2014/1/22 TechCompass #7 超絶トラフィックをミリ秒で処理する、アドテクノロジー開発現場の話 まとめ
同僚である@myfinderさんが登壇した、Tech Compass【Vol.07】に出席してきました。マイナビさんにレポートをあげていますので、興味のある方がいらっしゃいましたらご覧ください。
さらなる詳細な内容の書き起こしは、以下のエントリが詳しいです。
2014/1/22 TechCompass #7 超絶トラフィックをミリ秒で処理する、アドテクノロジー開発現場の話 まとめ
定義を忘れないようにまとめ。用語とかは以下の本のもの。
はじめての確率論 測度から確率へ
佐藤 坦
続く。
HipChatを使う機会があったので、lambdabotをHipChatへ組み込むプラグインを書いてる。とりあえず年内ぎりぎりでなんとなくは動くようになった。
以下、この件に関するメモ。
WEB APIとXMPPが使える。メッセージのストリーミングはXMPPを使うことになってるっぽいので、lambdabotのようなユーザの発言に反応するbotはこちらを使ったほうが良い。ただし、WEB APIの方がXMPPでは指定できないような細いことにも対応しているので、いろんな操作をしたければこちらを叩くことになる。
更新されてそうなpontarius-xmppを使った。network-protocol-xmpp の方も一応は更新されてそう。
HipChatでグループチャットの発言を拾うためにはMUCに対応する必要があるのだが、こちらに対応しているのはhaskell-xmppとXMPPの2つだけだが、あまり更新されてないので採用しなかった。
lambdabotのXMPPサポートについては、実は2007年に形跡があるが削除されている。今はXMPP関連のコードは残っていない。と思う。2008年にもXMPP用のforkが作られた形跡がある。が、だいぶ古いしWEB APIも併用したいので、今回はガン無視してスクラッチから書いた。
IRCに密結合している。masterブランチ見た感じだと、本体とプラグインを分けようとしているっぽく、今回作ったものもこれに便乗してパッケージを切った。
lambdabot-irc-pluginsを読むとやるべきことはだいたいわかる。Lambdabot.Monad の received と addServer がエントリポイントで、こいつらを呼べばbotの処理に参加できる。ユーザから受け取ったメッセージは、前者の関数にひたすら流す。botの発言はaddServerに登録したハンドラに流れてくるので、これを再びユーザに返せばよい。
ただし、どちらのインタフェースもIRCと密結合しており、IrcMessage型を必要とする。XMPPやWEB APIの言葉をそれっぽくIRCの言葉に翻訳する必要がある。メッセージの先頭が「:」から始まるとか、割と生のプロトコルが見える形なので、気持ち悪い。
lambdabotのIRCへの接続は、ドキュメントで見てもわかるようにコマンドライン引数の -e で irc-connect コマンドを実行させることで行う。このオプションを渡さないと offline コマンドが呼び出される仕組み。シンプル過ぎる。同様に今回作ったプラグインでHipChatへ繋げたい場合は、コマンドライン引数で -e に hipchat コマンドを渡すと良い。
lambdabotは以下の2点の理由でcabal sandboxと相性があまりよくない。
前者はPATH環境変数、後者はGHC_PACKAGE_PATH環境変数を、手元でlambdabotコマンドを実行する時に手動で設定することで凌いでいる*1。
よいお年を。
@__kanさんを見に来てます。メモを取る必要のあるイベントかわかりませんが、一応。
自分のトークでした。kan拡張の話をしました。
2014年をお楽しみに!
秋のエンジニアぶつかり稽古 2013で横綱級エンジニアのペアプログラミングを見てきたのだけど、これが想像以上に面白かった。他のイベントでもドンドンやるべき。
「ぶつかり稽古」はあんちぽさん(@kentaroさん)が考案した新しいエンターテインメントペアプログラミングのスタイル。単体テストを書く"受ける側"と、そのテストを通すために実装する"ぶつかる側"が交互にコードを書いて行き、聴衆はそれを観覧する。一種のライブコーディングではあるのだが、2人が実装に関わるため、事前の想定と違う方向にコーディングが進み易く、実装者のよりリアルな問題への対処方法を観察することができる。その人が普段どのようにコードを書いているかも、より正確に想像しやすい。参加者もテストを通す側の立場に立って内容を考えられるので、自分の実装と参加者の実装の癖の違いを楽しむこともできる。ぶつかる側だった@__kanさんは懇親会で寝落ちするほど精神力を使うきついセッションだったようだが、見ている方は新鮮な気持ちで楽しめた。
YAPC Asia 2014でも行われるといいんじゃないかなーと思った。
こんな感じでいいのかな。
class HFunctor hf where hfmap :: (Functor f, Functor f') => (forall t . f t -> f' t) -> hf f -> hf f'
以下は、型bを固定した時に定義できる関手F_bで、Functor fを型f bに移すような関手の定義。
data FunctorB b g = FunctorB (g b) deriving (Eq, Show) instance HFunctor (FunctorB b) where hfmap nat (FunctorB x) = FunctorB (nat x)
例えば、以下のようなMaybe関手からList関手への自然変換。
maybeToList :: Maybe a -> [a] maybeToList Nothing = [] maybeToList (Just x) = [x]
hfmapを使えばきちんとMaybe Intから[Int]への関数(Haskの射)に移る。
*Main> hfmap maybeToList (FunctorB (Just 10)) FunctorB [10]
昔はhackageに同名のクラスが上がっていたようだが、こちらは多分関手圏から関手圏への関手。今は消されている。
コンフリクトした場合はスーパークラス側のメソッドが優先されるべきなんだけど、"Hage te nai"が出力される。
package Role1; use Moose::Role; sub hage { "Hage te ru" } package Role2; use Moose::Role; sub hage { "Hage te nai" } package Super; use Moose; sub hage { "Dotti demo yoi" } package Sub; use Moose; extends 'Super'; with 'Role1', 'Role2'; package main; print Sub->new->hage, "\n"; print "Done\n";
以下も挙動が違うけど、overrideのセマンティクスがわからないのでなんとも。Mouseはエラーになるが、その方がありがたい気がする。Moose-2.1005はクラスに生えてるメソッドを優先して"Dotti demo yoi"を出力した。
package Role; use Mouse::Role; override hage => sub { "Hage te ru" }; package Sub; use Mouse; sub hage { "Dotti demo yoi" } with 'Role'; package main; print Sub->new->hage, "\n"; print "Done\n";
前者についてはpull-reqしておいたので、経過はそちらにて。