独学大学情報学部

主にScala、たまにHaskell、稀に数学

近況とか

aoino.hatenablog.com

以降の話をハイライトでお伝えします。 この記事は Scala関西Summit 2017 の資料作成に追われる現実逃避息抜きに書いています。

旅行と飯と酒と Switch しかありません。進捗はどこに行ったのでしょうか。

退職します

ちょっと数日たってしまいましたが、日記です。

マーベリック株式会社を退職します。 5/2 が最終出社日で、5/31 が退職日です。

例のアレです↓ http://www.amazon.co.jp/registry/wishlist/3C4T2LY4FGFR6/ref=cm_sw_r_tw_ws_x_VJddzb0XGN15T

何してる人?

猫が大好きな、東京都内で Scala 書くお仕事してる人です。 Lens の話してたり Monocle ってライブラリのコミッターだったりする人です。 あと、猫が大好きです。

振り返って

振り返ってみて、自由な社風でとてもいい会社だったなと思ってます。 自分がコミッターになったのも、思い返してみれば OSS 活動に対する理解があった故でしたし。 直近ではとあるシステムの要件定義から始まり、構成考えてミドルウェアの検証したのち、 実装から各種テスト、デプロイ体制の整備あたりまで一通り担当できてとても自信に繋がりました。 開発/運用、アプリ/インフラなどなどにおける垣根や柵が(いい意味で)ほぼ存在してないので、 入社してから約二年半という短い期間で様々なことに取り組めましたしとても素晴らしい経験をすることが出来ました。

では何故?って話ですが、自分が数年間隔で考えてる将来の展望と比較して所謂音楽性の違い(?)みたいなのがあったのと、 長期的な観点で考えた時に環境を変えて新たな業種での開発もしてみたいと思ったのが理由です。

