Fringeneer's Tech blog

Fringe81の開発者ブログ

DeepAnalyticsのデータ分析コンテストで優勝しました!

本記事はFringe81 アドベントカレンダー2017の6日目の投稿です。

こんにちは。Fringe81データサイエンティストの貫井です。 今年9月まではプライベートでやっていた競馬AIの開発を専業としており、10月からFringe81に正式ジョインしました。 業務では主に広告配信ロジックの最適化を取り組んでいます。 2017/10/30まで開催されていたDeepAnalytics主催のレコメンドエンジン作成コンテストに参加し、見事優勝することができました! 今回はそのコンペ参加の取り組みについて紹介します。

▽DeepAnalyticsについて

参加の背景

これまで自分は機械学習を競馬予測以外のタスクで試した経験がほぼなく、10月からの業務でどれくらいやれるのか一抹の不安を抱えていました。 そんなとき、データ分析チームの先輩社員から本コンペの参加を勧められ、腕試しのためにまずやってみようと参加を決めました。

コンテストについて

今回のコンテストでは、オプト社が提供する2017年4月の行動履歴から、2017年5月1週目においてユーザーが関心を示す商品を予測して、その精度を競います。

行動履歴には人材、旅行、不動産、アパレルと異なる4業種が与えられ、それぞれ個別にモデリングをします。 ユーザの行動は、CV、クリック、ページ閲覧、カートに入れるの4種類のevent_typeがあり、各履歴にはタイムスタンプがついています。

予測精度の評価は、nDCG(normalized discounted cumulative gain)が使用され、閲覧=1点、クリック=2点、CV=3点として計算されます。

開催期間は2017/8/28-2017/10/30の約2ヶ月間で、優勝賞金は30万円です。

本コンテストの詳細はこちらをご覧下さい。

精度を上げるための工夫

今回作成したレコメンドエンジンの精度を上げるのにした工夫は以下の3点です。

  • 特徴量大量生産の仕組み
  • 最近の行動をより重要視
  • 最後の最後にアンサンブル

特徴量大量生産の仕組み

まず、他の参加者との一番の差になったのはおそらく特徴量を大量生産できたことだと思います。 本コンテストに限った話ではありませんが、基本的に予測タスクを解くときは1特徴量=1Featureクラスとして定義しています。 今回の問題におけるイメージは以下の図のようになります。

f:id:fringeneer:20171201131510p:plain
特徴量クラスのイメージ

特徴量を作っていくと、作成過程で似たような処理がよく出てくることがあります。 例えば、ユーザの"閲覧"回数と"クリック"回数は、集計対象のevent_typeが異なるだけで、回数集計する処理は共通化できるはずです。 また、X曜日のイベント回数となると、掛け合わせが7曜日×4イベント種類=28パターンにもなるので、それをベタ書きしていくのはかなり辛いです。 そこで上図のように共通化できる処理は抽象クラスを設けてそこに記述することで、実特徴量クラスでは属性だけを指定すればよくなり、格段に特徴量定義の手間を抑えることができる上に、テストも楽に書くことができます。

また他の工夫としては、特徴量のクラス名を日本語で定義したことです。 日本語特徴量名を採用した理由は以下の3点です。

  • 良い英名を考える時間が無駄
  • 日本語の方が情報密度が高いので特徴量名を短く的確に表現しやすい
  • Python3では識別子にUnicodeが使える

コード内に日本語が入るのは気持ち悪い感じもしますが、名前を考えるのが億劫になって特徴量が作れなくなるよりはマシなんじゃないかと思います。

こうした工夫の結果、最終的に約400個もの特徴量を作成することができました。

最近の行動をより重要視

レコメンドエンジンでユーザのある商品についての興味を示す指標としてその商品に対する閲覧回数やクリック数がすぐに思いつくかと思います。 しかし、単純に閲覧回数やクリック回数のように時間軸を無視して集約してしまうと、「いつ行動したのか?」という情報が潰れてしまいます。 ユーザの関心や需要は時間ともに変化するはずなので、3日前の閲覧1回と30日前の閲覧1回は3日前の閲覧1回の方が価値が高いということが予想されます。

その直感を特徴量に落とし込むために、減衰率をrとして、X日前の行動の重みW(X)を指数関数で以下のように定量化しました。

W(X) = r^X \ \ (0 < r < 1)

減衰率rを変化させたときの過去1〜30日前の重みは以下の図のようになります。

f:id:fringeneer:20171201133235p:plain
減衰率を変化させたときの過去X日の時間減衰

回数の合計値を計算するときに、減衰関数で計算した重みを掛けることによって、最近の行動を強調できるようになります。 減衰率は複数の設定を変えたものを別の特徴量として追加していき、結果として時間減衰に関わる特徴量だけでも80個近い個数になりました。 この特徴量は締め切り2日前に追加して、1ヶ月近く超えられなかったnDCG=0.27の壁を突破する鍵となりました。

最後の最後にアンサンブル

