かとじゅんの技術日誌

技術の話をするところ

Baseunits for Scala を 作ってみました。

Scalaで初プロダクトということで、日常的に使うものからということで、以下のBaseunitsのScala版を作ってみました。

Baseunits Library - 都元ダイスケ IT-PRESS

ScalaJavaの資産が使えるので、普通に考えるとBaseunitsのJava版を使えばよいわけです。しかし、不変性やOption型によるnull回避や、コレクションの違いなどを想定すると、Javaとは文化が違う言語だという認識でScala版を作りました。

どんな言語でも同じでしょうが、ある程度の規模のScalaコードを書くと手に馴染みますね。Scalaのコレクションを初めてエンハンスしてみたのですが、かなり便利でした。Iterableとか、CanBuildFromとか、よく出来ているねーと関心しまくりでした。まだJavaっぽいところありますが、Scalaらしくなるように徐々にリファクタリングしていきます。

プロジェクトサイト http://maven.tricreo.jp/site/baseunits-scala_2.9.0-1/0.0.1/
Mavenリポジトリ http://maven.tricreo.jp/release
Maven groupId jp.tricreo
Maven artifactId baseunits-scala_2.9.0-1
Maven version 0.0.1
ソース置き場 https://github.com/tricreo/baseunits-scala/
ライセンス Apache License v2.0

pom.xmlには以下のような感じで追加してください。

<dependency>
    <groupId>jp.tricreo</groupId>
    <artifactId>baseunits-scala_2.9.0-1</artifactId>
    <version>0.0.1</version>
<dependency>
<repositories>
        <repository>
            <id>tricreo-maven-release</id>
            <name>tricreo Maven Repository</name>
            <url>http://maven.tricreo.jp/release</url>
        </repository>
        <repository>
            <id>sisioh-maven-release</id>
            <name>Sisioh Maven Repository</name>
            <url>http://maven.sisioh.org/release</url>
        </repository>
        <repository>
            <id>sisioh-maven-snapshot</id>
            <name>Sisioh Maven Snapshot Repository</name>
            <url>http://maven.sisioh.org/snapshot</url>
        </repository>
</repositories>

WEB+DB PRESSでJavaの連載を担当することになりました

6/24発売 の WEB+DB PRESS vol63 より Javaの連載を担当することになりました。

WEB+DB PRESS Vol.63

WEB+DB PRESS Vol.63

  • 作者: 竹迫良範,和田卓人,じゅんいち☆かとう,太田昌吾,小野修司,ミック,嶋田裕二,個々一番,みやけん,清水亮,おにたま,中島聡,角田直行,はまちや2,上谷隆宏,青木俊介,大塚知洋,生尾剛士,大和田純,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2011/06/24
  • メディア: 大型本
  • 購入: 19人 クリック: 428回
  • この商品を含むブログ (22件) を見る

「え、ScalaじゃなくJavaなの?」と思う方もいると思いますが、Javaもしっかり勉強しておきましょうね、ということで*1。まぁ、Javaは目新しい話題が少ないという説もありますが、なるべく現場の目線で面白いネタを提供できたらと思っています。どうぞよろしくお願いします。
今回のテーマは「コレクションライブラリの再考」です。身構えずに読める記事なっているので、書店で見かけたら手にとってみていただければ幸いです。

*1:どっかでScalaのネタをねじ込むかもしれませんが、、、

日経ソフトウエア 2011年6月号でScalaの特集記事を書きました

こんばんわ。
ブログの記事が滞っているときは執筆中だったりするわけですが、今回はScalaの記事を書きました。

日経ソフトウエア 2011年 06月号 [雑誌]

日経ソフトウエア 2011年 06月号 [雑誌]


私がScalaを始めたのは2010年10月ごろですが、それ以来取り憑かれたようにScalaをやっています。関連の書籍も買い込んで自炊してiPadで読み歩いています。また、近々、Scalaで実装したライブラリを公開する予定です。何事ごとも挑戦ですね。
Scalaの特徴はオブジェクト指向言語関数型言語のハイブリッド言語というのはよく知られていますが、記述性が極めて高いというところが気に入ってます。簡潔で明瞭にコードの意図を伝えるプログラミングできるというのは本当にすごいことだと思います。
今回の特集は、Javaプログラマを対象にして、Scalaを始めるきっかけの特集記事になっています。また、簡単ですが、IntelliJ IDEAの構築方法にも触れています。レビューをしてくれた、id:yuroyoroid:xuwei ありがとう!
書店で見かけたら、手に取ってみていただければ嬉しいです。

