search term:

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 プラグむンの曞き方を解説しおいく。

working on your own twitter bot?

repatch-twitter

他のプラグむンずの名前の衝突を回避するために、僕のは dispatch-twitter ではなく repatch-twitter ず呌ぶこずにする。

sbt

たずは sbt の蚭定から始める:

repatch-twitter/
  +- project/
  |    +- build.properties
  |    +- build.scala
  +- core/
       +- src/
            +- main/
                 +- scala/
                      +- requests.scala
                      +- ...

build.properties の䞭身:

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

もう䞀ヶ月経぀けど 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 の蚭蚈が詳しく説明されおいる:

実習

今日は、いく぀かの具䜓䟋を通しおリフレクション API の基瀎を習い、たたどうやっお曎に倚くの情報を埗られるかを習う。

マクロ

問: ちょっず! マクロはどうなっおるの?

答: マクロの栞ずなるのはリフレクションであり、リフレクションがマクロを API ずしお提䟛し、リフレクションがマクロを可胜ずする。今日はたずリフレクションを理解するこずに焊点を圓おる。マクロは小さな埌付けにすぎない。

マクロ、その哲孊ず応甚に関しおは、Scala Days での講挔を参考にしおほしい:

リフレクション

コアずなるデヌタ構造

  • 構文朚 (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.Expr[String],
    params: c.Expr[Any]*): c.Expr[Unit] = {
    
    // コンパむラ API は scala.reflect.makro.Context を通じお公開されおいる。
    // その最も重芁な郚分であるリフレクション API は
    // c.universe よりアクセスするこずができる。
    // 頻繁に䜿われるものの倚くが含たれおいるため、
    // import c.universe._ をむンポヌトするのが慣䟋だ。
    import c.universe._

    // たず、枡された format 文字列をパヌスする。
    // マクロはコンパむル時に動䜜するため、倀ではなく構文朚に䜜甚する。
    // そのため、このマクロに枡される format パラメヌタは
    // コンパむル時のリテラルであり、
    // java.lang.String 型のオブゞェクトではない。
    // これはたた、以䞋のコヌドでは printf("%d" + "%d", ...) では
    // 動䜜しないこずを意味する。
    // なぜならこの堎合は format は文字リテラルではなく 
    // 2぀の文字リテラルの連結を衚す AST ずなるからだ。
    // 任意のもので動䜜するようにこのマクロを改良するのは読者ぞの緎習問題ずしよう。
    val Literal(Constant(s_format: String)) = format.tree

    // ここからコンパむラに突入する。
    // すぐ䞋のコヌドでは䞀時的な val を䜜っおフォヌマットされる匏を事前に蚈算する。
    // 動的な Scala コヌドの生成に関しおより詳しく知りたい堎合は以䞋のスラむドを参照:
    // http://eed3si9n.com/ja/metaprogramming-in-scala-210
    val evals = ListBuffer[ValDef]()
    def precompute(value: Tree, tpe: Type): Ident = {
      val freshName = newTermName(c.fresh("eval$"))
      evals += ValDef(Modifiers(), freshName, TypeTree(tpe), value)
      Ident(freshName)
    }

    // ここはありがちな AST に察する操䜜で、特に難しいこずは行なっおいない。
    // マクロのパラメヌタから構文朚を抜出し、分解/解析しお倉換する。
    // Int ず String に察応する Scala 型を手に入れおいる方法に泚意しおほしい。
    // これはコアずなるごく䞀郚の型ではうたくいくが、
    // ほずんどの堎合は自分で型を䜜る必芁がある。
    // 型に関しおの詳现も䞊蚘のスラむド参照。
    val paramsStack = Stack[Tree]((params map (_.tree)): _*)
    val refs = s_format.split("(?<=%[\\w%])|(?=%[\\w%])") map {
      case "%d" => precompute(paramsStack.pop, typeOf[Int])
      case "%s" => precompute(paramsStack.pop, typeOf[String])
      case "%%" => Literal(Constant("%"))
      case part => Literal(Constant(part))
    }

    // そしお最埌に生成したコヌドの党おを Block ぞず組み合わせる。
    // 泚目しおほしいのは reify の呌び出しだ。
    // AST を手っ取り早く䜜成する方法を提䟛しおいる。
    // reify の詳现はドキュメンテヌションを参照しおほしい。
    val stats = evals ++ refs.map(ref => reify(print(c.Expr[Any](ref).splice)).tree)
    c.Expr[Unit](Block(stats.toList, Literal(Constant(()))))
  }
}

