教養としての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カンファレンスとのことで参加者数も多く、非常に熱気のあるカンファレンスでした。

Akka実践バイブル アクターモデルによる並行・分散システムの実現

Akka in Actionの日本語翻訳版である「Akka実践バイブル」がついに完成したとのことで翔泳社さんからお送りいただきました。ありがとうございます。

f:id:takezoe:20171212124409j:plain

実はこの本は2年ほど前に翻訳を検討していたのですが、当時まだ原著がアーリーアクセス中でいつ完成するかわからないという状態だったため見送ったという経緯があります(そのため同じく翻訳を検討していたScalaパズルに着手することになりました)。時は流れて今年のScalaMatsuriで@yugolfさんをお見かけし、当時Akka in Actionの読書会を主催されていたことから「Akka in Actionの翻訳しませんか?」とご相談させていただいたことが今回の日本語版発売のきっかけになりました。

自分としても数年越しの夢を形にしていただくことができ、翻訳者の皆さま、レビュアーの皆さまには感謝の気持ちでいっぱいです。分量もかなりある本ですので大変だったと思いますが、全編通して非常に丁寧に翻訳、レビューされています。また、単なる翻訳ではなく、Akkaの最新版にあわせた記述の修正や、Alpakka、JavaからAkkaを使う方法など日本語版独自の内容も含まれています。

Akkaがどのような思想で設計されているか、Akkaを使ったリアクティブシステムのデザインパターンなどについては実際にAkkaを使わない場合でも役に立つ内容なのではないかと思いますし、すでにAkkaを使っている方はもちろん、アクターモデルやリアクティブシステムのアーキテクチャについて学びたいという方は是非手に取ってみていただければと思います。

AWSの機械学習プラットフォームSageMakerを使ってみた

AWSの新サービスである機械学習プラットフォーム SageMakerを触ってみました。ざっくり言うとデータ処理、学習、作成したモデルをコンテナとしてデプロイするという一連の作業をAWS上で提供されるJupyter Notebookから行うことができるというものです。

aws.amazon.com

SageMakerで作成したJupyter Notebookには最初からいろんなサンプルがついているのでまずはこれらで動きを確かめてみました。

f:id:takezoe:20171206171818p:plain

データなどを準備した後、create_training_job()メソッドに必要なパラメータを渡すと自動的に必要なインスタンスが用意され学習が行われます。サンプルでは学習データはS3に置かれており、生成された予測モデルは指定したS3上のパスに保存されます。ちなみに独自のアルゴリズムを使用したい場合はDockerイメージを用意する必要があるみたいです。

同じくcreate_endpoint()メソッドでHTTPのPOSTメソッドでアクセス可能なエンドポイントができます。パラメータでインスタンス数を指定できるので冗長化はできるようですが、APIリファレンスを見た感じモデルを更新した場合などの再デプロイする場合はエンドポイントを一回削除して作り直すか、別のエンドポイントを作成する必要がありそう。

ダッシュボードにはこんな感じでノートブック、学習ジョブ、モデル、エンドポイントの状態が表示されます。

f:id:takezoe:20171206172133p:plain

これらのワークフローに乗るためにはSageMakerのライブラリの使い方を覚える必要があります。デフォルトで付属しているサンプルや以下の開発者ガイドに目を通しておくとよいと思います。

docs.aws.amazon.com

ただ、必ずしもSageMakerのワークフローに乗らなくてもよいのかもしれません。たとえば入力データをAthenaから持って来たり、SageMakerのジョブを使わずに学習を行うということもできそうです。AWS上のリソースを活用するためのマネージドなJupyter Notebookとして使うのもありかもしれません。