ちなみに、入門記事でページ数が限られているのでプログラムの書き方は説明していますが、言語としてなぜそのようになるかの深い原理をあまり説明していません。そのあたりを詳しく知りたい方は以下の書籍がお勧めです。順不同です。

オブジェクト指向プログラマが次に読む本 ?Scalaで学ぶ関数脳入門

オブジェクト指向プログラマが次に読む本 ?Scalaで学ぶ関数脳入門


ボクらのScala ~ 次世代Java徹底入門

ボクらのScala ~ 次世代Java徹底入門


Scalaプログラミング入門

Scalaプログラミング入門


Scalaスケーラブルプログラミング[コンセプト&コーディング] (Programming in Scala)

Scalaスケーラブルプログラミング[コンセプト&コーディング] (Programming in Scala)


プログラミングScala

プログラミングScala

「エリック・エヴァンスのドメイン駆動設計」 を献本していただきました

嬉しいことに「エリック・エヴァンスのドメイン駆動設計」 を献本していただきました!
訳者の和智さん、関係者の方々、翔泳社さん ありがとうございます。おめでとうございます!Tシャツまでもらった!!

実は、私とid:daisuke-mは、この翻訳版の実装編のレビューに参加させていただきました。
昨年、DevLOVEのイベント「Beautiful Develpment」でDDDの話を聞いた後に、翻訳版が発売される噂を聞きつけ、和田さん(id:t-wada)に「レビューに参加したい!」と無理を言って、訳者の一人である和智さん(id:digitalsoul)を紹介してもらいました。
和智さんは快く対応くれて、レビューさせてもらうことになりました。ありがとうございました。

ドメイン駆動設計との出会いは、id:daisuke-mに勧められたのがきっかけです。洋書だし、分厚くて枕になりそうだし、英語も文体が固く、エンティティの章を読むと裁判がどうのって、読むのはハードルが高かった。。

しばらく読み進めて、id:ashigeru の思惑通りDDDが気に入った俺は、今度は上司 id:j5ik2o にこの本を買って読ませる、という暴挙に出る。この本の内容を理解して、俺と共感してくれる変態はこの人しかいないだろう、と。まぁ、思惑通り上司はこの本に魅了され、翻訳レビュー謝辞にまで名を連ねるに至った。

でも、この本の中には設計と実装の面で深い示唆を与えてくれるという。「う〜ん、う〜ん」と言いながら英語を訳しながら読みました。簡単にいうと現実世界の問題をオブジェクト指向を使って設計・実装するにはどうしたらよいか、そういう示唆を与えてくれる本です。ドメインと聞くと業務系のノウハウかと勘違いしそうですが、オブジェクト指向設計やプログラミングに関する濃い話題の本だと思ってもらえばよいかと思います。
オブジェクト指向懐疑論を唱える人もいるくらい、オブジェクト指向は、本当の意味で理解が難しいし、それをシステム化する業務の対象で扱う場合は、どのように現実世界と抽象的なオブジェクトを関連付けるべきか、特に難しいです。それらに立ち向かうために、世の中には様々な設計手法が存在しますが、DDDはそれらの設計手法を踏まえた上で、ドメインをオブジェクト指向で解決するための新しい道しるべを示してくれると思っています。難しいからって諦めていては良いものは作れませんから、こういう本を読むわけです。まぁ、今年一番のお勧めの書籍であることは言うまでもありません。

近々に、以下のイベントも控えていて、今年は日本のDDDの夜明けを見ることになりそうです。
4月9日 Beautiful Development ソフトウェアの核心にある複雑さに立ち向かう(東京都)
セッション スピーカー : Eric Evans|QCon Tokyo 2011 Conference|QCon 東京 2011 カンファレンス

ということで、オブジェクト指向に慣れてきて、これからどういう設計や実装がよいか、暗中模索している悩めるプログラマにはぜひ読んでもらいたい一冊です。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

日経ソフトウエアの特集がムックになりました

まず、
3月11日の「東北地方太平洋沖地震」で、被害にあわれた皆様に心よりお見舞い申し上げるとともに、犠牲になられた方々とご遺族の皆様に対し、心よりお悔やみを申し上げます。
私も関西出身で阪神大震災の酷さを体験している人間でもありますし、気を負わずに自分なりにできることはやっていきたいと思います。ということで、通常通り ブログの方は継続します。