集団(アンサンブル)学習は複数の学習モデルを組み合わせて強力な1つのモデルを構築する手法です。 アンサンブル学習はコンテストで勝つためには必須と言っても過言ではない強い手法ですが、モデルの訓練に時間がかかるというデメリットがあります。 約2ヶ月という制限時間の中で精度を競うのには、実験サイクルの回転効率は競争力を上げるための重要な要素となるため、早々からアンサンブル学習に手を出すのは筋が良くないだろうと考えていました。 そこで今回のコンペでは、データの前処理方法や特徴量追加などオリジナリティが出る部分での実験の効率を上げるため、締め切り2日前までは線形モデルの1種であるElasticNetと中間層1層のシンプルなニューラルネットを予測モデルとして採用していました。 その結果、最終日まで精度を伸ばし続けることができて、2位以下に大きな差をつけて勝つことができました。 ちなみに最終的にはGBDTを予測モデルとして採用しました。 GBDTの学習自体はxgboostlightgbmなどの洗練された実装があるので高速ですが、パラメータチューニングまで含めると線形モデルに比べて時間がかかるため、正しい選択だったと思います。

祝勝会@ニクアザブ

弊社のデータ分析チームみんなでニクアザブ本店にて祝勝会!! 次はKaggleで世界のデータサイエンティストと戦っていこう思います!!

f:id:fringeneer:20171206111953j:plain
白飛びしているのが私(貫井)です

Functinal Reactive Domain Modeling読書会を完走しました

こんにちは、エンジニアの小紫(@petitviolet)です。

エンジニア有志でFunctional and Reactive Domain Modelingという本の読書会を開催していましたが、最近ようやく完走出来ました。

https://www.booktopia.com.au/http_coversbooktopiacomau/big/9781617292248/function-and-reactive-domain-modeling.jpg

何で読書会やったの?

この本はタイトルから分かるように、

  • Functional
  • Reactive
  • DomainModeling(DDD)

とかなり欲張りなトピックについて書かれている本です。
どれも社内で積極的に学習にもプロダクト開発にも取り入れていっているものではありますが、もう少し足場を固めるための情報を求めていました。
さらに、Fringe81がサーバサイド開発言語として全面的に取り入れているScalaでサンプル等が書かれているということで、これは読むしかないとなりスタートしました。

どんな内容?

https://www.manning.com/books/functional-and-reactive-domain-modeling

にある目次はこのようになっています。

1.  Functional domain modeling: an introduction
2.  Scala for functional domain models
3.  Designing functional domain models
4.  Functional patterns for domain models
5.  Modularization of domain models
6.  Being reactive
7.  Modeling with reactive streams
8.  Reactive persistence and event sourcing
9.  Testing your domain model
10. Summary - core thoughts and principles

全体の流れとしては、
関数型プログラミング学びつつドメインモデリングと組み合わせる、そしてFutureやActorとドメインモデリングを組み合わせるというものです。

もう少し細かく書くと、

  • Scalaを使って関数型プログラミングを学ぶ
    • 関数合成での処理の組み立て方
    • 副作用をどうやって切り離すか
    • Domain ModelingにおけるAlgebraic Data Type(ADT)の活用
    • Functor/Applicative/Monad/Kleisli等の概念
  • ScalaでReactiveなアプリケーションの書き方
    • AsynchronousなAPI
    • Domain ModelとActor
    • Reactive Streams
    • CQRS+ES
  • Domain ModelのTest
    • Property Based Testingについて

といった感じです。

学び

弊社Fringe81ではDomain-Driven-Design(DDD)に積極的に取り組んでいますが、基本的にオブジェクト指向プログラミングとの相性が良いものだと考えていました。
ですが、この本を読んでからは関数型プログラミングとの組み合わせ方に幅が出来たように感じます。

例えば、Userモデルの振る舞いはUserがメソッドとして持つのではなくUserServiceの関数として提供し、UserはあくまでADTであるとすることで、振る舞いが単なる関数となり処理を合成しやすい上にテストも用意になるというメリットがあります。
DDDにおけるService(ドメインサービス)はドメインモデル貧血症になる危険性があることから注意深く設計していましたが、上記のようなFPの視点に立つことでむしろドメインモデルとサービスが一対のものとして表現されるようになるというのはFPの視点を取り入れないと見えてこない景色でした。

実際のプロダクト開発でFP + DDDをどの程度取り入れていくべきかはメリット・デメリット様々で議論がわかれるところだとは思いますが、そういう議論ができるようになったという点でこの本を読んで良かったなと思っています。

最後に

より良いプロダクト開発のために一緒に読書会をして新しい技術や概念を学習していきたい人を探しています!
http://www.fringe81.com/recruit/

行ってまいりました、elm-conf US 2017へ!

Fringe81エンジニアの関(@jshosomichi)です。 首題の通り、会社に全面バックアップして貰う形で、現地時間9/28朝から夕まで、新卒二年目のElmer古渕くんとともにelm-conf USに行ってまいりました!

