The Type Astronaut's Guide to Shapeless

先日Scala eXchangeに参加して、海外での予想以上のShapelessの人気ぶりを目の当たりにしたのでちょっと勉強してみようと思い、Underscore社が提供している「The Type Astronaut's Guide to Shapeless」という本を読んでみました。

Underscore社のWebサイトからは電子版を無料でダウンロードできますし、ペーパー版も有料でオーダーできます。また、ペーパー版はAmazonなどでも購入できます。

The Type Astronaut's Guide to Shapeless

The Type Astronaut's Guide to Shapeless

  • 作者:Gurnell, Dave
  • 発売日: 2017/05/04
  • メディア: ペーパーバック

ちなみにこの本はオープンソースで原稿自体はGitHubで公開されています。

github.com

Shapelessはケースクラスやシールドトレイトを使った列挙型で表現される代数的データ型に対してHListと型クラスを使ってジェネリックなプログラミングを可能にするライブラリで、うまく使いこなせばJavaではランタイムリフレクションを使わざるを得ないような処理をタイプセーフに記述することができる非常に便利なライブラリです。

この本は実用的な例を題材にShapelessの基本的な使い方を説明していくというものなのですが、分量も100ページ程度と少なめですし、英語も平易かつコードも多めなので読みやすいです。Scalaに関する知識がそれなりにないと理解が難しいとは思いますが、Shapelessでこういう書き方をするのは何故なのか?ということが順を追って説明されているのでShapelessがどういうものかを押さえるには良いガイドだと思います。

ただ、Shapelessの機能やShapelessを使ったコードの書き方自体がScalaの制約から来ている部分が多く、読んでいて結構つらみを感じました。とはいえDependent TypesなどIdrisにも通じる部分もあり、個人的には興味深く読み進めることができました。面白いライブラリなので使う使わないは別として是非一度触れてみて欲しいです。

2017年の振り返り

2017年もいろいろありました。今年も恒例の振り返りをしてみたいと思います。

f:id:takezoe:20171222150416j:plain

仕事関係

今年はサービスから離れてしまったのであまり自分でがっつり開発するという感じではなく、他のチームのサポート的な感じだったのですが、技術的な部分以外で悩むことが多かったような気がします。ただ、やはりサービスの運用から離れたことで以前と比べると時間的には余裕ができたかなと思います(今年は終電で帰ることもほぼなかったw)。

後述の執筆活動やOSS活動とも絡むのですが、業務に関連するものとしては、会社の若者たちと本を出したり、Apache PredictinIOのコミッタになれたのは目に見える結果としてよかったです。あと、社内ではType-Driven Development with Idrisの読書会に参加していました(4月からやってるのですが、まだ読み終わる気配がない…)。

takezoe.hatenablog.com

来年は仕事でも新しいことをやりそうな感じなので、またちょっと違う感じになるかもしれません。

イベント関係

今年はScala関係のイベントに多く登壇させていただきました。特に年末にはリヨンで開催されたScalaIO、ロンドンで開催されたScala eXchangeと海外でのカンファレンスでそれぞれショートセッション、ライトニングトークですが発表の機会をいただきました。

ScalaMatsuriではScala Warriorの発表をさせていただきました。ScalaIOで「この時の発表を見たよ!」という方がいらっしゃって驚きました。

takezoe.hatenablog.com

Scala福岡ではApache PredictionIOの紹介をさせていただきました。福岡に行くのは中学生ぶりくらいだったのですが、博多駅がすごい近代化されていて驚きました。

takezoe.hatenablog.com

Scala関西サミットは気合いの日帰り参加。GitBucketでスポンサーもさせていただきました。

takezoe.hatenablog.com

ScalaIOでは初めてのフランス訪問だったのですが、滞在中に駅が何度も封鎖されていてびびりました。GitBucketのユーザさんが何人かいらしてお話しすることができました。

takezoe.hatenablog.com

Scala eXchangeではGitBucketの紹介をさせていただきました。JGitに関して質問してくださった方がいたのですが、うまく答えられなかったかも。ロンドンでは愛するアーセナルの本拠地エミレーツスタジアムのツアーに参加してきました。

takezoe.hatenablog.com

takezoe.hatenablog.com

Scala関西で今年は終わりかなーと思っていたところに立て続けにScalaIOとScala eXchangeのCFPが採択され、11月、12月と連続してのヨーロッパ渡航だったのでちょっと体力的にしんどかったです。英語力に関しては相変わらず改善の必要性を感じました。

