search term:

モナドはフラクタルだ

Uppsala から帰ってくる途中、何となく思い出したのは同僚とのモナドの直観についての会話で、僕は酷い説明をした気がする。色々考えているうちに、ちょっとひらめきがあった。

Sierpinski triangle

モナドはフラクタルだ

上のフラクタルはシェルピンスキーの三角形と呼ばれるもので、僕がそらで描ける唯一のフラクタルだ。フラクタルとは自己相似的な構造で、上の三角形のように部分が全体の相似となっている (この場合は、親の三角形の半分のスケールの相似)。

モナドはフラクタルだ。モナディックなデータ構造があるとき、その値のいくつかを合成して同じデータ構造の新しい値を形成することができる。これがモナドがプログラミングに有用である理由であり、また多くの場面で登場する理由だ。

具体例で説明する:

scala> List(List(1), List(2, 3), List(4))
res0: List[List[Int]] = List(List(1), List(2, 3), List(4))

カンファレンスでのユニバーサル・アクセスへ向けて

2日間の #ScalaMatsuri は盛況に終わった。だけど、来年へ向けて色々課題もあるので、それを自分なりに書き出してみる。題の通り、僕達の次の目標とするべきものはユニバーサル・アクセスだと考えている。Scala 言語においては、統一アクセスの原則 (universal access principle) と言えば、メソッドとフィールドの両方が外側から見ると別けへだて無くアクセスできることを指す。 この文脈でのユニバーサル・アクセスは、様々なグループの人にとっても包括的 (inclusive) なカンファレンスという意味で使っている。具体的には: 女性/男性/ヘテロ/LGBT のプログラマ 日本語/英語話者 初心者と上級者 ポスドクなどの研究者 日本以外のアジア諸国からの人 など。 テクノロジー界における女性問題、及びその他のジェンダー問題 去年は女性によるセッション数はゼロ。今年は、マクロに関してのセッションが一つと、FuRyu さんのスポンサー LT が一本あった。これは良い傾向だと思うけど、僕としては、女性の人による Scala コミュニティ一般への参加、勉強会などへの出席、そして ScalaMatsuri のようなカンファレンスへの出席をもっと応援したいと思う。男性側としてできることの一つに、もし勉強会に参加してくれた女性の方がいたら、変な挙動を取らずに普通のハッカーの一人として接することがあると思う。 Scala Days、NE Scala、そして PNW Scala に倣って、今年の ScalaMatsuri では Geek Feminism Wiki/Ada Initiative を原案とする行動規範を採用した。この行動規範は、全員にハラスメント・フリーの経験を提供することを約束し、特に「全てのコミュニケーションは、技術的な発表の場にふさわしいものであるべき」ことを求める。今後、正式なハラスメント報告方法の確立などを含む、ポリシーの実装をはっきりさせる必要があるが、公的にこのようなガイドラインを採用できたことで、より inclusive なカンファレンスになっていくと考えている。 言語の壁 Scala がよく使われているその他の欧米諸国に比べて、日本の英語スキルは特にリスニングとスピーキングで遅れている。ScalaMatsuri の運営側としては、カンファレンスをより尖ったものにして、Scala コミュニティからより多くの英語話者を惹きつけることを目標の一つとしている。それに沿って、招待講演者の旅費を出したり、テキスト翻訳を提供したり、一般的に英語話者が来ても楽しめるように歓迎するようにしている。今年は、日本語話者でも英語で発表する人も出てきた。 このような努力は、Scala には興味があるが英語は苦手という多くのカンファレンス参加者にとって利害関係の衝突となる。リアルタイムで提供される有志によるテキスト翻訳は、無いよりはいいかもしれないけど、往々にして不十分である。解決方法として検討するべきはプロの通訳を雇うことだ。これは YAPC::Asia などではうまくいったらしい。さらに、2つの別路線 (track) を作って、それぞれ英語での発表と日本語での発表を行うべきだ。 初心者と上級者 Matsuri は祭という意味で、テーマも “enjoy Scala” だった。前から Scala をやってきてるユーザには確かに楽しいカンファレンスだったかもしれないが、僕のものも含め多くのトークは初心者を置いてきぼりにしたものとなった。この回避方法となり得るかもしれないのが、英語路線と日本語路線の区別の他に、NE Scala のようにセッションを参加者の投票で決めてもらうことだ。(通訳付きで)英語のセッションでも聞いてみたい人と上級者、逆に日本語にして欲しい人と初心者に相関性があると仮定すると、それぞれの路線が、投票によって聴衆が聞きたい適切なレベルに補正されるのではないだろうか。 ポスドクとアジア諸国からの参加者 1日目のレポートに書いたとおり、宋 剛秀さんの発表は唯一学術的な方面からのものだったけど、独自で面白いものだった。アメリカやヨーロッパからのロックスター的な登壇者を観るのも面白いけども、日本から宋さんのようなポスドクの研究者や、はたまた近隣のアジア諸国である、インド、中国、韓国、台湾、シンガポールなどから呼んでみるのも面白いのではないだろうか。英語路線を設けることで、日本語の心配はいらなくなると思う。実装する方法の一つとしては、CFP をもっと比較的長く取って、例えば最大 $1500 までで旅費のサポートをすると宣伝すればいいと思う。投票後には、旅費予算から差し引いていって、票の多い順に可能な限りの人を招待すればいい。 全ての受け皿としてのアンカンファレンス もし英語路線か日本語路線のどちらかの競争率が高くなっても、今後はアンカンファレンスを受け皿として機能させることができる。今回で多くの人が直接アンカンファレンスが行われる様子を見たので、今後はより多くの議論や準備済みのトークが増えることを期待していう。来年からはホワイトボードを廃止して、当日の朝に Google docs に直接全てのアンカンファレンスのアイディアをファシリテータ名と共に書く方向に変えていくべきだと思う。狙いはあまり人気が無いセッションでも部屋が空いていれば、ちゃんとセッションを設けることにある。

ScalaMatsuri 1日目

日本での Scala カンファレンスも今年で二年目だ。今年は ScalaMatsuri と名前を変えて仕切り直し。300枚のチケットは売り切れ、招待講演者やスポンサー招待枠などを入れたら当日はもっといたかもしれない。アメーバブログやオンライン広告サービスなどを事業とする CyberAgent さんのオフィスを会場としてお借りした。 1日目のトップバッターは小田好先生こと Martin Odersky 先生 (@ordersky) の「Scala 進化論」。多くの人が小田好先生の講演を楽しみにしていたので、朝から満員に近かったと思う。僕が出席したセッションは、拙作の closed-captioning を使って和英、英和のテキスト翻訳を打ち込むのに忙しかった。一日目翻訳チームの他のメンバーは、@cbirchall、 @cdepillabout、 @okapies、 @oe_uia。 次に僕が「sbt、傾向と対策」を日本語で話した。mkdir helloworld から始めて、sbt の最初のステップから、continuous testing までの流れのデモから始めた。次に、基礎コンセプト、0.13.6 で入る新機能である HTTPS デフォルト、consolidated resolution、eviction warning を紹介して、最後に「サーバとしての sbt」とさらなる性能の改善という将来の展望でシメた。LinkedIn社のプレスチームから、LinkedIn が sbt の性能改善の仕事をスポンサーしてもらってることを話してもいい許可をもらってきたので、今回機能改善に関して公の場でお礼できたのは良かったと思う。 Activator と sbt に関して質問があった。Activator の 3つの用例ということで以下のように回答した: トレーニング・セッションなどにおける USBドライブなどによる Typesafe スタックのオフライン配布 新ユーザの out-of-the-box エクスペリエンス (箱を開けてすぐ遊べること) の改善 ユーザがコードを打ち込みながら使えるチュートリアルをホストするプラットフォーム sbt サーバに関しては、IntelliJ などの他のツールとの連携、と将来的な remote compilation などの可能性ができること両方について好反応を得た。 Jon Pretty (@propensive) さんの ‘Fifty Rapture One-Liners in Forty Minutes’ という講演。リソースの読み書きを抽象化することに焦点を絞ったライブラリみたいで、オンラインから色々読み込んで、生の状態の読み込み (slurp) や case class への落とし込みをするみたいだ。enrich-my-library、マクロ、dynamics などユーザ・フレンドリーな Json 処理のために言語のトリックを多用している。バックエンドの json ライブラリが選べるようになっているのは好印象。