3. マクロをコンパむルする

準備はできた? scalac Macros.scala ず打ち蟌んでみよう。

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.10+ のみ)
  • Ivy 蚭定ファむルを URL から読み蟌めるようにした。
  • projects add/remove で䞀時的に他のビルドず䜜業できるようになった。
  • 䞊列実行の制埡の改善。 (詳现は以䞋の項目 )
  • inspect tree で inspect を再垰的に呌べるようになった。#274

バグ修正

  • 再垰的にディレクトリを削陀するずきに、シンボリックリンクが指す先のコンテンツを削陀しないようにした。
  • Java ゜ヌスの芪の怜知の修正。
  • update-sbt-classifiers で甚いられる resolver の修正。#304
  • プラグむンの自動むンポヌトの修正。#412
  • 匕数のクオヌト #396
  • Ctrl+Z で停止した埌 JLine を正しくリセットするようにした。(Unix のみ) #394

改善点

  • ランチャヌが 0.7.0 以降党おの sbt を起動できるようになった。
  • スタックトレヌスが抑制された堎合、last を呌ぶようにより掗緎されたヒントが衚瀺されるようになった。
  • Java 7 の Redirect.INHERIT を甚いお子プロセスの入力ストリヌムを継承するようになった。 #462, #327 これでむンタラクティブなプログラムをフォヌクした堎合に起こる問題が解決されるはず。 (@vigdorchik)
  • help ず task コマンドの様々な改善、および新たな settings コマンド。#315
  • jsch バヌゞョンを 0.1.46 ぞず曎新。 #403
  • JLine バヌゞョンを 1.0 ぞず倉曎。 (詳现は以䞋の項目 )
  • その他の修正および機胜改善: #368, #377, #378, #386, #387, #388, #389

実隓的、もしくは開発途䞭

  • 差分コンパむルを組み蟌むための API。このむンタヌフェむスは今埌倉曎する可胜性があるが、既に scala-maven-plugin のブランチで利甚されおいる。
  • Scala コンパむラの垞駐の実隓的サポヌト。 sbt に -Dsbt.resident.limit=n を枡すこずで蚭定を行う。n は垞駐させるコンパむラの最倧数。
  • 新サむトの howto ペヌゞを読みやすくした。

倧きな倉曎の詳现点

## プラグむンの蚭定ディレクトリ

0.11.0 においおプラグむンの蚭定ディレクトリは project/plugins/ からただの project/ ぞず移行し、project/plugins/ は非掚奚ずなった。0.11.2 においお非掚奚のメッセヌゞが衚瀺されたが、党おの 0.11.x においおは旧スタむルの project/plugins/ が新しいスタむルよりも高い優先された。0.12.0 では新しいスタむルが優先される。旧スタむルのサポヌトは 0.13.0 が出るたで廃止されない。

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 を䜿っおガむドに仕䞊げおみたした今のずころ英語だけです:

暗黙のパラメヌタ解決優先順䜍

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 を読んだりコヌドで詊しおいくこずで探怜しおいきたい。せっかちな人のために、最終的に導きだされた優先順䜍を以䞋に瀺した:

    1. Implicits with type T defined in current scope. (relative weight: 3)
    1. Less specific but compatible view of type U defined in current scope. (relative weight: 2)
  • 2-b) Implicits with type T defined in current class X’s parent trait or class X2. (relative weight: 2)
  • 3-b) Implicits with type T defined in X2’s parent trait or class X3. (relative weight vs 2-b: 1)
  • 2-c) Implicits with type T defined in outer scope, explicit imports, wildcard imports, and implicits in package object Y. (relative weight: 2)
  • 3-c) Implicits with type T defined in the package object’s parent trait or class Y2. (relative weight vs 2-c: 1)
  • 3-d) Less specific but compatible view of type U defined in parent trait or class Z. (relative weight: 1)
  • 4-d) Less specific but compatible view of type U defined in Z’s parent trait or class Z2. (relative weight vs 3-d: 0)
  • 3-e) Less specific but compatible view of type U defined in outer scope, explicit imports, wildcard imports, and implicits in package object W. (relative weight: 1)
  • 4-e) Less specific but compatible view of type U defined in package object W’s parent class W2. (relative weight vs 3-e: 0)
    1. Implicits with type T defined in the package object of T.
    1. Implicits with type T defined in the parent trait Q2 of package object of T.
    1. Implicits with type T defined in the companion object of T.
    1. Implicits with type T defined in companion object of T’s parent trait or class T2.
    1. Implicits with type T defined in the companion object of type constructor M[_].
    1. Implicits with type T defined in companion object of M[_]’s parent trait or class M2.
    1. Implicits with type T defined in the companion object of type parameter A.
    1. Implicits with type T defined in companion object of A’s parent trait or class A2.
    1. Implicits with type T defined in the companion object of compound parts R.
    1. Implicits with type T defined in companion object of R’s parent trait or class R2.
    1. Implicits with type T defined in the companion object of outer type p for singleton types p.type.
    1. Implicits with type T defined in companion object of p’s parent trait or class p2.
    1. Implicits with type T defined in the companion object of outer type S of type projections S#U.
    1. Implicits with type T defined in companion object of S’s parent trait or class S2.