執筆活動

昨年から会社の若者達と執筆していたクローリングハックという本を出すことができました。途中でいろいろあって1年くらいかかってしまいました。体力的な問題から書籍の執筆は年々厳しくなっていきますね…。

takezoe.hatenablog.com

また、今年は久しぶりにSoftware Designさんで記事を書かせていただきました。Git特集の一部でGitHub、BitBucket、GitLab、GitBucketを比較するというものです。

takezoe.hatenablog.com

あと、実作業としては何もしていないのですが、Akka in Actionの翻訳版の企画に関わらせていただきました。数年前から翻訳できないかと検討していた本なので形にしていただくことができてよかったです。

takezoe.hatenablog.com

OSS活動

今年はかなりアクティブに活動できたかなと思います。大きなところでは前述の通り、Apache PredictionIOのコミッタになりました。プロジェクト自体もIncubatorを卒業してトップレベルプロジェクトになることができました。多少なりとも貢献できたのではないかと思います。

takezoe.hatenablog.com

takezoe.hatenablog.com

Scalatraの開発もかなり進めることができました。Webサイトをhugo + GitHub Pagesへの移行をはじめ、magnolia-kさんがコミッタになっていただき、約1年ぶりのメジャーバージョンアップであるScalatra 2.6を無事リリースすることができました。新しいバリデーションフレームワークの追加や、各所に手を入れて不要そうな機能の整理、パフォーマンスの改善などを行っています。

takezoe.hatenablog.com

takezoe.hatenablog.com

GitBucketも引き続き月一回のリリースを継続しています。CIプラグインなど新しいプラグインもいくつか作ることができました。aadrianさんkounoikeさんにコミッタになっていただいたり、Scala関西サミットではスポンサーをさせていただいたり、ScalaIOでは海外のGitBucketユーザさんと会話をしたり、Scala eXchangeでGitBucketの発表をさせていただいたりなど、開発以外の部分でもいろんな活動ができたかなと思います。

その他では、AlpakkaにElasticsearchコネクタをコントリビュートしたり、elasticsearch-hadoopScala部分のコードを直したり、PlayでZipkinを使うためのplay-zipkin-tracingというライブラリを同僚から引き継いでOSS化したりしていました。play-zipkin-tracingではZipkinの開発者であるAdrianさんとのやり取りもあって刺激になりました。

takezoe.hatenablog.com

takezoe.hatenablog.com

まとめ

今年は仕事が一段落したこともあり、個人の活動に時間を使うことができたかなと思います。PredictionIOはもうちょっと普及させていきたいところではありますが、機械学習周りやSpark周りなど知識不足を感じるのでその辺は勉強しないといけないかもしれません。インフラ周りも自分で触る機会が増えそうなのでキャッチアップしていかないといけないですね。また、意図的に増やしている面もありますが、英語を使う機会も増えてきているのでこちらの勉強も引き続きやっていきたいと思います。

教養としてのScala勉強会に参加しました

会社の若者たちがScalaの勉強会を開催していたので私もお呼ばれして参加してきました。

d-cube.connpass.com

私は「頑張りすぎないScala」という発表をさせていただきました。

www.slideshare.net

これはScala関西で発表させていただいた「Non-Functional Programming in Scala」の内容をベースにしたものなのですが、Scala関西ではすでにScalaをやられている方を想定してお話しさせていただいたのに対し、今回はこれからScalaを始める方向けに修正しています。また、Scalaをどのように使うべきかという問題に関しては最近いろいろと考える機会があり、その結果も反映したものになっています。

若者たちがScalaをどのように学習したか(参考になった教材や勉強法など)、これからScalaを始める際に知っておいた方がよいことなどの発表もあり、これからScalaを始める人だけでなく、逆にScalaを教える際の参考にもなりそうです。最近のScala界隈の話題は高度化しすぎているきらいがあるので、こういう初心者向けのScala勉強会ももっと増えていくといいなと思います。

ところでちょうどManningから新しいScalaの入門書の出版がアナウンスされました。こちらはオブジェクト指向プログラミングから入って関数型プログラミングのエッセンスを学ぶ、という流れになっているようです。

www.manning.com

アーリーアクセスが始まったばかりなので完成までまだしばらく時間がかかるのではないかとは思いますが、現状では洋書でもなかなか良いScalaの入門書が存在しない状況なのでこの本には期待したいところです。

GitBucket 4.20.0をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.20.0をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.20.0