Vim メモ

個人的には SublimeText で特に困っていないし、メインのエディタとしてしばらく使ってきた。だけど、コマンドラインから使えるエディタにも少しは興味があるし、色んな人がネットワーク上から使えるから便利ということを言っている。X を転送したり、他の方法でリモートインすれば Sublime を使えるんじゃないかとも思うが、一応試してみよう。 この Vim のセットアップをしようと思ったキッカケの一つに新しく MBP を買ったというのがあって、折角だから何か新しいことをやってみようかなと思った。つまり、本稿は完全な素人が個人的なメモとして書いてあるものだ。そもそもブログというのはそういうものなはずだ。動くかどうかは保証できない。全般的に yuroyoko さんが数年前に書いた iTerm2 + zsh + tmux + vim で快適な256色ターミナル環境を構築するを参考にした。 Vim 以外の色々なこと dotfiles 本稿で書いたセットアップは eed3si9n/dotfiles に上げてある。他の人の dotfiles を fork するのが作法らしいけども、自分の環境に持ち込む設定をちゃんと理解したかったので、一から書き始めた。 dotfiles の基本的な考え方としては、これを ~/dotfiles/ にまず checkout して、そこには zshrc などのファイルが入ってる。これらのルートの設定ファイルはホームディレクトリ内で ~/.zshrc などという感じでシンボリックリンクが張られる。 Terminal.app Mac で iTerm2 がどうしても必要になったことはまだない。以前には Terminal.app に色々と制限があったのかもしれないけど、今の所僕はこれで間に合っている。 Terminal.app を使い続けている理由のもう一つが、僕が TotalTerminal のファンであることだ。 homebrew Homebrew にはお世話になっている。 Zsh このマシンのシェルは Zsh にする。Mac なら How to use Homebrew Zsh Instead of Max OS X Default を参照:

Scala を用いたスクリプティング

現実問題として正規表現が必要になることがある。いくつかのテキストファイルに変換をかけたりする度に find コマンド、zsh のドキュメントや Perl 関連の StackOverflow の質問を手探りしながら作業することになる。苦労しながら Perl を書くよりは Scala を使いたい。結局、僕個人の慣れの問題だ。 例えば、今手元に 100以上の reStructuredText ファイルがあって、それを markdown に変換する必要がある。まずは pandoc を試してみて、それはそれなりにうまくいった。だけど、中身をよく読んでみるとコードリテラルの多くがちゃんとフォーマットされてないことに気づいた。これは単一のバッククォート (backtick) で囲まれていたり、Interpreted Text を使っているからみたいだ。このテキストをいくつかの正規表現で前処理してやればうまくと思う。 コマンドライン scalas 僕の現在の開発マシンには scala へのパスが通っていない。zip ファイルを一回ダウンロードするのは大した作業じゃないけども、将来的に jar とスクリプトの管理をしなきゃいけないのが面倒な気がする。普通なら僕は sbt を使って Scala の jar をダウンロードさせる。それでもいいけども、単一のファイルのみを使った解法が欲しいとする。 そこで今試してるのが sbt の script runnerだ: #!/usr/bin/env sbt -Dsbt.version=1.4.7 -Dsbt.main.class=sbt.ScriptMain -Dsbt.supershell=false -error /*** ThisBuild / scalaVersion := "2.13.4" */ println("hello") 次に、 $ chmod +x script.scala $ ./script.scala hello これで自分の Scala version を 2.13.4 に指定するスクリプトができた。コンパイルを含めて “hello” が表示されるまで 8秒かかるから、サクサクとは程遠い感じだけど、個人的には許容範囲内だと思う。

sbt テクノロジ・プリビュー: auto plugin

Preview of upcoming sbt 1.0 features: Read about the new plugins を訳しました。 著 @eed3s9n, @jsuereth sbt に変化が訪れようとしている。sbt 1.0 へ向けて sbt の原理である自動化 (automation)、インタラクション (interaction)、統合化 (integration) の全面において改善がみられる予定だ。1.0 の二大機能と目されているのは auto plugin と「ビルドサーバとしての sbt」の 2つだ。 今後の数ヶ月にわたって sbt チームは sbt 0.13 コードベース上にこれらの機能を追加したプリビュー版をリリースする。これらのプリビュー版によって、sbt 1.0 の仕様が固まる前にコミュニティーからのフィードバックを得たり、新しい設計方針や理念そして新機能を促進することを目的としている。 長い間 sbt を支えてきた Mark Harrah がビルド以外のことをするために旅立っていったことを残念ながら報告しなければならない。しかし、Typesafe のビルドツールチームである Antonio Cunei、Josh Suereth に新たなメンバー Eugene Yokota (@eed3si9n) が sbt の techlonogy lead の一人として参加することを歓迎したい。 本稿では、今回できあがった auto plugin 機能を紹介する。これは sbt 0.13.5-M2 リリースに含まれる。 プラグイン・エコシステム sbt の最大の強みとしてプラグイン・エコシステムを挙げることができる。プラグインはビルド定義と全く同じように動くため、sbt を習うことはそのままプラグインを書くのを習うことにつながっていく。sbt プラグインの多様性はこの基本的なコンセプトの力強さを物語っているだろう。中でも Play Framework と Activator の二つは抜き出ている。これらは sbt の上にで作られていてインタラクティブな開発エクスペリエンスを提供しているからだ。

Scala でのクラス線形化 (mixin 順序) の制約

昨日は、何故か早朝に目が覚めて @xuwei_k氏のScalaで抽象メソッドをoverrideする際にoverride修飾子を付けるべきかどうかの是非を流し読みしていた。この話題は面白すぎたので、飛び起きてすぐに英訳してしまった。Scalaz で遭遇したコードを例にして型クラスのデフォルトインスタンスを提供することの微妙なジレンマを解説している。 以下に問題を簡略化したコード例を示す: trait Functor { def map: String } trait Traverse extends Functor { override def map: String = "meh" } sealed trait OneOrFunctor extends Functor { override def map: String = "better" } sealed trait OneOrTraverse extends OneOrFunctor with Traverse { } object OneOr { def OneOrFunctor: Functor = new OneOrFunctor {} def OneOrTraverse: Traverse = new OneOrTraverse {} } これをテストするには以下を実行する: scala> OneOr.OneOrTraverse.map res0: String = meh OneOr.

sbt-sequential を用いたタスクの逐次化

本稿では sbt 0.13 における実行意味論 (execution semantics) とタスクの逐次化 (task sequencing) についてみていこうと思う。まずは前提となる背景を大まかに復習して、次に逐次的タスク (sequential task) を追加するために書いた実験的プラグイン sbt-sequential を紹介したい。 背景 Mark 曰く: sbt のモデルは副作用をタスクに局所化させることで、依存性さえ満たせば、タスクはいつでも実行できるというものだ。この利点はデフォルトで並列であることで、実際により速いビルドを可能とすることだ。 言い替えると、sbt を使ったビルド定義はタスク間の依存性のみを定義していて、これらのタスクがどのタイミングで始動されるかは sbt によって自動的に計算される。これをちゃんと理解するために、まず副作用を持った Scala コードの実行意味論をみてみよう。 直列実行 (serial execution) class Test { def startServer(): Unit = { println("starting...") Thread.sleep(500) } def stopServer(): Unit = { println("stopping...") Thread.sleep(500) } def numberTask: Int = 1 def integrationTest0(): Int = { val n = numberTask startServer() println("testing...") Thread.sleep(1000) stopServer() n } } 誰かが integrationTest0() を呼び出すと、コードは書かれたのと全く同じ順序で実行される。まず numberTask が呼び出され、次に startServer() が呼ばれこの実行は 0.

Spire の Ops マクロ: 暗黙の演算子の高速化