Elm-conf US

f:id:fringeneer:20170929120107j:plain

アメリカはセントルイス、ホテルのボールルームにて開催され、200人から300人くらいの世界のElmersが集結していて、熱の高まりを感じてきました。 お天気も雰囲気も良くて、スタバと提携して美味なコーヒー飲み放題だったり、人は入っていましたが会場はゆったりと使えるくらいの混み具合で、とても快適でした。

今回面白いなと思ったのが、恐ろしい速度で同時通訳の方がリアルタイムで話している内容をタイピングで書き取ってくれてサブディスプレイに写してくれていたので、話についていきやすく、今後それは公開動画などに字幕として設定されるものと思われます。

全体感としては登壇内容・パネルディスカッションの質問内容などから察するに、「Elmが良いものだ、ランタイムエラー無い」といったあたりはもう前提化し、プロダクションで使うために周囲にその良さを理解してもらったり浸透させて行くためにはどうしたら良いのか、とかプロダクションで使っている人たちも一定数いて、さらにBetter Wayをどのように見出していくのか、といった感じの話が多かったように思います。

そもそも自身の英語力が自分が思っていた以上に貧弱であったことを痛感し、英語学習は勿論、何か強制的に英語を使わざるを得ないような環境を、チーム含めて整備していく必要があるなと強く感じたりもしまして、内容の解釈に誤りがあったりもするかもしれませんが、あくまでラフに幾つか個人的に印象に残ったスピーチを紹介させてもらいます。

Keynote: Evan Czaplickiさん

  • roadmapにあるような、どうやってSPAを構成するのかの話。
  • どんなことがコアな課題なのか?その課題について詳しく学ぶこと、Elmにフィットする解決案ってなんなのか?
  • 表示のためのプロセス改善やファイルサイズ圧縮などの手段により、よりUXを向上させるような、効果的にプログラムを実行出来るようなモノを今後のリリースで実現していきたい
  • Elmのコアプラットフォームとしてはじっくりと良い方法を適用していくので、具体的な実装時期などについては、そう急かさないでほしい
  • 登壇後にお話させていただき、Elmを使って弊社サービスUniposのプロダクション開発していることや、Elmのお陰で思考に集中できてとても生産性が上がっていることなどお礼を伝えさせてもらい、とても幸せな時間をいただきました。とても暖かく聡明な方でした。 f:id:fringeneer:20170929120108j:plain

The Inportance of Port: Murphy Randleさん

  • Elmのポートはサポートしてない方式のサードパーティAPI等への非同期通信の送信/受信の代替物ではない。もっとポートの力を引き出せる捉え方で使おう
  • PortはPromiseとして捉え、1リクエストにつき送/受信の2ポートを用意するのではなく、複数の操作を行なう事が出来るものとして捉える
  • サブスクリプションは個々の値ではなく、アプリケーションの抽象モデルを受け取るようにし共通化することで、無駄なポートを作成しない

Putting the Elm Platform in the Browser: Luke Westbyさん

  • Ellieはソースコードをシェアするための最良の手段となっている
  • Ellieの運用は広告費で行っているが、現在はWeb Workersコンパイラを動かし、サーバーリソースの節約ができるようになった
  • 今後は複数人で編集シェアをしたり、GithubとリンクすることでOSS活動と繋げるような青写真がある

Solving the Boolean Identity Crisis: Jeremy Fairbankさん

  • Booleanを2分岐するような状態全てに適用していくと、フラグの塊ができてしまう
    • 数学的な意味合いのBooleanは命題なのに、意味が失われてしまっている
  • 函数呼び出す時の引数にbookFlight "St. Louis" True False Trueの引数たちって・・・何?
    • チームで作るので、使う側が解りやすいものにしよう。コンピュータのためではなく、人の為にコードを書こう
  • これらの課題にUnionTypesで応えていく

Teaching Elm to Beginners: Richard Feldmanさん

  • コードを書く専門家たちは教えることの専門家ではないので、どうやったらElmを上手く伝授できるのかを伝える
  • 授業の設計:生徒は理解できているか?
    • 事実よりも生徒の理解を促そう。「Html msgって何でHtmlじゃないんですか」という素朴な質問にkindというのがあってだな的な話をするのではなく、msg型引数がなくてMsgが文字列だったとして、、という話をしたり
  • 生徒にモチベーションは与えられているか?
    • 型の重要性を説くよりも、コメントは古くなってしまうので型アノテーション書いたほうが良いよね的なところから動機づけを行っていき、UnionTypesの理解などに繋げていく
  • 徐々に、インクリメンタルに知識を増やすように伝える
    • Elmの言語設計は徐々に知識を増やしながら、動かしていくことで段階的に習熟度を高めていくように設計している。Elm in Actionのアジェンダもそのような構成を取っている