プルリクエストのマージ時にSquashもしくはRebaseが可能に

プルリクエストをマージする際に以下の3つのオプションからマージ方法を選択できるようになりました。

  • Merge commit: マージコミットを作成してマージします(従来通りのマージ)
  • Squash: コミットは1つにまとめられてベースブランチに追加されます
  • Rebase: マージコミットを作成せずにベースブランチにrebaseします

f:id:takezoe:20171222145441p:plain

クイックプルリクエス

リポジトリにプルリクエスト可能なブランチがある場合、リポジトリビューアの上部にプルリクエストを作成するためのボタンが表示されるようになりました。このボタンを使うとワンクリックでプルリクエエスト作成画面に遷移することができます。

f:id:takezoe:20171222145420p:plain

パッチファイルのダウンロード

差分ビューに表示している差分をパッチファイルとしてダウンロードするためのPatchボタンが追加されました。

f:id:takezoe:20171222145405p:plain

差分が巨大な場合、GitBucketはブラウザ上で差分のグラフィカル表示を行わないようになっていますが、その場合でもこのボタンでダウンロードしたパッチファイルを参照することで差分全体を確認することができます。

リポジトリの作成、フォークが非同期に

これまでのGitBucketでは特に巨大なリポジトリをフォークする際、リクエストのタイムアウトが発生してしまうことがありましたが、これを避けるため、今回のバージョンからリポジトリの作成、フォークを非同期で行うようにしました。

f:id:takezoe:20171222145519p:plain

既存のgitリポジトリからのリポジトリ作成

リポジトリの作成時に既存のgitリポジトリのURLを指定し、そのリポジトリの内容をコピーして作成できるようになりました。すべてのブランチ、タグも新しいリポジトリにコピーされます。

f:id:takezoe:20171222145553p:plain

サイドバーがオーバーフローした場合の表示の改善

リポジトリ名が長い場合、これまではサイドバーからはみ出て表示されてしまっていましたが、省略して表示するようになりました。

f:id:takezoe:20171222145613p:plain

WebフックでCreateEventをサポート

WebフックでCreateEventのサポートが追加れました。

プルリクエストでコンフリクトしたファイルの表示

プルリクエストがコンフリクトして自動マージできない場合、プルリクエストのステータス領域にコンフリクトしたファイルの一覧が表示されるようになりました。

f:id:takezoe:20171222145626p:plain

今回のバージョンではこの他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

Scalaで型クラスをメタプログラミングできるライブラリMagnoliaを使ってみる

MagnoliaはScala界隈ではおなじみのJon Prettyさん作のライブラリで、簡単に言うとケースクラスに対する型クラスのインスタンスを生成するためのマクロを簡単に実装できるライブラリです。Play-JSONReadsWritesFormatなどのマクロなどを簡単に作れるものというとわかりやすいでしょうか。Scala eXchange 2017のとあるセッションでちょっとだけ紹介されていて面白そうだったので軽く触ってみました。

github.com

わかりやすい例としてケースクラスの内容を文字列表現に変換するShowという型クラスを作ってみます(ScalaのケースクラスはtoStringするだけで十分わかりやすい出力を得ることができるので敢えて作る必要はないのですがMagnoliaのドキュメントにも書かれているので練習ということで…)。

まずは以下のトレイトを定義します。

trait Show[T]{
  def show(value: T): String
}

Derivationというオブジェクトを以下のような感じで実装します。

import language.experimental.macros, magnolia._

object ShowDerivation {
  type Typeclass[T] = Show[T]

  def combine[T](ctx: CaseClass[Show, T]): Show[T] = new Show[T] {
    def show(value: T): String = {
      ctx.parameters.map { p =>
        s"${p.label}=${p.typeclass.show(p.dereference(value))}"
      }.mkString("{", ",", "}")
    }
  }

  def dispatch[T](ctx: SealedTrait[Show, T]): Show[T] = ???
  
  implicit def gen[T]: Show[T] = macro Magnolia.gen[T]
}

見た目でなんとなくわかると思いますが、combineメソッドにケースクラスに対するshowメソッドの実装が記述されています。decodeメソッドはsealedトレイトを扱わない場合は実装しなくても大丈夫です。今回はMagnoliaでどんなことができるかを見るだけなので???にしておきます。

定義したShowDerivationオブジェクトを実際に使ってみましょう。以下のようなケースクラスと関数を用意しておきます。