一見普通の演算でもいかに高速化できるかをいつも考えて発表してる奇才 Eiríkr Åsheim (@d6) さんの “How to use Spire’s Ops macros in your own project” を翻訳しました。いつも気さくに話しかけてくれるフレンドリーでいいやつです。翻訳の公開は本人より許諾済みです。 2013年10月13日 Eiríkr Åsheim 著 2013年11月20日 e.e d3si9n 訳 Spire の Ops マクロとは何か? Spire の型クラスは + や * といった基礎的な演算子を抽象化する。普通これらの演算は非常に速い。そのため、ちょっとでも余計な事 (例えば、boxing やオブジェクトの割り当てなど) を演算ごとにやってしまうと、ジェネリック化したコードは直接呼び出したものと比べて遅いものになってしまう。 効率的かつジェネリックな数値プログラミングが Spire の存在意義だ。不必要なオブジェクト割り当てを回避するために僕たちはいくつかの Ops マクロを用意した。本稿ではその仕組みと、君のコードからそれらのマクロを使う方法を解説する。 通常の型クラスを用いた暗黙の演算子の仕組み Scala で型クラスを用いる場合、通常は暗黙の変換に頼ることでジェネリックな型に演算子を「追加」する。(訳注: いわゆる Enrich my library パターンだ) 以下に具体例で説明すると、A はジェネリックな型、Ordering は型クラスで、> が暗黙の演算子となる。foo1 はプログラマが書くコードで、foo4 は implicit が解決されて、糖衣構文が展開された後のものだ。 import scala.math.Ordering import Ordering.Implicits._ def foo1[A: Ordering](x: A, y: A): A = x > y def foo2[A](x: A, y: A)(implicit ev: Ordering[A]): A = x > y def foo3[A](x: A, y: A)(implicit ev: Ordering[A]): A = infixOrderingOps[A](x)(ev) > y def foo4[A](x: A, y: A)(implicit ev: Ordering[A]): A = new ev.

sbt 0.13 を用いた四次元空間内の移動

警告: この sbt についての覚え書きは中級ユーザ向けだ。 セッティングシステム sbt 0.12 同様に sbt 0.13 の中心にあるのはセッティングシステムだ。Settings.scala を見てみよう: trait Init[Scope] { ... final case class ScopedKey[T]( scope: Scope, key: AttributeKey[T]) extends KeyedInitialize[T] { ... } sealed trait Initialize[T] { def dependencies: Seq[ScopedKey[_]] def evaluate(map: Settings[Scope]): T ... } sealed class Setting[T] private[Init]( val key: ScopedKey[T], val init: Initialize[T], val pos: SourcePosition) extends SettingsDefinition { ... } } pos を無視すると、型 T のセッティングは、型が ScopedKey[T] である左辺項 key と型が Initialize[T] である右辺項 init によって構成される。

オブジェクト指向プログラミングとは何か?

oop はどう定義されるべきだろうか?

純粋オブジェクト指向プログラミング

純粋オブジェクト指向プログラミングは以下のように定義できる:

オブジェクトを使ったプログラミング。

オブジェクトとは何か?

他のオブジェクトへの参照を保持し、事前にリストアップされたメッセージを受信することができ、他のオブジェクトや自分自身にメッセージを送信することができるアトムで、他には何もしない。メッセージは名前とオブジェクトへの参照のリストから構成される。

これでおしまい。言い回しは僕が考えたものだけど、アイディアはオブジェクト指向という言葉を作った張本人 Alan Kay (2003) からのものだ。これ以外は、直接 oop に関係無いか、実装上の詳細だ。

sbt 0.13.0 の変更点