色々なお話を聞くことができて、なんだかコードが書きたくなって古渕くんと二人とてもウズウズしてしまったり、あるある話に爆笑したり、良い視点から切り込まれた話に舌鼓を打ったり、とても楽しい一日を過ごすことができました。

英語沢山勉強したい、Elmの発展にも貢献したい、いずれはここで自分の発見をお話したい、などいろんなWillやWantが生まれました。プレゼンテーションの内容はいずれ動画でも見ることができるようになると思いますが、場の持つエネルギーや、世界のリテラシーの高さ、世界のエンジニアのガタイの良さなどを体感できたことはとても良い経験でした!

f:id:fringeneer:20170929120020j:plain

Scala関西で発表&スポンサーします! #scala_ks

こんにちは、サーバサイドエンジニアの小紫(@petitviolet)です。
サマーインターンの季節となり、Scalaと設計でアツい夏を過ごしています。

Scalaといえば、来る2017/9/9(土)に大阪でScala関西が開催されます。

まだ参加枠には余裕があるようですので、お早めに!。

このScala関西には、弊社から2名が発表する予定となっています。
タイムテーブルには非常に魅力的なセッションが並んでおりますが、ご興味を持っていただけたら私たちのセッションもぜひ聞きに来て下さい!

発表内容

メタプログラミングScala

Cサブ会場2にて16:00-16:45で小紫が発表します。

Scalaにはマクロなどのメタプログラミング技法がたくさんあり、普段のプロダクト開発でお世話になっているライブラリやフレームワークの裏側では色々なところで使われています。
メタプログラミングを使ってどうやって機能を実現しているかが分かるようになれば、何かが起きた時にも迅速に対応できるようになるはずです。
そう思い、Scalametaを触ってみたら意外と簡単な面も発見できたので、その感覚をぜひ共有したいです。
セッションを通して、食わず嫌いしていた方でも触ってみようかなと思っていただけると嬉しいです。

発表概要は以下。

Scalaには強力な言語機能がありますが、それをより強力にするメタプログラミング。 それでも何となく難しそうなマクロを使うことに抵抗がある人も多いと思います。 scalametaが新しいメタプログラミングの主流となりそうな今、入門するのにいいチャンスです。 scalametaで出来ること、使い方を紹介します。

Ladder of CQRS+ES

Cサブ会場2にて17:00-17:45で豊島が発表します。

CQRS+ESは比較的まだ新しい概念かと思います。 断片的な情報は増えてきつつありますが、まとまった情報はまだまだ少なくあったとしてもとてもボリューミーだったりと、ついつい先送りしている、という人も多いのではないでしょうか(かくいう私もその一人です)。 登壇をきっかけに(自分を追い込み^^;)、そのエッセンス的な部分を共有したいと思っています。 Scalaというよりはアーキテクチャの話が中心なためScala初心者の方でも楽しんでもらえるかと思います。

公式の発表概要は以下。

CQRSおよびEvent Sourcingについて耳にする機会が増えてきましたが、まだまだ実践事例が豊富という状況ではないように感じています。 このセッションでは私が自社サービスを構築する上で実践した事例の紹介と一口にCQRS+ESと言っても実際はいくつかのレベル感があり比較的カジュアルなレベルから始めることも可能であることなどについて述べたいと思います。

スポンサーもします!

Fringe81として、Scala関西のSilverスポンサーとなっています。

東京以外の地域で開催されるイベントにスポンサーするのは弊社としては初めての取り組みとなります。

ちなみにScalaMatsuri2017では大名スポンサーとしてイベント運営に微力ながら応援しておりました。

少しずつScalaを使っている会社だと認知していただけると嬉しいです。

新サービスUniposに新言語elmを導入しました!

Fringe81エンジニアの関(@jshosomichi)です。主にフロントエンドの開発を担当しています。

先日、Fringe81は新規事業、Unipos(ユニポス)の正式版をリリースしまして、このサービスは我々が持つ発見/賞賛する文化をWebサービスとして実現し、強い組織を作っていくという、開発背景として思い入れの強いものになっています。

更に、正式版リリースまでの道のりの中で約一年間のプロト・α版・β版というリリースがあり、その過程で様々な技術的チャレンジを行ってきたという、別の視点での強い思い入れもあるということで、今後何度かに分けてその取組みを紹介できればなぁと思ったりしています。

さて、今回はそんなサービスのWebフロントエンド開発の大きな取り組みとして、タイトルにもありますelm導入について、紹介させていただければと。

f:id:fringeneer:20170725230600p:plain

チームの発展をめざして

導入を決定したのは2016年の9月の事、当時は別のサービスの開発を(React, Flux, TypeScript, immutable.js)といった構成でやっておりまして。Uniposについてはα版の開発が始まるか否かというタイミングでワタクシの参画も決まっていたので、β版あたりで新しい取り組みへのチャレンジができないかなーなどと考えていました。

上記構成でのWebアプリケーション開発でも一定の成果は出ており、開発チーム内での知見の共有もある程度進んでいたため、そのまま踏襲することも可能ではあったんですが、より生産性を高め、技術者のレベルを高めるためのチャレンジをして、チームとしての大きなジャンプアップを果たしたいという思いが強くありまして。