// ケースクラス
case class Address(zipCode: String, country: String, prefecture: String)
case class Person(name: String, address: Address)

// Showを使ってケースクラスの内容を出力する関数
def printCaseClass[T](value: T)(implicit s: Show[T]): Unit = {
  println(s.show(value))
}

この関数を呼び出してみます。

// 基本的な型に対するインスタンスは自前で実装しておく
implicit val showString = new Show[String]{
  override def show(value: String) = value
}

// ケースクラスに対するインスタンスはgenマクロで生成可能
implicit val showAddress = ShowDerivation.gen[Address]
implicit val showPerson = ShowDerivation.gen[Person]

// ケースクラスのインスタンスを生成してメソッド呼び出し
val person = Person("takezoe", Address("150-0013", "Japan", "Tokyo"))
printCaseClass(person)

出力は以下のようになります。

{name=takezoe,address={zipCode=150-0013,country=Japan,prefecture=Tokyo}}

このようにMagnoliaを使うと自前でマクロを書くのに比べると簡単に型クラスのインスタンスを生成するマクロを定義することができます。GitHubリポジトリにはサンプルもいくつか含まれているので参考になると思います。

性質的にアプリケーションコードではなくライブラリやフレームワーク側で使うものだと思いますので利用頻度はさほど高くないかもしれませんが目の付け所が面白いライブラリですね。

ロンドンでエミレーツスタジアムツアーに参加してきました

Scala eXchange 2017参加のため13年ぶりにロンドンを訪れたわけですが、観光する時間があったので愛するアーセナルの本拠地エミレーツスタジアムのスタジアムツアーに参加してきました。

f:id:takezoe:20171218162223j:plain

スタジアムには巨大なショップが併設されており、ユニフォームを始めいろんなグッズが購入できます。試合のない日ですが休日ということもあり、多くの方が訪れていました。店員さんにキャプテン翼のキャラは日本語名だと発音しにくいからヨーロッパでは別の名前になっているんだよということを教えてもらうなどしました。

以下、スタジアムツアーの様子です。まずは来賓など偉い人たちが観戦するディレクターズボックス。リッチ。

f:id:takezoe:20171218162322j:plain

ディレクターズボックスからピッチを見たところ。さすが偉い人用、座席も一般客用のプラスチックの硬い椅子ではなくなんかフカフカしてます。

f:id:takezoe:20171218162503j:plain

無敗優勝のときのトロフィーが展示されていました。あれからもう13年も経つのか…。

f:id:takezoe:20171218162605j:plain

ホームチームのシャワールームにはお風呂がついてます。アウェーチームとの格差がすごい。

f:id:takezoe:20171218162658j:plain

シャワールームの先にはホームチームのロッカールームが。コンビを組む選手たちが隣になるように配置されているらしい。アウェーチームのロッカールームにはない座布団があります。柔らかいです。座っていても血行が良くなるらしい。

f:id:takezoe:20171218162827j:plain

こちらは攻撃陣。サンチェスとエジルは移籍してしまうのでしょうか…。

f:id:takezoe:20171218162917j:plain

Arsène Wenger's Office。

f:id:takezoe:20171218163045j:plain

広い。試合の前後はここでコーチ陣と相談したりするらしい。寒い季節、試合中ベンゲルが着ているダウンのコートがかけられています。

f:id:takezoe:20171218163210j:plain

選手たちはここを通ってピッチに向かいます。

f:id:takezoe:20171218163333j:plain

そしてついにピッチに!ちょうど雨が降ってきて椅子にビニールシートが被せられてしまい、監督席に座ることはできませんでした。無念。ちなみに監督やコーチ陣が座る座席は床暖房もついているらしい。ずるい。

f:id:takezoe:20171218163438j:plain

インタビューを受ける小部屋。部屋というよりボックスという感じで思ったより小さい。こんな感じの部屋がいくつか用意されていました。

f:id:takezoe:20171218163526j:plain

記者会見とかする部屋。座席はシアターのような感じで角度がついています。

f:id:takezoe:20171218163613j:plain

会見場の外にはプレスルーム。めっちゃ広いです。記者さんたちはここで速報を書いたりしているのかな。

f:id:takezoe:20171218163749j:plain

ということでツアー終了。エミレーツスタジアムは最新の大規模スタジアムなので見所が多く、客席で試合を見るのとはまた違った面白さがあります。ショップも充実していますし、ロンドンの中心部からも地下鉄で簡単にアクセスできるのでアーセナルファンの方は是非訪れてみるべきです。