概要 互換性に影響のある新機能、変更点、バグ修正 sbt とビルド定義を Scala 2.10 に移行した。 project/plugins/ 内に置かれたプラグインの設定ファイルのサポートを廃止した。これは 0.11.2 より廃止予定になっていた。 set コマンドにおいてセッティングの右辺項内のタブ補完を廃止した。新たに追加されたタスクマクロがこのタブ補完を不要にするからだ。 キーの慣用的な書き方はこれよりキャメルケース camelCase のみとする。詳細は後ほど。 Maven との互換性を正すため、テストのデフォルトの classifier を tests に修正した。 グローバルなセッティングとプラグインのディレクトリをバージョン付けるようにした。デフォルトでは、グローバルセッティングは ~/.sbt/0.13/ に、グローバルプラグインは ~/.sbt/0.13/plugins/ に置かれる。sbt.global.base システムプロパティを使った明示的なオーバーライドは継続して適用される。(#735) scalac にファイルを渡すときに sbt が行なっていた正規化 (canonicalization) を廃止した。(#723) 各プロジェクトがそれぞれ固有の target ディレクトリを持つことを強制するようにした。 依存ライブラリの Scala バージョンをオーバーライドしないようにした。これによって個別の設定が異なる Scala バージョンに依存できるようになり、scala-library 以外の Scala 依存性を通常のライブラリ依存性と同じように扱えるようになった。しかし、これによってその他の scala-library 以外の Scala ライブラリが最終的に scalaVersion 以外のバージョンに解決される可能性も生まれた。 Cygwin での JLine の設定が変更された。Setup 参照。 Windows 上での JLine と Ansi コードの振る舞いが改善された。CI サーバ内では -Dsbt.log.format=false を指定して明示的に Ansi コードを無効にする必要があるかもしれない。 フォークされたテストや run がプロジェクトのベースディレクトリをカレント・ワーキング・ディレクトリとして用いるようにした。 compileInputs は Compile ではなく (Compile,compile) 内で定義するようにした。 テストの実行結果は Tests.

Scala: 空飛ぶサンドイッチのパーツ

JavaScript が作られたのは 1995年のことだから、『JavaScript: The Good Parts』(2008年)、jQuery (2006年)、V8 (2008年) などが登場するよりもかなり前に作られたことになる。jQuery と V8 が加算的な貢献であるのに対して、Douglas Crockford 氏の『The Good Parts』が面白いのは、言語から機能を引き算した本であることだと思う。 ここ最近、もし Scala をリアルワールドな制約である Java 的な親しみやすさや互換性を無視してワンダーランド的な設定でサブセットを作ったらどうなるだろうかと考えている。Scala を Java の代替として使う事が許されるなら、関数型プログラミング言語の代替として使ってもいいじゃないかと思う。この思考実験のもう一つの試みは、Scala の構文の中で重複しているものを減らすことだ。本稿では、慣用的な用法が何かを考えたり、何かに対して良し悪しの判定を下すことには興味は無い。これは空飛ぶサンドイッチのパーツ (The Flying Sandwich Parts; TFSP) と呼ぶことにする。 値 What talk you of the posy or the value? — William Shakespeare, Merchant of Venice Scala 言語仕様は値を以下のように定義する: 値定義 val x : T = e は、e の評価から得られる値の名前として x を定義します。 TFSP においては、トレイトやクラスの本文内では型注釈 T の省略を禁止する。関数内のローカルの値は型推論を使って定義してもよい。これによって関数レベルにおいて型検査が行われることが保証される。 遅延評価値 素の val を使って値を定義すると、定義した順番に気を使う必要がある。初期化する前に値を参照してしまうと実行時に NullPointerException が発生してしまう。値を lazy だと書くことで最初に参照されるまで初期化を遅延することができる。

scopt 3.0

scopt is a little command line options parsing library. 今日 scopt 3.0 をリリースする。実装の詳細に興味が無ければ、readme に飛んでほしい。 2010年3月4日ごろ僕は scopt のコミッタになった。これは元々 Aaron Harnly さんが 2008年ごろ書いた scala-options のフォークだ。確か、usage text 周りの変更と key=value options と argument list という機能を追加したかったんだと思う。それ以降全てのバグレポを担当してきた。その中には jar を scala-tools.org に公開してくれというのもあった。2012年3月18日、僕は再びプロジェクトを scopt/scopt にフォークして immutable parser を追加した scopt 2.0.0 をリリースした。 数年に渡って重ねるようにして機能が追加されたため、scopt3 は一から書き直すことにした。発端となったのは Leif Wickland さんに「scopt に intArg() が無いのは設計上の理由があるのか」と聞かれたことだ。 Ruby の OptionParser に inspire されて書かれた元の Aaron さんの scala-options にはオプションのために 5個のメソッドがあった: onInt、 onDouble、 onBoolean、 on、それからもう一つオーバーロードされた on。重なる開発の結果 scopt2 は opt のオーバーロードが 6つ、intOpt、 doubleOpt、 booleanOpt、 keyValueOpt、 keyIntValueOpt、 keyDoubleValueOpt、 keyBooleanValueOpt それぞれに 4つづつのオーバーロードが蓄積された。合計 34 ものメソッドだ!

Dispatch プラグインの書き方

Dispatch は Scala からネットへつなぐデファクトの方法であり続けてきた。昨今のノンブロッキングIO への流れと歩調を合わせて @n8han はライブラリを Async Http Clientベースのものに書きなおし、Reboot と呼んだ。後にこれは、Dispatch 0.9 としてリリースされる。さらに、独自の Promise を SIP-14 で標準化された Future に置き換えたものが Dispatch 0.10 だ。 Dispatch Classic 同様に Reboot でも web API をラッピングしたプラグインを作ることができる。本稿では、Classic で書かれたプラグインを移植しながら Dispatch 0.10 プラグインの書き方を解説していく。 repatch-twitter 他のプラグインとの名前の衝突を回避するために、僕のは dispatch-twitter ではなく repatch-twitter と呼ぶことにする。 sbt まずは sbt の設定から始める: repatch-twitter/ +- project/ | +- build.properties | +- build.scala +- core/ +- src/ +- main/ +- scala/ +- requests.scala +- ... build.properties の中身: sbt.version=0.12.3 build.scala の中身:

カンファレンスを翻訳する

もう一ヶ月経つけど 2013年3月1日に日本に一時帰国して「Scala Conference in Japan 2013」に出席した。そういう名前のカンファレンス。 ポッドキャストから ある日 (2012年6月2日だけど) Scala Days 2012 で録音された Scala Types を聞いていると誰かが (@timperrett さん) “I would love to see Scala Days in Asia. We had two in Europe now. It would be wicked to have it in China or Japan, or somewhere like that.” と言っていたので、その趣旨を Twitter で伝えた: 今 Scala Days 2012 で録音された Scala Types を聴いてたら、開催地が欧米圏に偏ってるから次あたり日本とかアジア圏なんてどうだろうって話が出てた。コミュニティが声出せば誘致もありえるかも 会話が始まると @jsuereth がすぐに支持の声を上げてくれた: @kmizu @eed3si9n_ja If you guys manage to get a Scala conference somewhere in asia, I’ll be there!

抽象的な Future

これは Scalaz Advent Calendar 2012 12日目の記事です。 次々と Scala 界の知能派を集結させている Precog 社の開発チームからのブログ Precog.Copointed。今日は blueeyes などの開発でも知られる Kris Nuttycombe (@nuttycom) さんが書いた The Abstract Future を翻訳しました。翻訳の公開は本人より許諾済みです。 2012年11月27日 Kris Nuttycombe 著 2012年12月11日 e.e d3si9n 訳 Precog 開発ブログの前回は僕たちが Cake パターンを使ってコードベースを構造化して、ギリギリまで実装型を抽象化してしていることを Daniel が書いた。その記事での説明のとおり、これは非常に強力な概念だ。型を存在型として保つことで、やがて選択された型を「意識」していないモジュールからはそれらの型の値は不可視であるため、カプセル化の境界の突破をコンパイラが防止してくれる。 今日の記事では、この概念を型からさらに進めて型コンストラクタに適用して、計算モデルを丸ごと置き換える機構として使えることを説明する。 Scala を少しでも使ったことがあれば、何らかの文脈で誰かが「モナド」という言葉を使ったのを聞いたことがあるだろう。例えば、Scala の for というキーワードにより提供される糖衣構文に関する議論か、Option 型を使うことで null 参照エラーの落とし穴が回避できることを説明したブログ記事で読んだのかもしれない。Scala でのモナドに関する議論の大半が「コンテナ」型に焦点を当てているのに対して、Scala エコシステムでよく見かけるいくつかの型の中にモナディック合成のより面白い側面が表れるものがある。限定計算 (delimited computation) だ。どのモナディックな型を合成してもこの側面を見ることができるが、これを直接利用した例として最もよく使われている Scala でのモナディックな型に非同期計算をエンコードした akka.dispatch.Future がある (これは Scala 2.10 において現行の Future を置き換える予定のものだ)。これは計算のステップを順序付けするための柔軟な方法を提供することで、本稿が注目するモナディック合成の一面を体現する。 ここで一言断っておくが、この記事はモナドのチュートリアルとして機能することを意図していない。モナドの解説とその Scala のプログラミングとの関連を取り扱った記事は既にたくさんある (ありすぎるかも!)。もしこの概念に不慣れなら読み進める前にそれらの解説を読むと役に立つかもしれない。しかし、最初に注意しておきたい点が一つあって、(モナディック合成のための糖衣構文としての for が示すとおり) Scala ではモナドは広い範囲で利用されているにも関わらず Scala の標準ライブラリに Monad 型が無いというのは Scala 固有な状況だということだ。そのため、モナド型が必要ならば標準ライブラリ外の素晴らしい Scalaz プロジェクトを使う。Scalaz のモナド抽象体は implicit 型クラスパターンを利用している。以下にベースの Monad 型を簡略化したものを示す:

Func を使った数独

これは Scalaz Advent Calendar 2012 5日目の記事です。 12月の間中、日本の技術系ギークは日替わりでテーマに沿った記事を公開し、彼の国では「Advent Calendar」と呼ばれているらしい。去年の Scala Advent Calendar 2011 で僕は Eric Torreborre さんが The Essence of Iterator Pattern をカバーした記事を翻訳した。これは日本人の関数型プログラミング記事好きを知った上である程度狙ったものだった。もう1つの利己的な動機は、記事を一語一語訳す過程において概念のいくつかは僕の頭にも染みこんでくれるんじゃないかという期待だった。振り返ってみると、両方の目的とも作戦成功だったと言える。Jeremy Gibbons さん、Bruno Oliveira さんそして Eric 両方の仕事のクオリティのお陰だ。これらの染み込んだ知識が今年に書いた独習 Scalaz シリーズの隠し味だったんじゃないかと思っている。 独習 Scalaz 12日目でふれたとおり、Scalaz 7 の型クラスインスタンスには既に product と compose が含まれており、また Traverse も定義されている。論文にある word count の例題 まである。僕が気づいたのは、値レベルでの合成が無いことだ。この論文の興味深い点の1つに「applicative functor の合成」があり、これはモジュール化プログラミング的なものを可能とする。 Gibbons と Oliveira の言う「applicative functor」は実は型クラスのインスタンスだけではなく、applicative 関数の合成も指している。これは論文からの以下の抜粋をみれば明らかだ: data (m ⊠ n) a = Prod { pfst :: m a, psnd :: n a } (⊗) :: (Functor m, Functor n) ⇒ (a → m b) → (a → n b) → (a → (m ⊠ n) b) (f ⊗ g) x = Prod(f x)(gx) 代数データ型の ⊠ は型レベルの積だが、中置関数の ⊗ は 2つの applicative 関数の値レベルの積で、a → (m ⊠ n) という型の applicative 関数を返す。言い換えると、プログラマは applicative functor を返す関数を構築するだけよくて、型レベルでの合成は自動的に行われる。

絵で見るモナド

John Wiegley さんの “Monads in Pictures” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。

2012年8月20日 John Wiegley 著 2012年8月21日 e.e d3si9n 訳

これはモナドのチュートリアルではないし、ここには数学用語も出てこない。本稿は、既にモナドを一応使えるぐらいには習った人を対象とする。視覚化することで、何のために何をやっているかが明らかになるはずだ。

関数

モナドに対する直感を得る一つの方法として関数からモナドへの抽象化をたどるというものがある。関数が何をやっているのかを簡単な絵で表してみよう。Haskell の関数の呼び出しの構文を上に、同じ演算を視覚化したものを下に置いた:

Scala 2.10 におけるメタプログラミング: 構文木、シンボル、型について

Scala マクロの作者 Eugene Burmako さんによるリフレクション API に関する発表のスライド、“Metaprogramming in Scala 2.10” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。 2012年4月28日 Eugene Burmako 著 2012年8月5日 e.e d3si9n 訳 はじめに メタプログラミング メタプログラミングとは、他のプログラムや自身をデータとして書いたり操作するコンピュータプログラムを書くこと。 —Wikipedia コンパイラ 問: どうやってメタプログラミングを可能にすることができだろう? 答: コンパイラよりもプログラムに関してデータを持つ者がいるだろうか? プログラマにコンパイラを公開しよう。 リフレクション 2.10 ではプログラムに関するデータをリフレクション API として公開する。 この API は、scala-library.jar (インターフェイス)、scala-reflect.jar (実装)、scala-compiler.jar (実行時コンパイル) にまたがっている。 Martin の方が詳しい 先日行われた Martin Odersky 先生による講演にてリフレクション API の設計が詳しく説明されている: http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers 実習 今日は、いくつかの具体例を通してリフレクション API の基礎を習い、またどうやって更に多くの情報を得られるかを習う。 マクロ 問: ちょっと! マクロはどうなってるの? 答: マクロの核となるのはリフレクションであり、リフレクションがマクロを API として提供し、リフレクションがマクロを可能とする。今日はまずリフレクションを理解することに焦点を当てる。マクロは小さな後付けにすぎない。 マクロ、その哲学と応用に関しては、Scala Days での講演を参考にしてほしい: http://eed3si9n.com/ja/scala-macros-scaladays2012 リフレクション コアとなるデータ構造 構文木 (Tree) シンボル (Symbol) 型 (Type) $ scalac -Xshow-phases phase name id description ---------- -- ----------- parser 1 ソースを AST へとパースし、簡単な糖衣構文展開 (desugaring) を行う。 namer 2 名前を解決し、シンボルを名前付けされた構文木へと関連付ける。 typer 4 メインコース: 構文木を型付けする。 pickler 7 シンボルテーブルをシリアライズする。 できる限り分かりやすくこれらの概念の説明をするつもりだが、Paul Phillips 以上の説明は恐らく誰にもできない。 Inside the Sausage Factory という講演は絶対に見ておいたほうがいい。

初めての Scala マクロ

Scala マクロの作者 Eugene Burmako さんが管理する scalamacros.org から “Getting started” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。 Eugene Burmako 著 2012年7月31日 e.e d3si9n 訳 1. Scala 2.10 を入手する マクロは 2.10.0-M3 以降の Scala で出荷されている。現行のマイルストーンである 2.10.0-M6 などのマクロが入ったコンパイラを直接ダウンロードするか、Maven や sbt などから参照する。好きな方法を使っていい。 訳注: sbt 0.11.3 を使ったプロジェクトを github に用意したので、 git clone -b ja https://github.com/eed3si9n/scalamacros-getting-started.git でセットアップできる。 2. マクロを書く Macros.scala というファイルを作って以下のコードをペーストする (関連する API やインフラなどマクロシステムに大切なことが書かれているのでコメントもしっかり読んでほしい)。 import scala.reflect.makro.Context import collection.mutable.ListBuffer import collection.mutable.Stack object Macros { // マクロ定義のシグネチャは好きなパラメータを受け取る普通の関数と同じだ。 // しかし、本文は実装への参照のみとなる。 def printf(format: String, params: Any*): Unit = macro printf_impl // マクロ実装のシグネチャはマクロ定義のものと対応する必要がある。 // 一見複雑に見えるが、心配する必要はない。 // もしコンパイラが不満なら、エラーメッセージで必要なシグネチャを教えてくれる。 def printf_impl(c: Context)(format: c.

Scala マクロ、ロンドンに現る

マクロの作者として今注目を浴びている Eugene Burmako さんと、マクロを使って言語統合されたデータベース接続行うライブラリ SLICK の作者である Jan Christopher Vogt さんが今年の Scala Days で行った発表のスライドを翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。

2012年4月18日 Eugene Burmako、Jan Christopher Vogt 著 2012年7月30日 e.e d3si9n 訳

Scala マクロ

(頭をおかしくせずに) コンパイラを拡張する権限を開発者に与える!

これはコンパイル時に以下を行う:

  • 検査
  • 処理
  • AST 変換
  • コード生成
  • ランタイムへの AST の配備

訳注: Scala マクロは 2.10 より導入されるコンパイル時にコードを置換する機構だ。これにより今までボイラープレートが必要だったものを自動生成できるようになるなど、より高い表現力を手にすることができる。

Scala脳のための C# LINQ

これは Scala プログラマのための C# LINQ 機能の覚え書きだが、逆としても使えるはず。 型推論 C# には型推論がある。個人的に、ローカル変数ではできるだけ var を使うようにしている。 var x = 1; Scala にも var があるけど、可能なら不変 (immutable) な val を使うのが好ましいとされている。 val x = 1 新しい List と Array の作成 C# はインラインでコレクションを作ることができる。 using System.Collections.Generic; var list = new List { “Adam”, “Alice”, “Bob”, “Charlie” }; var array = new [] { 0, 1, 2 }; 全ての Scala コレクションにファクトリメソッドがある。 val list = List("Adam", "Alice", "Bob", "Charlie") val array = Array(0, 1, 2) ラムダ式を使ったフィルタ C# には “enrich-my-library” 的なモンキーパッチングがあり、普通の Array に Where メソッドが追加されている。

sbt 0.12.0 の変更点

ついに final がリリースされた、sbt 0.12.0 の変更点を訳しました。 バイナリバージョンという概念が導入されることで、Scala 2.9.0 で入ったけどあまり活用されていない Scala の後方バイナリ互換性がより正面に出てくるキッカケとなると思います。 互換性に影響のある新機能、バグ修正、その他の変更点 Scala 2.10 以降の Scala 及び sbt プラグインのクロスバージョン規約の変更。 (詳細は以下の項目 ) 直接実行された場合、強制的に update を実行するようにした。 #335 sbt プラグインリポジトリがプラグインとプラグインの定義にデフォルトで加わった。 #380 プラグイン設定ディレクトリの優先順位。 (詳細は以下の項目 ) ソース依存性の修正。 (詳細は以下の項目 ) 集約がより柔軟になった。 (詳細は以下の項目 ) タスク軸の構文が key(for task) から task::key へと変更された。 (詳細は以下の項目 ) sbt の organization が org.scala-sbt へと変更された。(元は、org.scala-tools.sbt) 特に、scripted プラグインのユーザはこの影響を受ける。 artifactName の型が (ScalaVersion, ModuleID, Artifact) => String となった。 javacOptions がタスクとなった。 session save は build.sbt 内の設定を(適切な時に)上書きするようにした。#369 新機能 テストのフォークのサポート。 #415 test-quick。 (#393) リポジトリ設定のグローバルなオーバライドをサポートした。 #472 再コンパイルをせずに unchecked と deprecation の警告を表示する print-warnings タスクを追加した。(Scala 2.

sbt プラグインのまとめ

XML ベースのビルドツールと比較すると sbt はビルド定義を (.sbt と .scala の両方とも) Scala を使って書くという違いがある。それにより一度 sbt のコンセプトや演算子を押さえてしまえば、ビルドユーザが sbt プラグインを書き始めるのにあまり労力がいらない。 既にあった sbt 0.7 のプラグインも移植してきたが、オリジナルのも書いているのでまとめて紹介したい。 sbt-dirty-money sbt-dirty-money は Ivy キャッシュを何となく選択的に消去するためのプラグインだ (~/.ivy2/cache 下の organization と name を含むもの)。たった 25行の簡単な実装だけど、clean-cache と clean-local の 2つのタスクは僕の役に立っている。 例えば、何かプラグインを開発していてそれがテスト用の hello プロジェクトにおいてキャッシュされているかどうかが不明であるとする。 プラグインプロジェクト中から clean-cache と clean-local の両方を走らせ、hello プロジェクトを reload することでプラグインが解決できないかどうかを確認する。解決できなければ、どこか知らない所から引っ張ってきてるわけではないということなので成功だ。 sbt-buildinfo sbt-buildinfo は前から書こうと思っていたプラグインの一つだ。これはビルド定義から Scala のソースを生成する。主な目的はプログラムが自身のバージョン番号を意識することにある (特に、conscript を使ったアプリの場合)。 sourceGenerators を使ってバージョン番号を含むオブジェクトを生成するスクリプトをちゃちゃっと書いたことが何回かあったが、他の人にも使ってもらえるようにするにはプラグインにするのが適してると思った。state から値を抽出することで sbt-buildinfo は任意の複数のキーから Scala ソースを生成する。以下を build.sbt に加える: buildInfoSettings sourceGenerators in Compile <+= buildInfo buildInfoKeys := Seq[Scoped](name, version, scalaVersion, sbtVersion) buildInfoPackage := "hello" これで以下が生成される:

Scala 並列コレクションライブラリ

並列コレクションライブラリのガイドを翻訳して、docs.scala-lang.org に取り込んでもらいました。 原文は EPFLの研究アシスタントで、並列コレクションの設計書である A Generic Parallel Collection Framework (pdf) という論文の第一著者でもある Aleksandar Prokopec さんと 現在アメリカから EPFL に留学中で、並列と分散プログラミングモデルを研究していて、コミュニティ内ではドキュメンテーションツァーとしても知られる Heather Miller さんです。

treehugger.scala pamflet

treehugger はコードを用いて Scala のソースコードを書くためのライブラリだ。それはまた、Refelection API に基づく Scala AST の代替実装の一つでもあり、github で eed3si9n/treehugger として公開している。 更新: この記事を拡張して本当かっこいい n8han/pamflet を使ってガイドに仕上げてみました(今のところ英語だけです): treehugger のパンフレット

暗黙のパラメータ解決優先順位

Scala という言語は、僕の使ったことのある中では最もエレガントで、表現力に富み、一貫性があり、かつ実利的な言語の一つだと思う。パターンマッチングや統一形式アクセスの原則などはじめ、その筋の良さは枚挙にいとまがない。そして、Scala エコシステムと Scala コミュニティーはその言語をより強力なものにしている。

Scala 2.9.1 において、ローカルで宣言された implicit はインポートされたものよりも優先される。問題は、言語仕様にはそのような振る舞いは書かれていないことだ。僕の当初の仮説は、自分が言語仕様を正しく理解していないか、もしくは言語仕様に抜け穴があるかのどちらかだろうというものだった。とにかく、その仮説に基づいて暗黙のパラメータ解決の優先順位について色々調べた結果を先週書いた。「怪しい伝説」でもよく言われるように、全く予期していなかった結果が出てきたときが最も面白いものとなる。後で分かったのは、仮説の両方とも間違っていたということだ。

つまり、関連部分に関する僕の仕様の理解は正しく、仕様も正しいということだ。SI-5354 によると、間違っていたのはコンパイラの実装だった。

再考「import 税のかからない implicit」

Northeast Scala Symposium 2012 もあと数ヶ月という所だけど、2011年をまとめるという形で去年のシンポジウムでの発表の一つを再考してみたい。とにかく、nescala は次から次へとクオリティの高い発表があった。これらの全ては、ここで見ることができる。Daniel の関数型のデータ構造と Janas の Akka がそれぞれ一時間のキーノートがあったこともあり、Scala コミュニティーの中に FP とアクターという二つの潮流が形成されつつあることが印象に残った(Paul がアクターのメッセージの送信には参照透過性が無いと宣言したのもヒントだったかもしれない)。また、一年のその後の予兆とも言えた Mark の sbt 0.9 のプレゼンや Nermin による Scala のパフォーマンスに関する考察もあった。しかし、僕の中で直ちにコードを変更する必要に迫られような直接的なインパクトという意味で抜きん出た発表は Josh の発表だった: Implicits without the import tax: How to make clean APIs with implicits. (import 税のかからない implicit: implict を用いていかにクリーンな API を作るか) ビデオ スライド 暗黙のパラメータ解決 Josh の発表の大きな点は、暗黙のパラメータ (implicit parmeter) はいくつものレイヤーを順番に見ていくことで解決され、ワイルドカード import は高い優先順位を占めるため、ライブラリがそれを使ってしまうとユーザがそれをオーバーライドできなくなってしまうということだった。 このポストにおいて、implicit の解決優先順位を Scala Language Specification を読んだりコードで試していくことで探検していきたい。せっかちな人のために、最終的に導きだされた優先順位を以下に示した: Implicits with type T defined in current scope. (relative weight: 3) Less specific but compatible view of type U defined in current scope.

Iterator パターンの本質

これは Scala Advent Calendar 2011 の 17日目の記事です。 specs2 の作者であり、@etorreborre としても活発に発言を続けるシドニーの強豪 Eric Torreborre さんが書いた “The Essence of the Iterator Pattern” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。 2011年6月24日 Eric Torreborre 著 2011年12月17日 e.e d3si9n 訳 去年読んだ論文で一番気に入ったのは “The Essence of the Iterator Pattern”(以下、EIP)だ。これを読んだ後で、今まで何年も使い続けてきたあるものに対する考えがガラリと変わった。それは、for ループだ。 この論文の中からいくつかのアイディアを紹介して、書かれている解法の実装方法を Scalaz っぽいコードを使って説明する。以前に関数型プログラミング、ファンクタ、モナドなどに少しでも触れたことがあれば、役立つと思う! for ループの中身は何だ? これが、本当に僕がハマったキッカケだ。「for ループの中身は何だ」とはどういう意味だ? 僕が何年も使ってきたこの構文に、何か魔法は入っていないだろうか? EIP の導入部に、(C のような添字を使った for ではなく)各要素を一つづつ順に返すタイプの for ループの例がでてくる。ここでは、Scala に変身させて書くけど、考え方は一緒だ: val basket: Basket[Fruit] = Basket(orange, apple) var count = 0 val juices = Basket[Juice]() for (fruit <- basket) { count = count + 1 juices.

フィールドテスト: conscript, giter8, sbt-dirty-money

Scala のツールを使った、日常のコーディングでのテクニックを紹介したい。 例えば、ツールとかライブラリを開発してるとして、バグ報告を受けるとする。まず原因の分析に入る前に僕が集中することは、ユーザが使っているのと同じデータで問題を再現することだ。問題が再現できれば、次に問題を単純化して失敗する spec や機能テストに落としこむことに移行する。バグが修正されれた後で、同じセットアップを使って実際のデータでもバグが直っているかを確認することができる。

始める sbt: 公式ガイド

sbt プロジェクトからついに、公式ガイドと言える Getting Started Guide が出てきたので、翻訳しました。原文は、Heroku に Scala を載せたりなんかしてる、Typesafe 社の Havoc Pennington 氏により全て書かれています。

非公式 sbt 0.10 ガイド v2.0

version 2.0 2011年6月19日に最初のバージョンを書いた時点での僕の動機は、運良く Mark による sbt 0.10 のデモを二回も生で見れたことに触発されて(最初は northeast scala、次に scala days 2011)、sbt 0.7 から 0.10 へと皆が移行するのを手助けしたかったからだった。プラグインがそろっていなければビルドユーザが 0.10 に移行できないため、プラグインが移行への大きな妨げになるというのが大方の考えだった。そこで僕が取った戦略は、無いプラグインは自分で移植して、つまずいたらメーリングリストで質問して、結果をここでまとめるというものだった。それにより、多くのポジティブな反応があったし、数人を 0.10 へ移行する手助けにもなったと思う。だけど、後ほど明らかになったのは、僕の sbt 0.10 に関する理解は完全なものではなく、時として全く間違っており誤解を与えるものだったということだ。文責は僕にあるが、古い内容をそのまま残しておくのではなく、github に push して、新しいバージョンを作って、前へ進むことにした。プラグインの作成に関する最新の知識は Plugins Best Practices にまとめられており、大部分は Brian と Josh、ちょこっとだけ僕により書かれている。 慌てるな (don’t panic) さっき 0.7 の世界から着陸したばっかりの君。sbt 0.10 があまりにも違うのでビックリすることだと思う。ゆっくり時間をかけて概念を理解すれば、必ず分かるようになるし、sbt 0.10 の事がきっと大好きになることを約束する。 三つの表現 sbt 0.10 とやり取りするのに三つの方法があるため、最初は混乱するかもしれない。 sbt 0.10 を起動時に現れるシェル。 build.sbt や settings 列に入る Quick Configurations DSL。 普通の Scala コード、別名 Full Configuration。 それぞれの表現は別々の使用モデルに最適化している。sbt を単にプロジェクトをビルドするのに使っている場合は、ほとんどの時間を publish-local などのコマンドを使って、シェルの中で過ごすだろう。次にライブラリの依存性など基本的な設定の変更を行いたい場合、build.sbt の Quick Configurations DSL に移行する。最後に、サブプロジェクトを定義したり、プラグインを書く場合には、Full Configuration を使うことで Scala のパワーを発揮することができる。

sbt プラグインをテストする

テストの話をしよう。一度プラグインを書いてしまうと、どうしても長期的なものになってしまう。新しい機能を加え続ける(もしくはバグを直し続ける)ためにはテストを書くのが合理的だ。だけど、ビルドツールのプラグインのテストなんてどうやって書けばいいんだろう?もちろん飛ぶんだよ。 scripted test framework sbt は、scripted test framework というものが付いてきて、ビルドの筋書きをスクリプトに書くことができる。これは、もともと 変更の自動検知や、部分コンパイルなどの複雑な状況下で sbt 自体をテストするために書かれたものだ: ここで、仮に B.scala を削除するが、A.scala には変更を加えないものとする。ここで、再コンパイルすると、A から参照される B が存在しないために、エラーが得られるはずだ。 [中略 (非常に複雑なことが書いてある)] scripted test framework は、sbt が以上に書かれたようなケースを的確に処理しているかを確認するために使われている。 正確には、このフレームワークは siasia として知られる Artyom Olshevskiy 氏により移植された scripted-plugin 経由で利用可能だが、これは正式なコードベースに取り込まれている。 ステップ 1: snapshot scripted-plugin はプラグインをローカルに publish するため、まずは version を -SNAPSHOT なものに設定しよう。 ステップ 2: scripted-plugin 次に、scripted-plugin をプラグインのビルドに加える。project/scripted.sbt: libraryDependencies <+= (sbtVersion) { sv => "org.scala-sbt" % "scripted-plugin" % sv } 以下を scripted.sbt に加える: ScriptedPlugin.scriptedSettings scriptedLaunchOpts := { scriptedLaunchOpts.value ++ Seq("-Xmx1024M", "-XX:MaxPermSize=256M", "-Dplugin.

sff4s: simple future facade for Scala

future の実装には様々なものがあるけど、標準ライブラリの中に共通の親 trait があれば、特定のプラットフォームスタックにコードを依存させずにこの概念を表現できるのにと思っていた。そう思う人が他にもいるかは分からないけど、ライブラリの作者なんかには役に立つんじゃないかな。取り敢えずこれが、sff4s を書いた動機だ。 future って何? 多分名前ぐらいは聞いたことあるかもしれないけど、一応おさらいしよう。future値(promise とも呼ばれる)は未完の計算を表現する。 future値は未完の計算を表現する。 これがよく使われる説明だけど、それだけでは分からない。ここで言外に含まれているのは、その計算は裏で行われているということだ。それは同じコンピュータ内の別のスレッドか、別のサーバの中かもしれないし、行列待ちでまだ計算は始まってさえいないかもしれない。とにかく、計算は現在の制御フローの外で行われているということだ。 計算はどこか別の所で行われる。 future値のもう一つの側面は、そのうちに計算結果を得られるということだ。Scala の場合は def apply() を呼び出すなどの明示的なステップを要する。計算が未完の場合は、ブロック(block)する。つまり、計算結果が得られるまで待たされる(もしくはタイムアウトする)。 future値から計算結果を得ることができる。 最初に future値が宣言された時には計算結果は有るかもしれないし、まだ無いかもしれない。うまくいけば、ある時点で結果が到着し、オブジェクトの内部構造が変更される。これを、future値を「解決」(resolve)したという。勝手に状態が変わるものというのはプログラミングではあまり見かけないので、少し不気味ではある。 計算結果を解決するための裏口がある。 これまでで、最も単純な形の future値を記述した。実際に役に立つには他の機能も必要だけど、これでも使えないことはない。ちょっと使用例をみてみよう: val factory = sff4s.impl.ActorsFuture val f = factory future { Thread.sleep(1000) 1 } f() // => これは 1秒間ブロックした後で 1 を返す 細かい事は気にしないで、最後の一行の振る舞いだけ見てほしい。このように、計算結果を取得することを、強要(forcing)するともいう。最小限の API は以下のようになる。 Future v0.1 abstract class Future[+A] { /** 計算結果を強要して無期限にブロックする */ def apply(): A } Scala から使用可能な future値の実装にはいくつかあるけど、どれも一から書かれてる。上のような共通な親クラスがあれば、特定のライブラリに依存しないコードを書くことができる。 まだ来ない? Future v0.1 に対して唯一できる事が計算結果が戻ってくるまでブロックしてしまうので、あまりにも不便だ。待つことしかできないから future を使わないほうがいい。そのため、全ての future値が提供するもう一つの機能として、計算結果の用意ができたかを確かめるノンブロッキング(non-blocking)な方法がある。これは実装によって isDone、isSet、isDefined、isCompleted などと呼ばれているが、全て同じ意味だ。今のところ、僕の好みとしては def isDefined: Boolean がいいと思う。future を概念的に Option の変数として考えることができるからだ。

モナドはメタファーではない

Scala界の関数型プログラミング一派を代表する論客の一人、@djspiewak が 2010年に書いた “Monads Are Not Metaphors” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。

2010年12月27日 Daniel Spiewak 著 2011年5月29日 e.e d3si9n 訳

僕は今、約束を破るところだ。およそ三年前、僕は絶対にモナドの記事だけは書かないと自分に約束した。既にモナドに関する記事は有り余っている。記事の数が多すぎてその多さだけで多くの人は混乱している。しかも全員がモナドに対して異なる扱い方をしているため、モナドの概念を初めて学ぼうとする者は、ブリトー、宇宙服、象、砂漠のベドウィン (訳注: アラブ系遊牧民) の共通項を探す努力をするハメになっている。

僕は、この混乱した喩え話のサーカスにわざわざもう一つ追加するようなことはしない。まず、どの喩え話も完全には正確では無い。どの喩えも全体像を伝えきれていないし、いくつかは重要な点に関して露骨に誤解を招くような内容になっている。メキシコ料理や宇宙(そら)に思いをはせることでは、絶対にモナドを理解することはできない。モナドを理解する唯一の見方は、それをありのままの姿、つまり数学的概念として見ることだ。

実戦での Scala: Cake パターンを用いた Dependency Injection (DI)

Akka の作者として益々注目を集めている Jonas Bonér が 2008年に書いた “Real-World Scala: Dependency Injection (DI)” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。 2008年10月6日 Jonas Bonér 著 2011年4月22日 eed3si9n 訳 さて、実戦での Scala シリーズ第二弾の今回は、Scala を用いた Depenency Injection (DI) の実装をみていきたい。Scala は、備わっている言語機構だけを用いても何通りかの DI を実現できる非常に豊かでディープな言語だが、必要に応じて既存の Java DI フレームワークを使うこともできる。 Triental では、一つの戦略に落ち着くまで三つの異なる方法を試した。以下のように話を進めていく。まず、現行の DI の実現方法を詳しく説明した後で、試した他の方法も簡単にカバーする。 Cake パターンを用いる 私たちが用いている現行の戦略は、いわゆる Cake パターンに基づいている。このパターンは、Martin Odersky の論文 Scalable Component Abstractions において、Ordersky と彼のチームが Scala のコンパイラを構成した方法として最初に発表された。このパターンがどのようにして DI を実現するのかということを日本語で説明する事を試みるよりも、(私たちの実際に使っているコードに大まかに基づいた)愚直なサンプルコードをみてみよう。 注意: 順を追って、最終バージョンに向けてリファクタリングしながら説明していくので、最終バージョンを読んで理解するまでは、「ダメじゃん!」と叫ぶのは待ってほしい(もちろん、読了後にどうしてもと言うなら批判、賞賛、意見、アイディアなどを送ってもいい)。また、このサンプルコードは、このようなサンプルの例にもれず、非常に複雑な方法で取るに足りない事を行っているようにみえるが、我慢して大規模システムでの実際のサービスを想像して、どのように応用できるかを想像して欲しい。 まずは、UserRepository (DAO、Data Access Object) を実装しよう。 // 実際の永続化は何もしていなくて、画面にユーザを表示するだけのダミー。 class UserRepository { def authenticate(user: User): User = { println("authenticating user: " + user) user } def create(user: User) = println("creating user: " + user) def delete(user: User) = println("deleting user: " + user) } trait インターフェイスとその実装に分けて実装することもできたが、話を簡単にするために、敢えてここではそうしなかった。

Scala と Json で tweed を織る

次々とヤバいコードを紡ぎ出し NY Scala シーンの中心的存在であり続ける @n8han が二年前に書いた “Weaving tweed with Scala and Json” を翻訳しました。翻訳の公開は本人より許諾済みです。翻訳の間違い等があれば遠慮なくご指摘ください。 2009年5月27日 n8han 著 2011年1月2日 eed3si9n 訳 抽出子は、Programming in Scala の 24章にのみ記述されている Scala の秘密機能で、この春の大ヒットだ。今までは皆 case Some(thing) => kerpow(thing) で満足だったのが、今では抽出子を書けなければ #scala freenode にも入れてもらえない。ズルをすれば Scala チャンネルの硬派な常連たちは君のコンピュータをハックして驚くほど馬鹿げたドールハウスを連続再生して(ただし混浴シャワーシーンを除く)、番組の「アクティブ」のように意味のあるタイピングを諦めなければいけない。 訳注。以下 Draco より抜粋 ロッサム・コーポレーションは人間の人格、経験をすべて消し、新しい人格を植え付ける技術を開発した。彼らはこの技術を用いて、戦闘用の人形アクティブを生み出した。 人形たちはドールハウスという施設で生活している。誰かの人格を移植され、任務に挑む。 アクティブの一人、エコーは記憶のリライト中にエラーが起こり、完全には記憶が消されていなかった。 この抽出子はちょっとチクっとしますからね 命からがら逃げ出した僕は抽出子をありとあらゆる状況に適用するよう努めた。例えば、JavaScript インタプリタが理解できるお洒落な文字列、Json オブジェクトだ。抽出子を使えば case 構文でこのように処理することができる: import dispatch.json.Js val echo = Js("""{"acting": "無表情で前を見ている"}""") object Echo extends Js { val acting = 'acting ? str } echo match { case Echo.

IntelliJ IDEA のための Twilight

Scala をやりながら他の IDE も試しましたが、結局 TextMate に戻っています。 今回巷で話題の IntelliJ IDEA に便乗するにあたって、Twilight theme を作りました。

screenshot

型クラスによる XML データバインディング

結局の所,scalaxb のユーザはエンティティ・オブジェクトが表現する現実の問題に興味があるのであって,それがどう XML に永続化されるかといったことではない.だから,いつかデータバインディングの実装をシングルトン/コンパニオン・オブジェクトから追い出さなければいけないことは分かっていた.つい最近までデータバインディングの実装は以下のように生成されていた: object Address extends rt.ElemNameParser[Address] { val targetNamespace = "http://www.example.com/IPO" def parser(node: scala.xml.Node): Parser[Address] = ... def toXML(__obj: Address, __namespace: String, __elementLabel: String, __scope: scala.xml.NamespaceBinding): scala.xml.NodeSeq = ... } つまり,scalaxb は Address そのものとは関係の無い XML データバインディングのために一等地をハイジャックしてしまったのだ. adapter まず最初に以下のような adapter オブジェクトに追い出すことを考えた: object DefaultXMLAdapter { object AddressAdapter extends rt.ElemNameParser[Address] { val targetNamespace = "http://www.example.com/IPO" def parser(node: scala.xml.Node): Parser[Address] = ... def toXML(__obj: Address, __namespace: String, __elementLabel: String, __scope: scala.xml.NamespaceBinding): scala.xml.NodeSeq = .

sjson: Scala の型クラスによる JSON シリアライゼーション

Debasish Ghosh さん (@debasishg) の “sjson: Now offers Type Class based JSON Serialization in Scala” を翻訳しました. 元記事はこちら: http://debasishg.blogspot.com/2010/07/sjson-now-offers-type-class-based-json.html (翻訳の公開は本人より許諾済みです) 翻訳の間違い等があれば遠慮なくご指摘ください 長い間 sjson のシリアライゼーション API はリフレクションに依存するものだった.この方法の長所としては,縁の下ではリフレクションによる実装が頑張っていても API は使いやすくすることができたということだ. しかし,JSON 構造と Scala のオブジェクトでは型情報の豊かさに大きな違いがあることを忘れてはいけない.Scala から JSON にいくときに何らかの形で型情報をシリアライゼーションプロトコルの一部として保存しないかぎり,可逆変換させるのは場合によってはとてもトリッキーで難しいことになる.特に JVM では type erasure のせいで JSON構造にシリアル化した Scala オブジェクトの中には元に戻すのがほぼ不可能なものもあるだろう. ver 0.7 より sjson は元のものに加えリフレクションを使わない JSON シリアライゼーションプロトコルを用意した.これはユーザが任意のオブジェクトから JSON へシリアル化する自分のプロトコルを規定できるようになった.リフレクションによる JSON シリアライゼーションではアノテーションで行っていたものをカスタムプロトコルを自分で実装することで実現することができる. sjons の型クラスによるシリアライゼーションは David MacIver による素晴らしい sbinary (現在は Mark Harrah によりメンテされいる) にインスパイアされており,同じプロトコルを使いまた実装レベルでも色々と盗ませてもらった. 型クラスの基礎的概念への入門,Scala での実装,そして型クラスを使ったシリアライゼーションプロトコルが Scala でどう設計できるかについては,数週間前に書いた以下の blog 記事を参照してほしい:

Scala Implicits: 型クラス、襲来

Debasish Ghosh さん (@debasishg) の “Scala Implicits : Type Classes Here I Come” を翻訳しました. 元記事はこちら: http://debasishg.blogspot.com/2010/06/scala-implicits-type-classes-here-i.html (翻訳の公開は本人より許諾済みです) 翻訳の間違い等があれば遠慮なくご指摘ください. 先日 Twitter 上で Daniel と Scala での型クラスについて論議していると,突然このトピックに関する書きかけだった記事を発見した.これを読んでもあなたは特に目新しい事を発見するわけではないが,型クラスに基づいた思考はあなたの設計の幅に価値を与えることができると思う.この記事を書き始めたのはしばらく前に設計の直交性についての記事 (原文)を公開したときのことだ. まずは GoF の Adapter パターンから始めよう.委譲型の Adapter はよく勧められる合成(composition)というテクニック用いて抽象体(abstraction)1どうしをバインドする. 設計の直交性のときと同じ例を使うと, case class Address(no: Int, street: String, city: String, state: String, zip: String) これを LabelMaker というインターフェイスに適合させたいとする.つまり,我々は Address オブジェクトを LabelMaker として使いたい. trait LabelMaker[T] { def toLabel(value: T): String } インターフェイス変換を行うアダプターは… // Adapter クラス case class AddressLabelMaker extends LabelMaker[Address] { def toLabel(address: Address) = { import address.

Scala 型クラスへのリファクタリング

Debasish Ghosh さん (@debasishg) の “Refactoring into Scala Type Classes” を翻訳しました. 元記事はこちら: http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html (翻訳の公開は本人より許諾済みです) 翻訳の間違い等があれば遠慮なくご指摘ください. 二週間ほど前に Scala の暗黙の(implicit)パラメータを用いた型クラスの実装について書いた.型クラスはある抽象体(abstraction)についての直交した関心事を,抽象体そのものに直接組み込むことなくモデル化することができる.これでコアな抽象体から余計なものを取り去って,別々の独立したクラス構造に変えていくことができる.最近 Akka actor のシリアライゼーションをリファクタリングして型クラスの恩恵に関する実地的な知見を得ることができたので,ここに報告したい. 最初は継承と trait でうまくいくと思った… … しかし,それは長続きしなかった.Jonas Boner と筆者の間で actor のシリアライゼーションに関して面白い論議があり,以下のような設計が生まれた … trait SerializableActor extends Actor trait StatelessSerializableActor extends SerializableActor trait StatefulSerializerSerializableActor extends SerializableActor { val serializer: Serializer //.. } trait StatefulWrappedSerializableActor extends SerializableActor { def toBinary: Array[Byte] def fromBinary(bytes: Array[Byte]) } // .. 以下続く このような trait はシリアライゼーションという関心事をコアな actor の実装と結合(couple)させすぎてしまう.様々なシリアライズ可能な actor があるため,良いクラス名が足りなくなってきていた.GoF本が教えてくれる知恵の一つにインターフェイスを用いたクラスの命名に困るとしたら,間違ったことをやっている,というものがある.関心事をより意味のある方法で分割する別のやり方を探ろう.