前向きなので特別なネタは無いですが、そのあたり聞きたい方は肉or寿司の場で(ぇ

まとめとか

とりあえず5月一杯の有給消化期間を全力でまったりと(?)進捗を出していこうかなと思っています。 次どこで何をするかは諸々確定してから改めて書く予定です。

お世話になった皆さん、本当にありがとうございました。 今後とも引き続きよろしくお願い致します。

Scala関西 Summit 2016 で Lens/Prism について発表してきた

日付変わってしまいましたが、Qiita 版 Scala Advent Calendar 2016 の12日目の記事です。

前日: grimrose さんの ScalikeJDBCを使ってAmazon Athenaへアクセスしてみた
翌日: jwhaco さんの いい感じの sbt パーサを作る

blog 記事を書くまでがイベントです。 とても遅くなってしまいましたが、10/8 に開催された Scala関西 Summit 2016 のレポートです。

Scala関西 Summit 2016 とは

関西最大級の Scala カンファレンスで、2015年に初開催。今年で二回目です。
イベントページはこちら↓↓↓

summit.scala-kansai.org

発表内容とか

タイトルは「今から始める Lens/Prism」です。
資料は SlideShare に上げてありますので見直したい方はどうぞ。

www.slideshare.net

以下、思い出とか発表の背景とか。

資料は reveal.js 使って作成しました。 当日はブラウザで index.html を開いて発表しようと考えていたんですが試しにプロジェクターと接続した瞬間レイアウト完全崩壊。 本番では発表15分前になんとなく PDF にして SlideShare に上げておいた奴を使って事なきを得たので、事前の準備大事ですよ!!!という教訓...*1

今回の発表は 46, 47 ページを境にざっくり前半と後半部分に分かれています。 前半部分は Scala で Lens/Prism を使う際のモチベに始まり、getter/setter を抽象的に考えていって Lens を導入。 法則やら合成やら Prism やら Optics Hierarchie やらをざっとなぞって完。 そして後半に「今から始める〜」とか入門編みたいなタイトルにしておきながら基礎理論的な内容として van Laarhoven Lens の話をしました。 後半に関しては正直なところ入門的な話の後にする内容ではないとは思っていたのですが、 それ以上に自分が理解した時のテンション&概念の面白さを伝えたかったのと、 途中に出てくる traverse 関数から map と foldMap を導出する話が Scala 関数デザイン&プログラミングの 12章で語られていて、 書籍からの一歩進んだ応用例みたいな位置付けとして面白そうだなと思い盛り込む事にしました。 振り返ってみると、結果的に内容に緩急もついて良かったんじゃないかなと思ってます。

他に時間やら理解度やらの都合で話せなかった Lens の歴史や別な実装である Store Commonad Lens の話などなど、 色々と面白くて興味深い内容もまだまだたくさんあるので機会があれば関連内容でまた発表したいですね。 例えば、タイムテーブルも公開され始めた 2/25, 2/26 に東京国際交流館で開催される ScalaMatsuri 2017 の二日目、アンカンファレンスとかいいかもしれませんね!!!!!

本当に発表するかはさておき、とても面白い分野(?)なので来年も引き続きお金のかからない Lens 沼に浸っていられそうな気がしています。

まとめ

関西 Scala コミュニティの盛り上がりをすごく感じましたし、とても楽しく充実した1日を過ごせました。 スタッフの皆さん本当にお疲れさまでした。ありがとうございました。次回の開催も心より楽しみにしております!

Special Thanks

開催前日に @kawachi さんと @lyrical_logical さんより資料や発表の構成についてアドバイスを頂きました。特に @lyrical_logical さんには文章や細かい言い回しから理論的な監修に至るまで長時間おつきあい頂きました。 お二人のアドバイスがなければあの資料は完成しませんでした。本当にありがとうございました。

*1:今回は資料を発表直前まで弄っててその辺怠ってた...今までは何もなかった慢心...

Imp と implicitly

かなり遅刻してしまいましたが、Adventar 版 Scala アドベントカレンダーの2日目です。

前日: Typelevel.scala Projects Stickers が欲しい
翌日: so_zaneli さんの finagle-toggleでデプロイとリリースを分離する

今回は implicitly と Imp ってライブラリ話を書こうと思います。

implicitly is slow

implicitly はご存知ですね。Scala 標準ライブラリの Predef に以下のように定義されています。※ 2.11.8 時点。

@inline def implicitly[T](implicit e: T) = e

要するに型パラメータを明示的に指定してスコープ内に定義されている指定した型の暗黙的な値を取得する為のメソッドなわけですが、 こいつは大抵以下のように使われて(理屈上では?) implicitly の処理分遅いよねって話があります。

def fast[A](implicit ev: Monoid[A]): A =
  ev.empty

def slower[A: Monoid]: A =
  implicitly[Monoid[A]].empty

def alsoSlower[A: Monoid]: A =
  Monoid[A].empty // without imp

※ cats, spire の作者 Erik Osheim さんの Scala World 2015 での発表資料の84枚目より。

alsoSlower 内の Monoid#apply も資料内に定義は書いてありませんが恐らく

def apply[A](implicit A: Monoid[A]): Monoid[A] = A

あたりで implicitly と同様な実装になってることでしょう。 これも結果的には alsoSlower 内で implicitly と同様の apply 処理分遅くなります。 そして、こういった無駄な処理を削りたい!って思った時に同氏作の Imp ってライブラリを使うと良いよって話です。

Imp とは

どんなライブラリかと言うと README に書いてある下記一行で全てです。

It provides a zero-cost macro to summon implicit values.

実装もとてもシンプルでコメントや import を無視すると実装自体は実質二行。

def imp[Ev](implicit ev: Ev): Ev = macro summon[Ev]

def summon[Ev](c: Context)(ev: c.Expr[Ev]): c.Expr[Ev] = ev

要するに macro を使って compile 時に暗黙的な値をそのまま置き換えて(召喚して)しまうというわけです。 使い方も README に書いてある通りとても簡単。

念のため typer phase で確認してみましょう。 適当に以下のようなコードを書いて、Show#apply の実装を書き換えて compile してみます。

class Foo()

trait Show[A] {
  def show: String
}

object Show {

  def apply[A: Show]: Show[A] = implicitly[Show[A]]
  //   or
  def apply[A: Show]: Show[A] = imp.imp[Show[A]]

  implicit val showFoo: Show[Foo] = new Show[Foo] {
    def show = "foooooooooooooo"
  }
}
  • implicitly
  object Show extends scala.AnyRef {
    // ...
    def apply[A](implicit evidence$1: Show[A]): Show[A] = scala.this.Predef.implicitly[Show[A]](evidence$1);
  • imp
 object Show extends scala.AnyRef {
    // ...
    def apply[A](implicit evidence$1: Show[A]): Show[A] = evidence$1;

implicitly と用いた場合は apply の引数が implicitly メソッドに渡されてますが、imp を用いた場合は apply の引数がそのまま返されています。 これで implicitly の呼び出し分早くなるよ、やったね!!

implicitly も実質ゼロコスト?

喜びも束の間。近年の Hotspot の最適化の前には Imp 不要では?という話が。 README の Known Issues ってところに書いてある一文を引用します。

Dmitry Petrashko has argued persuasively that modern Hotspot optimizations mean that Imp is unnecessary. See the imp-bench repository for more information on his benchmarks.

Dmitry Petrashko*1 さんの jmh を使った benchmark

によると、Hotspot の最適化でもって implicitly も単純な値の呼び出しに置き換えられるという話が書かれているっぽいです。

せっかくなので自分の環境でも試してみました。 実行環境は以下の通り。

  • OS: OS X Yosemite 10.10.5
  • CPU: 3 GHz Intel Core i7
  • メモリ: 16 GB 1600 MHz DDR3

で、実行結果が以下の通り。baselineimplicitly で、measureimp の結果です。

[info] Benchmark                                 Mode  Cnt  Score   Error  Units
[info] addable.ImplVsImplicitlyAddable.baseline  avgt   30  2.444 ± 0.070  ns/op
[info] addable.ImplVsImplicitlyAddable.explicit  avgt   30  2.649 ± 0.215  ns/op
[info] addable.ImplVsImplicitlyAddable.imply     avgt   30  2.554 ± 0.135  ns/op
[info] bench.ImplVsImplicitly.baseline           avgt   30  3.025 ± 0.050  ns/op
[info] bench.ImplVsImplicitly.measure            avgt   30  2.905 ± 0.020  ns/op

うぅm、README の Result とは微妙に差のある結果ですね。 Error 率も差があまりないようですし、間違ってはなさそうな気もしますが...。 この最適化の方の話については別な日に詳しく追うことにします... *2

まとめ

Hotspot の最適化も優秀っぽいけど、最適化に身を委ねたくない人は Imp を使うと良いんじゃないでしょうか?

*1:EPFL Scala Team の一人。記事公開時点で dotty の commit 数2位。

*2:記事を書くとは言っていない?

Typelevel.scala Projects Stickers が欲しい

この記事は ADVENTAR 版 Scala Advent Calendar 2016 1日目の記事です。 明日もあたしです。埋まらないのは悔しいので極力埋め作業しようと思いますが、全然ウェルカムなのでどうぞ。

初日なので(?)一切 Scalaソースコードが出てこない記事です。

Typelevel.scala Projects Stickers って?

とても cooool ですね。欲しくなりましたね?

注文したい

Typelevel のトップページ -> About から stickermule ってページに飛べます。 www.stickermule.com

好きなステッカーをポチポチして右側の checkout で住所入力画面に飛びます。 住所の入力方法は↓あたりを参考にするといいと思います。

注文ボタンを押すと、入力した住所の確認モーダルが表示されるので改めて正しく入力できてるか確認しましょう。

ってことで、一通り全種類注文してみました。 予定だと16日に届くらしいので楽しみですね。到着したらまた記事書けますし(ぇ

f:id:Aoino:20161201221148p:plain

まとめ

この前に書いた記事が昨年度末の Advent Calendar なので、ほぼ一年間自分のブログでは何も書いてないことに気づいた。