「どう作るか」に関しては自分で責任を負うことにして、デメリットがあったとしても、それを覆すことのできるメリットが出せそうであればチームの皆に強力を仰いでブッ込んでしまおう、といった観点でビッグなメリット探しをポイントに、
現状構成から見て、ざっくり①言語の発展、②アーキテクチャの発展という2面での考察を始めました。

elmの美点

当時導入していたTypeScriptについては、JSと比較すると、コンパイラによって、誤りの早期発見や、エディタ上でのコード補完が強力になる、といった恩恵を享受出来ていました。

一方で、型の設定が上手く行っていないと、エラーを検出できなかったり、言語仕様の早いアップデートのキャッチアップ等、メンテナンスのためのコストもそこそこに支払うという課題感を感じたりしていました。

elmを魅力的に感じた点は

  • 純粋関数型言語であり、常に式が値を返し、不変であり、参照透過性を確保出来る点
  • コンパクトな言語設計により、学習コストは記憶よりも思考に多くを払うことになる
  • elmアーキテクチャという優れた枠組みが実装されていることにより、アプリケーション基盤の構築コスト(ライブラリの組合せ・依存解決・バージョン管理)がグッと下がる。

などがあります。

なにより、いかにもアカデミックな方向性に向かいそうな出自の言語でありながら、目指している方向はもっとカジュアルなところで、楽しく学ぶことができ、子どもへのプログラミング教育にも使ってもらえるような言語にしていくという言語創設者のEvan氏のメッセージもとても刺さりました。

色々な言語やフレームワークの利用を模索しましたが、将来的に大きな広がりを見せる可能性と、言語自体の面白さ、選民思想ではなく大きな広がりに向かっていく方向性、どれもがビビッと来て、チームを強くし・共に成長していける技術はコレが最高だ!と感じました。

個人的にelmの今後に期待!なポイント

クリティカルな問題というのは正直ありませんでしたね。

主に表現力の部分が高まると良いなーと思う部分はありますが。下記のような事ができると個人的にはうれしいですね。

  • 型を抽象化したり、モジュールに関数の定義を義務化させるような制約をかける、といった機能の実装(いわゆるHaskellの型クラスというやつですね。話し合われてはいるようですが)
  • Range型のような、Int型ではあるのだけれども1〜10までしか受け付けないという型

導入意思決定から現在

始まってから5年(当時は4年)という若い言語であるという点や、プロダクト導入に踏み切っている企業は殆ど無いと思われる点が懸念ではありましたが、僕はそれを逆に面白いと思っていました。

幸いなことに、技術選定段階や、チームへの紹介での評判も良く、大きな問題があれば引き返すという意思決定も自分が担うことにして、導入を決定しました。

慎重に入れながら、少しずつ前進しては反省を繰り返し、アーキテクチャの細部や開発ポリシーをつめていき、現在ではUniposプロジェクトにおけるelmの稼働コード記述量は3万行近くになっています。

社内にelmを書くメンバーも5人ほどおり、みんなも沢山の新しい発見を得ることができ、徐々に生産性の高い開発技術として社内でも大きな存在感を見せるような認知になってきております。

ちなみに、メンバーへの教育コストはそれほどかけておりません。この手のシンタックスに慣れていない人には、これこれこうでね、とメカニズムを教えてあげればよく、 コードレビューも「イベントを表す『メッセージ』」と「状態を表す『モデル』」のレビューに矛盾や重複が無いことをチェックすれば拡張機能開発くらいであれば、根っこが腐るような事はほぼありません。

未来に向けて

9月には会社からの全面協力のもと、アメリカはセントルイスで行われるelm-conf USというカンファレンスに、オーディエンスとしてですが行くことになりました。

今後、何か会社としてelmという言語の発展に寄与するような活動もしていくことができればなー、というかやらねばなるまいと思っています。 その一環としてFringe81はElm Tokyo Meetup vol.4の会場として場の提供をさせていただき、私もトークセッションでお話させていただきます。

elm-tokyo.connpass.com

上記のイベントに是非ご参加いただければと思いますし、

なんかFringe81面白そうだなーと感じられたら採用・一緒に働いてみたーいの等のお話なども全力でお聞きします。

ElmもFringe81も盛り上げていきたいなー、 と切に願い、やるぞーと思う今日この頃でございます。

Typelevel Summitに参加してきました

こんにちは、@petitvioletです。
遅くなりましたが、ScalaDaysの翌日に開催されたTypelevel Summitにも参加したので、そちらについてのレポートです。

ScalaDaysの参加レポートはこち
fringeneer.hatenablog.com

typelevel.org

Typelevel summit

Typelevel.scalaにまつわるカンファレンスです。
ScalaDaysよりも技術的に難しい話が多かった印象で、そのせいか人数もかなり少なくなっていて70-80人くらい?の比較的小じんまりしたイベントでした。