お知らせです。これまでに日経ソフトウエアで執筆した特集がムックになりました。
Javaツール完全理解 (日経BPパソコンベストムック)

Javaツール完全理解 (日経BPパソコンベストムック)


タイトルはJavaツール完全理解ということで、前半はJavaの開発環境やビルドツールなどの開発に必要なツールの解説があり、後半は私の記事を含めて実装編の記事が満載です!!

私が担当したのは以下です。
【第2部】 最新Eclipseで良いJavaプログラムを書こう
【第4部】 現場で通用するソフトウエア設計を学ぼう

読みどころ

読みどころとしては以下です。
【第2部】については、Javaで良いプログラムを目指すにはどういう視点を持つべきかというテーマで、Eclipseの基本から入ってオブジェクト指向ポリモーフィズムをおさらいしながら、後半ではドメイン駆動設計(DDD)に基づいてRDBMSスキーマを作成するツールの開発を実践的を紹介しています。
この当時はまだDDDの翻訳本が出ておらず、本誌初登場でどのように解説すべきか、日経BPさんとも悩みながら書いた記事でした。そして、いよいよ4月にDDDの翻訳本が出ます。DDDは簡単にいうとオブジェクト指向を生かしたアプリケーション開発をしようという哲学です。オブジェクト指向は面倒だから使えない、で思考停止するのではなく、自分たちが実際に使ってみて評価して改善を加えていくべきだと思います。その意味では第一歩としてDDDを学ぶことは間違いではないと思います。
情報源としては、まず翻訳本です。これは間違いありません。それ以外に日本語の情報源はまだ少ないので、今回のムックは一つの情報源として活用していただければ幸いです。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

そして、【第4部】については、【第2部】とは違ってDDDは全面に出ていません。もしかしたら、こちらの方がみなさんが日常で書いているコードに近いかもしれません。ここでのテーマは現場で通用する設計とは何か。まさに幅広いテーマですが、一例として設定ファイルに基づいてJavaBeansを生成するコードジェネレータを設計/実装する特集になっています。
その中で様々なノウハウを紹介していますが、中でも「不変性」についてページを割いて説明しています。
若干、話しが逸れますが、18ヶ月でCPUのチップ性能が倍になるというムーアの法則があります。それを維持するためにマルチコア化に流れています。今や18ヶ月でCPUのコア数が2倍になる法則になっていくだろうとも言われています。この変化によって、これまで以上に並行プログラミングに気を配らなければならなくなるでしょう。このストーリについては「Java: The Good Parts」の並行処理にもっと分かりやすく書かれているのでぜひ読んでみてください。

Java: The Good Parts

Java: The Good Parts

この並行処理の課題に対応するには、「不変性」について理解しなければなりません*1。「不変性」は、並行処理以外にも、理解しやすい、テストしやすいプログラムを作る上でも効果があると言われています。この「不変性」の考え方は、最近話題の関数型言語設計思想の根底にもあります。「不変性」を今のうちに学んでおくと、関数型言語の学習がしやすくなるかもしれません。

*1:不変というのはどのような操作を行っても状態を変更することができないオブジェクトを作るための考え方です

ScalaでBrainf*ckインタープリタを実装してみた

ScalaでBrainf*ckのインタプリタを書いてみたよ - 都元ダイスケ IT-PRESS
Scalaを頑張っておるようなので、私もBrainf*ckのインタープリタをなんとなく実装してみた。

BrainfuckRuntimeと、Expression系のクラスが関数型らしくないのでなんとかしたいな...。
ソースはgithubにあげてます。ツッコミ or フォーク歓迎 https://github.com/j5ik2o/brainfuck-scala
とりあえず、nullチェックとか、例外処理は適当です。

package com.github.j5ik2o.brainfuck

object BrainfuckApplication {

  def main(args: Array[String]) =
    try {
      new BrainfuckRuntime(new BrainfuckParser).execute(args(0))
    } catch {
      case BrainfuckException(msg) => println(msg)
    }

}

以下のように実行するとHello World!が表示されるはず。

$ scala com.github.j5ik2o.brainfuck.BrainfuckApplication "++++++++++[>++++++++++<-]>++++.+++++++.--------.--."

以下、パーサーとランタイムのソース。

package com.github.j5ik2o.brainfuck