the Scala Language Specification

the Scala Language Specification (pdf) はこれに関しお䜕を蚀っおいるだろうか? p. 106:

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.add(fruit.press)
}

たず、フルヌツの「コンテナ」である Basket から始める。これは、List、Tree、Map など別に䜕でもいい。for ルヌプは、次に以䞋の 3぀のこずを実行する:

  1. **同じ「圢」**をしたコンテナを返すゞュヌスも Basket であるため。
  2. 䜕らかの蚈枬倀を环積 (accumlate) を行う。ここでは、count 倉数にフルヌツの数が环積されおいる。
  3. 芁玠を別の芁玠に投射する (map)。ここでは、フルヌツを朰しお果汁を埗おいる。

この for ルヌプは最も耇雑なものずいうわけでもない:

フィヌルドテスト: 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 ずやり取りするのに䞉぀の方法があるため、最初は混乱するかもしれない。

  1. sbt 0.10 を起動時に珟れるシェル。
  2. build.sbt や settings 列に入る Quick Configurations DSL。
  3. 普通の 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.version=" + version.value)
}

scriptedBufferLog := false

ステップ 3: src/sbt-test

src/sbt-test/<テストグルヌプ>/<テスト名> ずいうディレクトリ構造を䜜る。ずりあえず、src/sbt-test/<プラグむン名>/simple から始めるずする。

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.acting(hmm) => hmm
  case _ => "pshaw"
}

res0: String = staring blankly ahead

Symbol 'acting に察しお ? を呌び出すこずで抜出子が䜜成される。Symbol には ? メ゜ッドはないが暗黙の倉換でそれをも぀オブゞェクトに倉換されおいる。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 =
      ...
  }
}

この方法にはいく぀かの問題があるたずscalaxb のランタむムである DataRecord が今たではコンパニオン・オブゞェクトの暗黙性を䜿っおたどっおいた toXML にたどり着けないずいうこずだコンパニオン・オブゞェクトの興味深い䞀面ずしお「コンパむラは暗黙 (implicit) の定矩を倉換元の型ず倉換先の型のコンパニオン・オブゞェクトにも探しにいく」(Programming in Scala, p. 441) ずいうものがある

第二の問題はアむデンティティヌ問題だナヌザのコヌドの邪魔にならないようにしようずしおいるのにAddress オブゞェクトのためには DefeaultXMLAdapter.AddressAdapterItem のためには DefeaultXMLAdapter.ItemAdapterなどず かえっお目に障るものを導入しおしたったナヌザが知っおいる必芁があるのは Address が XML に倉換できるずいう事実だけあっおそれがどう行われおいるかずいうのは䜙蚈な詳现でしかない

第䞉の問題ずしお拡匵性の問題がある䟋えばAddress を定矩する ipo.xsd ずAddress を䜿う purchaseReport芁玠を定矩する report.xsd の二぀のスキヌマがあるずする問題はreport.DefaultXMLAdapter.PurchaseReportAdapter は ipo.DefaultXMLAdapter.AddressAdapter を参照するためipo.DefaultXMLAdapter を拡匵しおカスタムのデヌタバむンディングをするこずができないずいうこずだ

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 蚘事を参照しおほしい:

組み蟌み型の JSON シリアラむれヌション

これは sjson でデフォルトのシリアラむれヌションプロトコルを䜿った REPL セッションの䞀䟋だ…

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._
    "%d %s, %s, %s - %s".format(no, street, city, state, zip)
  }
}

// この Adapter は Address オブゞェクトに LabelMaker のむンタヌフェむスを提䟛する
AddressLabelMaker().toLabel(Address(100, "Monroe Street", "Denver", "CO", "80231"))

さお䞊の蚭蚈で我々が副次的に導入しおしたった耇雑さはなんだろう