f:id:fringeneer:20170608230013j:plain

Inviting everyone to the party

基調講演
資料
プログラミングパラダイムはたくさんある。
コミュニティや考え方など、人には色々なコンテキストがあり、それを尊重しよう、という話。

途中、Type Tetrisという単語が出てきてちょっと笑いが起きてました。
やっぱり型合わせでみんな苦労しているんだな、と。

Refined types for validated configurations

資料:Refined Types for Validated Configurations

Configurationはボイラープレートが多い上にバリデーションが難しく、RuntimeExceptionになってしまいがち。
それなのに何かミスがあると致命的な結果に繋がってしまうことが多いため、
ボイラープレートを削除しつつ安全にしたいという欲求が生まれ、
ライブラリを組み合わせて楽に安全にconfigurationする方法について話していました。

pureconfigで設定をちゃんとクラスで表現しつつ、refinedで値に対する制限を表現する、というイメージになりますね。

発表者のViktor氏が開発しているCirisも型安全にconfigurationが出来て便利そうでした。

Herding types with Scala macros

資料:Typelevel summit

AerospikeのScalaクライアントをmacroを使って実装した話でした。
TinkoffCreditSystems/aerospike-scala

shapelessのHListに対して適切な型のBinWrapperをmacroで生成するようになっており、型安全にデータを保存できるようになったそうです。

Monad Stacks

資料:MonadStacks.pdf

PlayでJsonを受け取ってユーザーを作成・保存してユーザー情報をJsonとして返す、という流れを実装するにあたって、
普通に実装するとFutureOptionの扱いもあり、そこそこのコード量になってしまう。

単にFuture[A]だけならfor式を使って簡潔に書けるが、Future[Option[A]]になってしまうと単純にfor式ではうまく書けなくなる。 Error情報を持つクラスをErratumとして定義しつつ、Future[Either[Erratum, A]]をどうやって扱うか、という話。

選択肢は以下を上げていました。

後半はこれらに対応するライブラリの紹介だったので、詳細は資料をご参照下さい。

Freestyle: A framework for purely functional FP Apps & Libs

47degreesのCTO。
frees-io/freestyleについて。

@freeをつけるだけでfree monadになるというイメージなもの。すごい…。 @freeをつけたalgebraと、それのinterpreterを実装するだけで良いというのは非常に楽で良いですね。

PlayやSlickとのintegrationも開発されてました。

stack safeになっており、大量にannotationを付けてもパフォーマンスの劣化も無いとのことです。

Lenses for the masses introducing Goggles

kenbot/goggles: Pleasant, yet principled Scala optics DSL

Monocleを強化してstring interpolatorとして利用できるようにしたものについて。

公式のサンプルから例を拝借すると、以下のようにgetter/setterを実行できる。
なかなか変態チックですね。

get"$myBakery.cakes*.toppings[0].cherries"
set"$myBakery.cakes*.toppings[0].cherries" := 7

setは内部的にはcase classのcopyを呼んでいるが、ネストしたcase classのcopyを意識せずに済む上に、*[0]でループ処理やindex指定できる、さらに?Optionなオペレータを提供していたりと非常に便利。

Mastering Typeclass Induction

資料: Mastering Typeclass Induction

Listを再帰的に型レベルで処理していく手法について。

val x: Named[(Int, (String, (Char, EOL)))] = ???
f(x)
// "int, string, char,"

簡単に言うとこの例のfをどのように実装するか、という話。 数学的な帰納法と型クラスを使って実現していました。

値について再帰的に処理するのではなくて、型そのものに対して再帰的に処理するインタプリター的なものを実装するという観点がなく、非常に新鮮でした。

Do it with (free?) arrows!

資料: Do it with (free?) arrows! (1))

WhatとHowを分離させる宣言的プログラミングの話から始まり、Applicative Functor, Monad, Arrowだとどう実現できるかという話でした。

Monadだと失敗ケースで畳み込んでしまって蓄積できないデメリットがあるが、Applicative Functorだと表現力が足りない。
そこでArrow、さらにChoiceを使うとそのようなニーズを完全に満たすことが出来るそうです。

やや難しいですが、使ってみるだけならそこまで難しくはないかもしれないですね。

感想

ScalaDaysが幅広いScala開発者を対象とした大規模なイベントだったのに対して、Typelevel Summitは関数型プログラミングな開発者に絞ったイベントだったので、人数が少ない分内容も濃くて非常に楽しかったです。
初心者お断りなトークを英語で聞いて理解が非常に怪しいので復習します…。

ちなみにランチタイムはビュッフェ形式で豪華な食事もあり、着席するスタイルでした。
テーブルはこんな感じ。 f:id:fringeneer:20170629105558j:plain

いつか海外カンファレンスでトーク出来るように頑張ります。

ScalaDays@コペンハーゲンに参加してきました!