case class BrainfuckException(msg:String) extends RuntimeException

class BrainfuckRuntime(parser: BrainfuckParser, size: Int) {
  require(size > 0)

  val memory = Array.fill(size)(0)

  var pointer = 0

  var counter = 0

  val evaluator = new Evaluator()

  def this(parser: BrainfuckParser) = this (parser, 3000)

  // Brainfuckのスクリプトを実行する
  def execute(script: String) {
    val parseResult = parser.parse(script)
    if (parseResult.successful) {
      evaluateExpressions(parseResult.get)
      println
    } else {
      throw new BrainfuckException("parse error")
    }
  }

  // ASTを評価するビジター
  class Evaluator extends ExpressionVisitor {

    override def visit(expression: Expression): Unit = expression match {
      case IncrementPointerExpression() => incrementPointer
      case DecrementPointerExpression() => decrementPointer
      case IncrementMemoryAtPointerExpression() => incrementMemoryAtPointer
      case DecrementMemoryAtPointerExpression() => decrementMemoryAtPointer
      case OutputMemoryAtPointerExpression() => outputMemoryAtPointer
      case LoopExpression(expressions: List[Expression]) => loop(expressions)
    }

  }

  // 以下、ランタイムが持つAPI

  private def validateRange =
    if (counter > size) throw new BrainfuckException("limit over")

  private def readMemory = {
    validateRange
    memory(pointer)
  }

  private def writeMemory(b: Int) = {
    validateRange
    memory(pointer) = b
  }


  private def incrementPointer {
    validateRange
    pointer += 1
    counter += 1
  }

  private def decrementPointer {
    validateRange
    pointer -= 1
    counter += 1
  }

  private def incrementMemoryAtPointer {
    writeMemory(readMemory + 1)
  }

  private def decrementMemoryAtPointer {
    writeMemory(readMemory - 1)
  }

  private def outputMemoryAtPointer {
    print(readMemory.toChar)
  }

  private def loop(expressions: List[Expression]) {
    while (readMemory != 0) {
      evaluateExpressions(expressions)
    }
  }

  private def evaluateExpressions(expressions: List[Expression]) {
    expressions.foreach(_.accept(evaluator))
  }


}

Scalaのパーサコンビネータを使って実装しているので、以下のURLを読むとコードを理解しやすいと思います。
http://www.coins.tsukuba.ac.jp/~i021216/Scala-parser-combinator.pdf

package com.github.j5ik2o.brainfuck

import util.parsing.combinator._

// 式を訪問するビジター
trait ExpressionVisitor {
  def visit(e: Expression): Unit
}

// 式を表すトレイト
trait Expression {
  def accept(visitor: ExpressionVisitor): Unit = {
    visitor.visit(this)
  }
}

// 式の実装 これを使ってASTを構築する
case class IncrementPointerExpression extends Expression
case class DecrementPointerExpression extends Expression
case class IncrementMemoryAtPointerExpression extends Expression
case class DecrementMemoryAtPointerExpression extends Expression
case class OutputMemoryAtPointerExpression extends Expression
case class LoopExpression(expressions:List[Expression]) extends Expression

// Brainfuckパーサ
class BrainfuckParser extends JavaTokenParsers {

  def parse(source:String) = parseAll(brainfuck, source)

  def brainfuck: Parser[List[Expression]] = rep(instruction)

  def instruction: Parser[Expression] = loop | token

  def token: Parser[Expression] = incrementPointer ||| decrementPointer |||
    incrementMemoryAtPointer ||| decrementMemoryAtPointer ||| outputMemoryAtPointer

  def incrementPointer: Parser[Expression] = ">" ^^ {
    case ops => IncrementPointerExpression()
  }

  def decrementPointer: Parser[Expression] = "<" ^^ {
    case ops => DecrementPointerExpression()
  }

  def incrementMemoryAtPointer: Parser[Expression] = "+" ^^ {
    case ops => IncrementMemoryAtPointerExpression()
  }

  def decrementMemoryAtPointer: Parser[Expression] = "-" ^^ {
    case ops => DecrementMemoryAtPointerExpression()
  }

  def outputMemoryAtPointer: Parser[Expression] = "." ^^ {
    case ops => OutputMemoryAtPointerExpression()
  }

  def loop: Parser[Expression] = "["~>brainfuck<~"]" ^^ {
    case exprs => LoopExpression(exprs)
  }

}