ちなみにスタジアムツアーに参加するとミュージアムにも無料で入れたり、Arsenal駅方面からであれば旧ハイバリースタジアムの名残を残す住宅街も近いので散策してみるのもよいかと思います。

Scala eXchange 2017に参加してきました

f:id:takezoe:20171218053514j:plain

ロンドンで開催されたScala eXchange 2017でGitBucketのLTをさせていただきました。スライドは以下になります(口頭で話した部分を付け足すなどちょっと修正してあります)。今回もいろいろ反省が多く、修行しなくては…という感じでした。

www.slideshare.net

参加したセッションで記憶に残っているものを挙げておきます(1日目のセッションは自分の発表の準備してたのでほとんど記憶がありません)。

Leave Jala Behind: Better Exception Handling in Just 15 Mins

初日のライトニングトークScalaでの例外の扱い方について、Javaスタイルのtry〜catchブロック、Tryを使った方法、Exceptionsを使った方法を紹介していました。

Scalaでのエラー処理の方法はどうやるべきかというのは悩ましいところがある気がしますが、エラーの表現としてTryを使うのはともかくExceptionsのシンタックスシュガーを使うならtry〜catchブロックでいいんじゃないかなーというのが個人的な感覚です。

ただ、最近はScala界隈の話題は高度化しすぎているので、こういう入門者向けの話も定期的に出てくるといいなと思います。

Is ScalaC Getting Faster, or Am I Just Imagining It?

コンパイラ高速化の技術的な話かと思っていたのですが、ちょっと思ってたのと違いましたw 以下のようなことを話されていました。

  • Scala 2.12になってからすでに20%以上コンパイラのパフォーマンスは改善されており50%の高速化も夢ではない
  • 高速化のためにはベンチマークやプロファイリングが重要だけどコンパイラベンチマークやプロファイリングは難しい
  • scalacの高速化の成果はDottyにも還元される
  • 様々な人がコンパイル速度の高速化に取り組んでいるのでもしアイデアがあれば聞かせて欲しい、取り組みに参加して欲しい

技術的な話というよりは、どちらかといえばコミュニティ寄りの話だったのですが、パッションを感じる熱いセッションだったと思います。

Compiling Collections to SQL with Slick

今回はこのために参加したと言っても過言ではないほど楽しみにしていたSlickの開発者Stefan ZeigerさんによるSlickのQuery Compilerの解説セッション。内容的にはだいぶ前のものですが以下のスライドが近く、このスライドを現状にあわせてアップデートした感じでした。

http://slick.lightbend.com/talks/2014-03-04_LAMP/Slick%20Query%20Compiler.pdf

デバッグ用のオプションや、コンパイラのフェーズ、ASTの変換の様子がまとめられており、ノードの特殊なプロパティについても説明があり、これからSlickのソースを読んでみようという人には大変参考になる内容だったのではないかと思います。是非スライドを公開して欲しいです。

How to Name Things: The Hardest Problem in Programming

Peter Hiltonさんによるネーミングについてのセッションでした。

彼は結構前から同じような話をしているようですし、Scalaとも直接関係ある話ではないのですが(fishとかspaceshipみたいなASCIIアートオペレータはやめろという話はありましたがw)、特に良い名前付けのためにはボキャブラリを増やすことが重要という点は非常に刺さるものがありました。良いコードを書くためにはプログラミングテクニックだけでなく教養も必要ということですね…。

Composing Programs

Functional Programming in ScalaRed Book)の著者Rúnar Bjarnasonさんによる関数型プログラミングの基礎的な話でした。

スライドは以下のURLで公開されています。

https://www.dropbox.com/s/0l7r5o7tczzx57m/Compositionality.pdf?dl=0

最初に紹介する係の人が「FP in Scala持ってる人!」→みんな一斉に手をあげるからの「エクササイズ全部ちゃんとやった人!」→1人以外全員手を降ろすが面白かったです。

まとめ

去年のScala界隈ではFreeモナドがブームだったようですが、今年はTagless Finalが流行りみたいです(自分は今回はその手のセッションには参加しませんでしたが…)。他のセッションではShapelessやcirceといったライブラリの名前がよく登場しており、Scala界隈における関数型プログラミングの人気の高さを再確認しました。

Scala eXchangeは(ヨーロッパ開催のScala Daysを除けば)ヨーロッパ最大のScalaカンファレンスとのことで参加者数も多く、非常に熱気のあるカンファレンスでした。