Fringe81株式会社でエンジニアをやっている小紫(@petitviolet)です。
このたびFrigeneer(Fringe81のエンジニア)で技術ブログを開設しました。

記念すべき第一回目として、5/30 ~ 6/4で海外出張としてデンマークコペンハーゲンまではるばる行ってきた話をします。

f:id:fringeneer:20170608230008j:plain

  • 5/31~6/2がScalaDays

http://event.scaladays.org/scaladays-cph-2017/

  • 6/3がTypelevel Summit

まずはScalaDaysで聴いた発表についてのメモ、コメントです。 英語の理解が追いついていないところも多々あり、誤っている可能性もあります。

ScalaDays

f:id:fringeneer:20170608230009j:plain

Odersky先生のkeynoteから始まる3日間のイベントとなります。

What’s Different In Dotty

Odersky先生によるDotty講座。
今回の発表で初めて知ったのがtype lambdaとenumサポートでした。

type lambdaについてはこちらの論文に詳しく書いてあります。
Implementing Higher-Kinded Types in Dotty - dotty-hk.pdf

type Pair[A, B] = (A, B)

↑が↓のように書けるということっぽい。

type Pair = A => B => (A, B)

type projection(Hoge#Foo)が廃止されることによる影響でしょうか。

enumは今までsealed traitcase classcase objectでADTで表現してきたやつが言語としてサポートされるようになるということで嬉しいですね。
このenumを使うと、例えばOptionは以下のように表現できるらしいです。

enum Option[+T] {
  case Some[+T](value: T) // case classになる
  case None // case objectになる(パラメータを取らないため)
}

implicit functionとか型推論の強化とかもあってDottyに対する期待がどんどん上がっています。
早くproduction readyになって業務で使いたいところですね。

8 Akka Anti Pattern

資料: Scala Days Copenhagen - 8 Akka anti-patterns you’d better be aware of

Akkaを使う際の8つのアンチパターンについて。

  • Global mutable state
  • flat actor hierarchies
  • too many actor systems
  • Logging(the wrong way)
  • being out of touch with ther hardware
  • blocking
  • re-inventing akka tools
  • using java serialization

Akka使ったことあれば納得感はあるかなと思います。
Q&AでAkka-Agent使うのどう?っていう質問に対して聴衆の一人がdeprecatedだよ、って返してたのが驚きです。
知らなかった…。 便利そうだしどこかで使えるかなとか思ってましたが、deprecatedと明記してあるので使わないまま終わってしまいました。
Agents • Akka Documentation

Building code analysis tools at Twitter

シカゴでの発表資料:2017-04-21-SemanticToolingAtTwitter.pdf
Twitter社におけるコード解析ツールの話。

全体構成として、mono-repoにしてあってCIをやりやすくしているし、噂は間違っていて今もバリバリScala書いてるよ!という前提から始まりました。

scalametaのsemantic-api, semantic-dbやgoogle/kytheを使った例を紹介していました。

チェックできていませんでしたが、scala.metaの最新版でsemantic-apiが入っていたらしいです。
scalameta/1.8.0.md

Compiling like a boss

Triplequoteのお二人。 hydraというScala Compilerを使えばScalaコンパイルが速くなって最高!という内容。
マルチコアをフル活用してコンパイル速度を上げているようです。

とりあえず憶えておけば良いのはこの2つかと。

  • scala2.12は2.11より20%ほどcompile速くなっているよ
  • implicitの解決に時間かかるからワイルドカードimportやめよう

裏側はともあれコンパイル早くなるならチーム全体の生産性にも直結するので嬉しい話ですね。
sbt integrationとかcommand lineサポートとかもあって、とりあえずローカルで試せるようになったらもう少し追いかけます。

Adventures in Meta-Programming Macros vs Shapeless

Underscoreの人。
発表資料

ボイラープレートの削減やDSLの実装にはMacroとShapelessが使える。 davegurnell/macros-vs-shapeless: Slides and code samples on meta-programming techniques in Scala.

例としてインスタンスの自動生成やvalidationロジックにおけるフィールド名へのアクセスなどを通して、
それぞれのメリット・デメリットをまとめて紹介していました。

最後のまとめはこちら。

  • macros are good for syntactic stuff
  • shapeless is good for structural stuff

ボイラープレートの削減に対するアプローチの違いによって、どちらを採用するかを決められるようになりそうです。
どちらも便利だけど銀の弾丸ではないので注意しましょう。

ADTs for the win

47degreesの人。
資料: ADTs For The Win!
Algebraic Data Typeの話でした。

ドメインモデルもtupleで型として表現出来なくはないが、
case classとして実装することによって、その型のtupleに対して命名出来て網羅性も担保出来て型は便利。

Optionとかはfoldメソッドがあり、Someなら…とNoneなら…を簡潔に表現できるようになっています。
じゃあドメインモデルに対してもfoldを実装してみよう、という話で確かに便利そう。
パターンマッチよりもAPIとして実装の網羅性を強制出来るのが利点ですね。

以下のような実装イメージになりそうです。

sealed trait DatabaseResponse {
  def fold[A](fi: (Boolean, Int) => A, fe: String => A): A = ???
}
case class Invoice(paid: Boolean, price: Int) extends DatabaseResponse
case class ErrorMessage(description: String) extends DatabaseResponse

The best is yet to come State of Akka 2017

konrad氏。
資料: State of Akka 2017 - The best is yet to come

Akkaプロジェクトの総復習っぽいイメージの発表でした。
Scalaカンファレンスではありますが、Scala APIだけでなくてJava APIもしっかり作ってるよ、とのこと。

ざっくりまとめるとこうでしょうか。

あとはマルチデータセンターでAkkaを使うところがあるらしいが、それに対するサポートは今のところお手上げ?
どうしていいかわからないので、もっとユースケースを聞きたいらしいです。

懇親会

食事もアルコールも沢山出て、IntelliJやSAPなどが企業ブースを出してました。

f:id:fringeneer:20170608234150j:plain

Managing Consistency, State and Identity in Distributed Microservices

LightBendの人。

Microservicesは、独立したチームで独立したサイクルで開発できるものであり、自律的に協調する分散サービスと定義していました。

Microservicesにしておけば、各コンポーネントにおいて必要なデータのことだけ考えればよくなります。
そうなるとbounded context(境界付けられたコンテキスト), consistent boundaries(整合性境界)を考えなければいけないですが…

  • 世の中のシステムは意外と結果整合で問題ないようになっている。
  • さらに、Databaseのデータはlogのサブセットでしかない

という理由から、EventSourcingが解決策になるのでは、とつながっていきます。

たとえばショッピングカートを作るにあたって、途中で削除された商品のデータが欲しい、となった場合に
CRUDで現在の状態を保存するように実装していたらそのデータを抽出するのは不可能だが、ESなら簡単に実現できるなど、ESの利点を説明していました。

Reification and type-safety in a CQRS world

CQRS界隈だとフレームワークを作るなと言われているが、Scala開発者向けに作ってしまった人だそうです。
Fun.CQRS

CommandとEventを扱うDSLを型安全に作るためのフレームワーク
ブログに詳しく書いてあります。
Building a CQRS / ES Framework (part 1)

使い方としては、
domainモデルのもつメソッドをCommandとして切り出し、その振る舞いの結果をEventとして定義する、というのが基本になるようです。

type parameterとtype projectionとpath dependent typesの3パターンで実装してみて、それぞれのメリットデメリットについて説明していました。
型合わせで大変そう…。

Uniting Church & State OO vs FP

underscoreの人。
noelwelsh/church-and-state: Unifying Church and State

  • Classical OO
    • operatorの追加は容易
      • メソッドを追加するだけ
    • actionの追加が難しい
      • BigDecimalで計算するように変更する、とか?
  • Classic FP
    • Data型で振る舞いを定義して、interpreterで実装する
    • actionの追加は容易
    • oepratorの追加が難しい

whatとhowを分離したい。
そのためにはFPの力が必要だが、FPだと中間データ型が必要になる分、OOよりもパフォーマンス観点でコストが高い、という問題があります。

その解決のために、ChurchEncodingとtype classを使って実現する!というストーリーでした。
(church-encodingがわからず、この辺から置いて行かれた)

Beyond the Build Tool

Tapadの人。

sbtを再評価する内容。
sbtは、ただのツールじゃなくて、ツールの土台になる可能性があるものとのこと。

sbtに対するレベル感は以下のように段階があるそうです。

初期段階はscalaを書いていれば誰しもクリアしているとは思いますが、プラグインを使ってみたりタスク書いてみるところから、
少しずつやれる範囲を広げていきましょう。

公開されているsbt pluginはたくさんあって、ここで見れます。
sbt Reference Manual — Community Plugins

よく使うやつ(?)はこの辺りだそう。

  • sbt-dependency-graph
  • sbt-assembly
  • sbt-release
  • sbt-docker
  • sbt-twirl
  • sbt-buildinfo, sbt-doge

使うのに慣れてきたら作る側に回り、そのときにはBestPracticeを読みましょう。
sbt Reference Manual — Plugins Best Practices

所感

発表とか懇親会を通して世界のScala状況みたいなのを何となく感じることが出来ました。
Odersky先生からDottyの話やLightbendからのAkkaの話など、海外カンファレンスだと作者にあたる人がばんばん出てきて良いですね。

大雑把にはMicroservicesやCQRSなどのシステムアーキテクチャのような話、Akkaやsbtなどのツール・ライブラリの使い方、FPな話が主流でしたが、 日本で盛り上がっているDDDについては恐らく発表が無かったのが意外でした。

コペンハーゲンの人もカンファレンスの参加者も皆とても優しく、楽しく過ごすことが出来ましたが、英語力が足りずに思うようなコミュニケーションを取れないこともあったので、Scalaだけでなくて英語も頑張りたいなと思います。