kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

Scala DaysにおけるKeynoteの歴史(或は、Rod Johnsonの"Scala in 2018"について)

注:このエントリの結論は、これまでScala Daysに参加してきた経験と、一連の騒ぎにおける対応から推測したものであり、決定的な証拠があるわけではないことをお断りしておきます

さて、皆様いかがお過ごしでしょうか。近頃、海外のScala界隈では、Scala Days 2013におけるRod JohnsonのKeynoteである"Scala in 2018"が発端となって、海外のScalaコミュニティを中心に、Twitter上での炎上が起きています。

特に、

  • Typesafeのboard(顧問?)の一人であるRod Johnson(彼はEJB批判やSpring Frameworkの作者としてJavaコミュニティではよく知られた人物です)がKeynote中で、Scalaコミュニティの主要コントリビュータの一人が開発したHTTPクライアントライブラリdispatchを例としてScala界隈における記号の濫用について批判したこと
  • 批判点はdispatch-classicに対するものであって、現在のdispatchでは既に指摘の問題点は改善されていること
  • その他の問題点についても、Scalaコミュニティでは既知のものが多く、既に改善に向けた努力および実際の成果があるにも関わらず、その点について言及しなかったこと

などがあり、「個人攻撃だ」「特定ライブラリのAPIについて語るなら、最新のAPIを調査すべきであって、昔のAPIに語るのは的外れ」「Scalaはエンタープライズ言語になるべきではない?」など様々なツイートが飛び交っています。実のところ、私も彼のKeynoteは現地で聴いているのですが、それに関する感想は既にツイッターにつぶやいたので詳しくは述べません。

このエントリでは、Scala Days 2010から全て参加してきた一人として、ちょっと俯瞰してこれまでのScala DaysにおけるKeynoteについて語ってみることにします。

Scala Days 2010

  • Martin Odersky, Scala: Where we are, where we go to. *1
  • Kunle Olukotun, A Domain Specific Language Approach to Heterogeneous Parallel Programming Using Scala

Scala Days 2011

  • Martin Odersky, State of Scala
  • Doug Lea, Supporting the Many Flavors of Parallel Programming

Scala Days 2012

  • Martin Odersky, Where is Scala going?
  • Guy Steele, What Scala and Fortress can learn from each other
  • Simon Peyton-Jones, Towards Haskell in the Cloud
  • Anthony Rose, Re-inventing the Media and Television industry

Scala Days 2013

  • Martin Odersky, Scala with Style
  • Rod Johnson, Scala in 2018

以上が、これまでのScala DaysのKeynote一覧です。発表者はそうそうたる面子です 。ただ、Martin*2の発表は基本的にKeynoteと呼ぶのにふさわしいものでしたが、彼以外のKeynoteは驚く程一貫性がありません(これは、Scala Days 2010から毎年参加していた人間としての実感です)。

Kunleの発表はScalaに関連していたものの、軸は彼の研究にありました。Doug, Guy, Simonについても同様です。Dougの発表はScalaに関係ない並列プログラミング一般の話がほとんどでしたし、Guyの発表はFortressとScalaの構文的な類似と相違という観点で興味深い発表でしたが、軸は彼が開発した言語Fortressにありました。SimonにいたってはScalaについての言及はごく一部で、内容のほとんどがHaskellに関するものでした。AnthonyはZeeboxにおけるScala採用事例を語っていたという点でやや他と異なっていましたが、Scala Daysの「Keynote」の一貫性のなさという印象をより深めるだけでした。


さて、今年のRodによるKeynoteです。彼が単にこれまでと同様、Spring作者でありJavaコミュニティの著名人物という立場で「招待講演者」という事で発表したのなら大して問題にならなかったのではないかと思います。問題は、彼の現在の立場がTypesafeのboardであることです。このため、彼によるdispatch(-classic)批判をはじめとした、やや古いScalaコミュニティ批判に対して、Typesafe社が公式的にScalaコミュニティの主要なコントリビュータに対して不適当な批判をしたと捉えている人が少なからず居るようです。

ただ、これまでのScala DaysにおけるKeynoteの歴史(あるいは一貫性のなさ)を踏まえると、「Typesafeのboard」であるRod Johnsonが、不当なScalaコミュニティ批判をしたという問題のとらえかたは正しくなくて、実は単にRod個人としての見解なのではないかと思います。だとしても、Rodが現在のポジションでKeynoteで発言したことがどう捉えられるかをちゃんと把握してなかったことになるわけで、それはそれで別の問題がありそうですが。個人的にはTypesafe Blogで公式的な見解出した方が良いんじゃないかと思う次第。TypesafeでScalaやAkka、Playの開発を行っている開発者がTwitter上でのリプライに多少なりとも時間を割いているのをみていると、とても不毛だと思うので*3

*1:正確にはこの回のみ、"Opening Talk"となっていますが、位置づけは変わっていないので、Keynoteに含めることにします

*2:以下、基本的にファーストネームで呼称します

*3:近いうちに収束するとは思いますが

HerokuでOpenJDK 7を使う方法

といっても、公式ドキュメントに全部書かれてるわけですが。ポイントは、

  • java.runtime.version=7 を書いた system.properteis ファイルをプロジェクト直下に置いてコミットする
  • heroku上のPATHに /app/.jdk/bin を追加する (既存のPATHより前になるようにすることに注意)

くらいでしょうか。

モバイルSuicaとPasmo定期券と自分の脳みそ

※自分は脳の専門家でもなんでもないので、原因についてはテキトーな憶測です

今日、自分にとっては新鮮な発見があったので、せっかくなので書いてみます。

ここ一年くらいどうしてこうなるのか…と思っていた事が一つありました。それは、「9割くらいの確率で、モバイルSuica(Android携帯)とPasmoの通勤定期を取り違えて改札機にかざしてしまう」ことです。

ちょっとそれ頭ヤバイんじゃね?と言われそうなので、前提条件を補足します。自分は通勤に

  • 行き
    • (1-a) 半蔵門線O駅 - 渋谷駅 + 京王井の頭線渋谷駅 - K駅
    • (1-b) 半蔵門線O駅 - 田園都市線I駅直通
  • 帰り
    • (2-c) 京王井の頭線K駅 - 渋谷駅 + 半蔵門線渋谷駅 - O駅
    • (2-d) 田園都市線I駅 - 半蔵門線O駅

の経路のいずれかを使っています。

Pasmoの定期はO駅からI駅までです。通勤費は全額出るため直通で行った方が明らかに安いです。ただ、田園都市線I駅から職場までは上り坂なのと若干時間がかかるので、だるいときはS駅で乗り換えます。この場合、渋谷駅 - K駅間は自費になります。この通常の通勤経路では、どの組み合わせでも間違えることは「ほぼ」ありません(もちろん、全く自慢になりません)。

ただ、週一のミーティングが京王井の頭線の神泉駅付近で行われるため、

が週一の割合で発生します。9割くらいの確率で定期とモバイルSuicaを取り違えるのは、まさにこのときです。最低限の額しかチャージしていない通勤定期をK駅で間違ってかざしてしまうのです!今まで変だなあと思いつつ、元々ボーっとしててドジりやすいからだとか自分を納得させていたのですが、よく考えると妙です。それなら、似たような(2-c)や、それ以外で乗り換えが発生する(1-a)でもかなりの確率で取り違えが発生しているはずです(ただ、(2-c)は、(3-a)ほど頻発はしないものの、一定確率で取り違えが発生しているように思います)。

整理してみると、(1-a) (1-b) (2-d)のいずれも、最初に乗る電車でまず「Pasmoの通勤定期をかざす」動作を行っています。改札機で引っかかるパターンは「モバイルSuicaをかざすべきところを、Pasmoの通勤定期をかざしてしまう」パターンしかありません(逆パターンは引っかからない上に残額が減るので、すぐ気づきますが、ほとんどありません)。そして、主な通勤ルート(行き帰りの両方含む)では、「Pasmoの通勤定期をかざす -> モバイルSuicaをかざす」あるいは「Pasmoの通勤定期をかざす」のどちらかになります。

ここまで考えて、「まず最初にPasmoの通勤定期をかざす」というのが行動としてプログラミングされているために、(3-a)で高確率で間違うのではないかと考えるに至りました。

しかし、(3-a)で取り違える確率が圧倒的に高くて、(2-c)のK駅で取り違える確率がだいぶ低いのは不思議です。(2-c)の経路も週2回、多いときは3回くらいで使うので、帰りの経路で「まず最初にモバイルPasmoをかざし、次の乗り換えでPasmo通勤定期をかざす」という行動がプログラミングされているのかもしれません(3-a)は週1回で、しかも「通勤」ではないためか、うまくプログラミングされず、頭の中で「デフォルトの処理」として「まず最初にPasmoの通勤定期をかざす」という行為が反射的に行われているのかもしれません。

何はともあれ、自分の脳が改めて興味深く思えてきました。日々の生活の中でこういう事を考えるのもいいものですね。

ところで何故こんな面倒な切り替えを行っているかというと、モバイルSuicaでは乗車駅がJR沿線でないと定期券を買えず、Pasmo(Suicaが使える場所では普通使える)でオートチャージをするには、鉄道会社のクレジットカード等を別途契約する必要があるためです*1

最後に当たり前ですが、私は脳の専門家でも脳について特別に勉強をしていたわけでもないので、行動が「プログラミングされている」といった表現はあくまでイメージであって、的外れな考え方かもしれません。

ではでは。

*1:とても面倒くさいですね。せめてモバイルSuicaでJR沿線が乗車駅でなくても定期が買えるか、Pasmoでオートチャージが簡単に設定できればいいのですが…

部分適用をカリー化と呼ばないで

カリー化と部分適用の違いについては、過去のエントリ カリー化 != 部分適用 で既に述べており、決着もついているので改めて書きません。

カリー化 != 部分適用のエントリを書いたのは2009年12月です。もう3年以上前の話になります。ですが、JavaScript界隈などをみると、未だにカリー化と部分適用の違いについての誤解は残っているようです。一方で、静的型付き言語界隈でそのような誤解をほとんどみかけません。カリー化が関数の「型」を変換する操作(関数)であるために、動的型付き言語にのみ慣れ親しんでいると、両者の違いがわかりにくいのかもしれません。

ある技術用語が指すものを誤解する事自体は仕方ないことですし、責めるものではありません。また、用語が指すものは時代を経ると変わっていくものだという主張もあるでしょう。ただ、カリー化という用語の定義は明確に定義されており、数十年もの歴史があります。ここ10年くらいのいわゆるLightweight Languageの台頭によって、本来の意味で「カリー化」という用語が使いにくくなるのは嬉しくありません。

というわけで、今回のエントリのタイトルにつながります。好き好んで間違った用語の使い方をする人は居ないと思いますが、

最初に、カリー化に関する誤解をした状態で、カリー化に関する記事を書く ->
別の人が最初のエントリをみて、誤解した理解でカリー化に関する記事を書く -> 
さらにそのエントリを読んだ人が…

のような状態になるのは珍しいことではありません。

一方、カリー化(を行う関数)と部分適用(を行う関数)では静的な型が異なるため、静的型付き言語ではこのような勘違いは起きづらいです。カリー化という用語の正しい使い方について調べるときは、動的型付き言語のサンプルコードを用いた解説ではなく、できる限り静的型付き言語(Haskell, OCaml, Standard ML)を用いた解説を読む事をお勧めします。

もちろん、動的型付き言語のサンプルコードで正しい「カリー化」の解説をしている記事も多数あるのですが、間違った記事や、ある言語の標準ライブラリが間違った「カリー化」関数を提供していることすらあるので(!)、カリー化について調べているときにどちらが正しいか判断するのはやや難しいです。

Scala Conference in Japan 2013 〜座長の軌跡〜

時間が経つのは早いもので、Scala Conference in Japan(略称ScalaConfJP) 2013 (3/2(土), 3/3(日)) が開催されてからもう2週間です。200名分のチケットが1週間足らずで売り切れ、その後もキャンセル待ちが増え続けた段階である程度の盛り上がりは予想していましたが、当日は予想以上に盛況で、朝一のJonasさんの講演にも100名以上が参加していました (こういうイベントだと、朝早い時間は来る人が少ないのがよくあることです) 。

Twitter上でのつぶやきも盛んに行われ、#scalaconfjp ハッシュタグがTwitterのトレンドを独占し続けた程でした。当日は、普段Twitterを通してしかやり取りを行っていない、Scalaを実用に用いている方々が議論をしている姿が見られたり、Typesafeからのゲストスピーカー4名と国内の技術者が交流している姿が見られたりと、今回のカンファレンスの目的を考えると概ね成功だったのではないかと思います。

既に参加者による感想ブログ/ツイートが多数書かれています。数が多いので、リンクは省きますが、概ね印象は悪くなかったようでほっとしています。また、スタッフの立場からのエントリもいくつか書かれています:

今回、運営スタッフが軒並みこういった大規模イベントの運営に関して経験がなかったため、様々な試行錯誤がありました。今年でノウハウが蓄積できたので、来年開催するときはスムーズに行くのではないかと思います(既に来年があることを前提にしていますが、来年もできればやりたいところです)。

さて、ここまでが前置きです。このイベントの言い出しっぺとして、座長として、一体どういう経緯でこのイベントを企画したのか、どういう時期にどういう考えがあったのか、座長という立場から時系列で書いてみようと思います。長いのでテキトーに読み飛ばしてもらってかまいません。

おまえ何やってたの?

その前に自分が何をやっていたかを簡単にまとめておきます。立場としては一応座長(?)だったのですが、やっていた作業は、以下のような感じです。時期に応じて必要な作業を色々やっていたように思います。

  • Typesafeのゲストとのメールのやりとり
  • 東工大側窓口とのメールのやりとり
  • 会場下見
  • 書類への押印・郵送作業
  • ちょっとヤバそうな人への対応 (謎)
  • ページ更新のアナウンス

あとは、「座長としてここは譲れない」部分に関する決定でしょうか。たとえば、英語話者の発表に関して、同時通訳を当日雇うのはどうかという案が出たことがありました。しかし、これは

  • 発表の醍醐味である動的な部分が損なわれる
  • 雇った同時通訳が、技術的な用語を含めてちゃんと通訳してくれるか不安がある
  • 発表者の負担が増える懸念がある

といった事を考慮して却下しました。

また、キャンセル待ちが大幅に出た段階で、チケットの追加販売の案が出たことがありました。会場のキャパシティには若干余裕はありましたし、不可能ではありませんでしたが、初回開催であることと、弁当の発注量の変更を含め、関係スタッフにかかる負荷がどのくらいになるか予測しづらかったなどの理由もあり、チケットの追加販売は今回は見送ることにしました(チケット買えなくて参加できなかった方、申し訳ありません)。これについては、来年はチケットの販売スケジュールにもっと余裕をもたせて、追加販売をやりやすい体制にしたいところです。

事の発端

今回のカンファレンスの発端となったのは、次のツイートでした。

Scala Days 2012に参加していたので、次の開催地がアジアになるかも、という情報は当日耳にしていましたが、日本誘致という事は考えてもみませんでした。その後、Scala Days 2013を日本に誘致するためには?という議論を経て、Scala Days 2013の日本誘致は難しそうだと考えるに至りました。しかし、その中で、

というツイートをみて、誘致は無理でも、日本でのScala Conferenceならいけるのでは?と考え始めました。この時のJoshのツイートがなければ、今回のカンファレンスを企画しようと本気で考えることは無かったかもしれません。Typesafeからゲストを数名呼ぶというのもこの頃から少しずつ考え始めていました。

構想段階 (2012年6月)

さて、日本でのScala Conferenceをやろうと考え始めたはいいものの、私にはそのようなイベントの運営経験はなく、右も左もわからない状態でした。とりあえず、そういうことは先人に聞くのが一番だろうということで、

  • サイボウズラボの竹迫さんにYAPC::Asia 2008の時の事を伺ったり
  • 会場の候補として考えていた東工大の首藤先生に話を伺う

などして、企画として始動するにはどうすればいいか、少しずつ自分の中で構想を固めていきました。

企画始動前の交渉 (2012年6月)

さて、このちょうどいい時期に、Typesafeの Jamie Allen (@jamie_allen) さんから別件で私宛にメールが来たのでした。今にして思えばこれはとてつもない幸運でした。

というのも、私はScala Days 2010, 2011, 2012と参加して、Typesafe内に数名知人はいたものの、EPFL時代とメンバの役割が大きく変わっている可能性があったため、誰とコンタクトを取るべきか悩んでいたからです。

この別件については省略しますが、返信のついでに彼に

  • 2013年3月に、詳しいプランは決まっていないがScala Conferenceを日本でやることを企画している
  • Typesafeから招待講演者を呼びたい

旨を伝えたところ、比較的好感触な返事が返ってきました。その後数回のやり取りを経て、ちゃんとした企画と渡航費の負担さえできればTypesafeから招待講演者を呼ぶのは十分現実的な範囲になってきたと感じていました(もちろん、その渡航費の負担は決して楽ではなかったのですが)。

企画始動 (2012年7月21日(土))

かなりおおざっぱではあるものの企画の骨子が出来たので、企画の是非および、そのために協力してくれる方がどれくらいいるかを確認するために、Scala Conference in Japan(仮) キックオフと題したイベントをpartake.inに作成し参加者を募集しました。参加者が少ない場合や、企画の趣旨に無理があるという意見が多いようであれば企画は放棄するつもりでした。しかし、幸運にも27名もの方に集まっていただいて、企画にも賛同していただいたため、この日からScala Conference in Japan 2013の企画が正式に始動することになりました。また、月1ペースでオフラインミーティングを行うことも決定しました。

ここから、私はJamieさんは継続的に連絡を取り合い、企画の進捗状況を定期的に報告するようになりました。

停滞期 (2012年8月)

企画が始動したはいいものの、Webページも存在せず、しばらくは全体的に活動は停滞していました。話し合いは主にスタッフ用のclosedなMLで行っていました。この時点での優先事項は会場を確定させることだったのですが、下見日程をスタッフと東工大側の窓口の方でなかなか合わせられなかったこともあり、話し合いのペースも比較的ゆっくりしていました。

会場下見・確定 (2012年8月下旬)

8月下旬にようやく日程を合わせることができ、会場候補である東工大 大岡山キャンパスに初めて下見に行くことになりました。このとき、東工大の窓口の方が大変丁寧に大学構内を案内してくださったのが印象に残っています。また別の会場を探してメールのやり取りをして…となるとかなり時間がかかりそうだったので、大岡山キャンパス内に会場を決めることにして、下見と同時に、会場に良さそうなホール・部屋をこの時期に仮予約しておきました。

Webページ開設 (2012年9月)

こうして施設の仮予約ができたことで、Scala Conferenceのページを公開できるようになりました。この時点では最小限の情報しか載せていませんでしたが、ようやく話が動き出したという感じがしました。8月当時、会場が決まらなかったら…ということで、内心焦っていたことを覚えています。

本格始動 in ML (2012年9月〜11月)

仮予約とはいえ会場が確定したため、この時期からようやく他のスタッフも動けるようになってきました。この期間、主な話し合いはスタッフMLで行われていたため、開催時期が近づいてくるにつれメールの流量が凄まじい量になり、末期は管理できる限界を超えかけていました。途中、"会場", "All" などの「タグ」をSubjectに付けることで個々人が把握する必要があるメールを区別する試みが行われましたが、膨大なメールの中に埋もれてしまい、必要な情報を検索するのがかなり手間でした。

Typesafeからのゲストについては、私が中心になって交渉を進めていました。比較的早い内に、4名のゲストは固まっていたものの、渡航費を全額支払える保証がこの時点ではなかったこともあり、しばらくは「暫定的」な状態でした。スポンサー募集については、ページで公募する前に色々模索していたのですが、最初のスポンサー企業様を獲得するまでは、スポンサーチムを含め、苦労が大きかったように思います。また、この時期、スポンサーチームの方が本業の方が多忙になってしまったため、事務局チームにスポンサーとの交渉をお任せすることになりました。

この辺りで、

  • 一人のスタッフへ負荷が罹りすぎないようにするにはどうすればいいか(チーム内での負荷分散)
  • ML + github Wikiより良い情報共有/議論の場

について考え始めていました。ただ、スポンサー対応にしろ、他の作業にしろ、チームで分担するより結局は個人でやった方が効率が良いため、今思えば「チーム内での負荷分散」という考え方に私が拘ったのは良くなかったと思っています。この頃は、どうすればいいのか日々考えて心労がたまっていたように思います(笑)。

また、ML + github Wikiでの議論はもはや管理できる限界を超えてしまっており、このままではまずい、とも感じていました。

co-meeting の導入 (2012年12月)

MLでのやり取りに(おそらく)皆限界を感じていたなか、12月の定例ミーティングで、Sawayamaさんがco-meetingを使ってはどうかという提案をしてくれました。私も別件でco-meetingを使ったことがあり、現状のMLベースでのやりとりの問題を解決するにはとても良さそうだと考えたため、その日の内にco-meetingを導入することが決まりました。早速、中核となっていたスタッフは全員co-meetingに入り、凄い勢いでスタッフ内でのコミュニケーションがco-meetingに置き換えられていきました。

Webページリニューアル(2012年12月〜2013年01月)

初期公開時のWebページはデザインを含め、色々問題があったのですが、@seratchさんが、複数ページ対応なども兼ねて、内部構成を Jekyll ベースに整理してくれました。このおかげで、後のページ更新作業が格段に楽になったように思います。また、細かい見た目の調整についても、かなりの部分を@seratchさんに手がけていただきました。ページ更新の頻度がその後どんどん増えていったことを考えると、この時期にページ構成を再編したのは大正解でした。

個人ベースの作業分担 (2013年1月〜)

co-meetingの導入によって、チーム内での情報共有・チーム間での情報交換は格段にやりやすくなりましたが、依然として少数のメンバに作業負荷がかかるという状態が続いていました。特に、私が

  • 座長としての作業 (請求書への押印・郵送)
  • Typesafeのゲストとのメールのやりとり
  • 会場チームリーダーとしての作業 (この時期までは主に東工大側とのメールのやり取り)
  • タイムテーブル・プログラム作成

を兼ねていたため、私がボトルネックになりかけていました。幸いにして、

引き継いでもらったため(作業を奪っていったともいう(笑))、私がオーバーフローすることなく、座長としての役割に専念できるようになっていきました。その他発生したタスクについては、個人がそれぞれのタスクに責任を持つ、個人ベースの作業分担になっていきました。これは私が割り振ったのではなく、スタッフの各々が自分で作業を受け持ってくれたようなもので、本当に助かりました。

カンファレンス参加者募集開始 (2013年2月〜)

決済にDoorkeeperを利用するというのは事前に決まっていたため、これに関しては比較的スムーズに行ったように思います(Sawayamaさんが裏で苦労していたかもしれませんが…)。ただ、1月の定例ミーティングの時点では、参加費3000円のScalaというメジャーとは言えない言語のカンファレンスで、200名枠が埋まるかどうかについてはスタッフの多くが不安に考えていたようです。

私は過去に類似イベントに多数参加した経験から、この手のイベントには、Scalaを仕事で使っている人だけでなく、Scalaを勉強し始めた人や、Scalaにはあまり興味がない「一見さん」もそれなりに参加すると考えていたので、最終的には200名枠は十分埋まるだろうと考えていました。結果としては、私の予想も遥かに上回って、1週間足らずでチケットが完売してしまったわけですが。

最終作業 (2013年2月中旬〜)

この時期は本当に大詰めといった感じで、定例ミーティングでも

  • 前日・当日の作業リストアップ
  • 緊急時の対応
  • ノベルティの補完場所
  • 翻訳チームとの連携(スライド同時通訳)
  • 招待枠の最終確認

といった作業が中心でした。この時期には、本当に座長として必要な作業以外は引き取ってもらっていたので、私自身の作業量は逆に減っていました。この時期は、本当に開催されるんだ、という実感でスタッフ皆がみなぎっていたように感じました。

前日作業 (2013年3月1日)

この日は、前日動けるメンバーだけが集まって、

  • 看板・机の借り受け作業
  • バッグにスポンサー企業様からのノベルティを入れる作業

といったことを行っていました。実は、とある別のイベントの実行委員から聞いたところによると、前日はかなりぎりぎりだったらしいのですが、幸いにして、前日準備は比較的早めに終わりました。

当日 (2013年3月2日)

当日の座長の仕事は飾りになることです。というわけで、お世話になった方々への挨拶周りが私の当日の作業でした。「座長」などという立場で、これだけの規模のイベントでオープニングスピーチなどやったことがないので緊張しまくりでしたが、参加者の皆さんにはどのように見えたでしょうか。後で動画をみると自分のアレさに卒倒してしまいそうで少し怖いです(笑)。ちなみに、この日は、スーツコス+ScalaConfJP スタッフパーカーという謎の格好をしていました。一応、会場を回って何か起きていないか確認したりもしていましたが、スタッフの方々のおかげで、こころおきなく、座長の責務(?)を全うすることができました。

ちなみに、懇親会で胴上げをされたのは想定外でちょっと怖かったです(笑)が、同時に達成感もあり、非常に嬉しかったです。

この日のスタッフの方々の働きは素晴らしかったです。参加者の方々にとって至らないところもあったかもしれませんが、それについてはアンケートに記載されている分も含めて、きちんと来年にフィードバックしたいと思います。

ハッカソン大会 (2013年3月3日)

ハッカソン大会は、無料イベントで申し込みも当日まで誰でもOKという感じだったので、私も座長というより一参加者として楽しむことができました。合間合間に好き勝手に参加者がtalkしたり、もくもくとコーディングしたりと、フリーダムな雰囲気が出ていたのではないかと思います。ただ、この前日でかなり気が抜けていたこともあり、ちょっとだらしなかったかもしれません。Typesafeからのゲストの内、Jonasさんを除く3名にも来てもらうことができ、活発な議論が行われていました。最後には、プチプログラミングコンテストが行われ、Typesafeのゲストによる審査の結果、優勝した@cocoa_rutoさんには、Joshuaさん直筆サイン入りの『Scala in Depth』が贈呈されました。

この日は、ハッカソン大会にも参加した一部スタッフを交えて懇親会があったのですが、疲労コンパイルだったので、最初1時間くらいだけ出て帰ることにしました。本当の事を言うと、最後まで居たかったですが。

まとめ

と、このように時期によって色々問題を抱えつつも、カンファレンスは盛況の内に終わることができました(まだ後処理は残っていますが)。これもひとえに、中核になって動いてくれたスタッフの方々、Typesafeからのゲストを招待するに当たっての原資となったスポンサー企業様、発表者の皆様、参加者の皆様のおかげです。あらためてお礼申し上げます。

sbt + sbt-idea + Intellij Scala Pluginを使ったScala開発 (in Mac OS X)

注意:この記事の内容は、2013年7月2日現在、やや古くなっています。現在は「Use external build」のチェックはONにしたままで、「Use project FSC」をチェックしない方が安定して動作します。これは、最近のアップデート(ここ1〜2ヶ月くらいの話ですが)「Use external build」を使ったときに、IDEAが内部でzincというsbtベースのスタンドアロンコンパイラを内部で使うようになった事に起因しています。コンパイラの設定以外は現在でもそのまま通用しますが、このエントリを読んでIntelliJ IDEA + ScalaプラグインによるScala開発を行おうとしている人は注意してください。

これは、Scala入門をIntelliJ IDEAでやろうとしている人向けのエントリではありません。このエントリでは、IntelliJ IDEAのScalaプラグインのインストールやその他プラグインのインストールについては触れていません。また、設定上の注意事項(特にPlay 2と併用する場合)などは飛ばしているので、ご注意ください。

少しは役に立つ記事を書いてみようかと思い、ちょっと普段Scala + sbt + IntelliJ IDEA + Scala Pluginでどいういう風に開発してるのか書いてみることにしました。面倒なので、sbtの設定ファイルについての解説は飛ばします。テンプレートとなるプロジェクトを作成したのでこれをforkするなりcloneするなりして弄ってみてください。

さて、とりあえず上記のscala-idea-templateプロジェクトをcloneしてきて、sbtがインストールされているとします。コンソールからsbtコマンドをたたくと次のように表示されます。

 ~/git/scala-idea-template (git master) 
[mizushima]$ sbt
[info] Loading global plugins from /Users/mizushima/.sbt/plugins
[info] Loading project definition from /Users/mizushima/git/scala-idea-template/project
[info] Updating {file:/Users/mizushima/git/scala-idea-template/project/}default-2c9cb0...
[info] Resolving org.scala-sbt#precompiled-2_10_0-m7;0.12.1 ...
[info] Done updating.
[info] Set current project to sbt-idea-template (in build file:/Users/mizushima/git/scala-idea-template/)
> 

さて、ここで

[info] Loading global plugins from /Users/mizushima/.sbt/plugins

というメッセージはとりあえず無視してください(こちらの開発環境での設定によるものです)。ここで、既にsbtのプラグイン設定ファイル(project/plugins.sbt)にIntelliJ IDEA Scalaプラグイン用のプロジェクト設定ファイルを生成するためのsbt-ideaプラグインが入っているので、これを実行します。

> gen-idea
[info] Trying to create an Idea module sbt-idea-template
[info] Updating {file:/Users/mizushima/git/scala-idea-template/}default-986503...
[info] Resolving org.specs2#specs2-scalaz-core_2.9.2;6.0.1 ...
[info] downloading http://repo1.maven.org/maven2/org/specs2/specs2_2.9.2/1.12.2/specs2_2.9.2-1.12.2.jar ...
[info] 	[SUCCESSFUL ] org.specs2#specs2_2.9.2;1.12.2!specs2_2.9.2.jar (6901ms)
[info] Done updating.
[info] Resolving org.specs2#specs2-scalaz-core_2.9.2;6.0.1 ...
[info] downloading http://repo1.maven.org/maven2/org/specs2/specs2_2.9.2/1.12.2/specs2_2.9.2-1.12.2-sources.jar ...
[info] 	[SUCCESSFUL ] org.specs2#specs2_2.9.2;1.12.2!specs2_2.9.2.jar(src) (1718ms)
[info] downloading http://repo1.maven.org/maven2/org/specs2/specs2_2.9.2/1.12.2/specs2_2.9.2-1.12.2-javadoc.jar ...
[info] 	[SUCCESSFUL ] org.specs2#specs2_2.9.2;1.12.2!specs2_2.9.2.jar(doc) (3803ms)
[info] Excluding folder target
[info] Created /Users/mizushima/git/scala-idea-template/.idea/IdeaProject.iml
[info] Created /Users/mizushima/git/scala-idea-template/.idea
[info] Excluding folder /Users/mizushima/git/scala-idea-template/target
[info] Created /Users/mizushima/git/scala-idea-template/.idea_modules/sbt-idea-template.iml
[info] Created /Users/mizushima/git/scala-idea-template/.idea_modules/sbt-idea-template-build.iml
> 

こんな感じのメッセージが表示されるはずです。ちなみに、build.sbtで依存関係に指定したscalaj-httpがダウンロードされていませんが、これは既に他のプロジェクトで同じライブラリの同バージョンのものがダウンロードされてキャッシュされているからです。

さて、ここまででIntelliJ IDEAの設定ファイルは生成できたので、IntelliJ IDEAを起動します。

http://gyazo.com/1dab70c5fc4277b8a7c9a4f1e88707b5.png

こんな感じの画面が表示されるので、「Open Project」を選択して、scala-idea-templateのあるディレクトリを指定して、「Choose」を押します(以下)。

http://gyazo.com/60b679810a2a2232cea90d1b9684b5bf.png

ちょっと待つと、以下のような画面が表示されます。

http://gyazo.com/429d5ef17c9f2e3b59714c8b90f3db83.png

これで準備完了…の前に、もう一ステップ必要です。src/main/scalaがScalaソースのルートディレクトリに設定されているので、そのためのディレクトリを作ります。

http://gyazo.com/0ea529a245b5393121566fd624fb711d.png

これで今度こそ準備完了です。とりあえず、パッケージを作ってみましょう。面倒なので、toolsパッケージにします。

http://gyazo.com/5d854395703e7cc329a4df751259e556.png

toolsパッケージの上にHello objectを作成します。

http://gyazo.com/e8bc878f92e511ca6dce4e0e059eb95f.png

あとは適当にプログラムを書いていきましょう。IntelliJ IDEA の Scala プラグインは import補完も含めてちゃんとサポートしています。例えば、java.util.Calendarが使いたくなったとします。以下のようにCalendarまで入力して、Alt + Enter。

http://gyazo.com/cf5fd84124bc35b66184d5a985399717.png

すると、以下のような感じで、java.util.Calendarを自動的にimportしてくれます。

http://gyazo.com/85c22014f9923abf6d45f594b47d05b1.png

val calendarの型が知りたい場合、calendarにカーソルを合わせたときに出てくる電球マークの「Add type annotation to value definition」を選択すると、以下のようにcalendarの型としてCalendarが明示的に付きます。型推論の結果がよくわからないときに便利です。

http://gyazo.com/5fffcf1ff30fd0e912e0d097e9b98cbf.png

さて、プロジェクトをビルド…する前にちょっと注意点をば。現在の最新版のIntelliJ IDEA + Scala Pluginでは、以下の「Use external build」のチェックボックスをまず外す必要があります。

http://gyazo.com/aea80f6643e97e9d123038981531c6fa.png

プロジェクトの設定画面が次のようになっていることを確認し、「Use project FSC」にチェックを入れます。さて、ビルドしてみましょう。ビルドは、「Build」メニューの「Build Project」を使います(私は、Command + Bでビルドできるようにしてあります)。

http://gyazo.com/6e4b55d7cd4f20d79e7a22656a318900.png

Scalaはコンパイルが遅い言語の一つですが、IntelliJ IDEA + Scala Pluginを使った場合、差分ビルドではsbtでビルドするよりも高速にビルドできます(厳密に測定していませんが、差分ビルドでは明らかに早い)。

IntelliJ IDEA (+Scala Plugin)は、他のIDEに慣れていると若干操作性に癖を感じるかもしれませんが、

  • リファクタリングサポート(特にRename)
  • 自動インポート
  • メソッド/変数の(定義元/呼び出し元)へのジャンプ
  • sbt-ideaによって、依存ライブラリのソースコードがダウンロードされる

など、現代的なIDEに必要な機能はあり、現時点でのScala開発環境としては最も良く出来たものの一つだと思います。もちろん、Eclipse JDTや、IntelliJ IDEA (Java)における補完機能には及ばない部分もありますが、リファクタリングサポートや自動インポート、依存ライブラリのソースへのジャンプなどの機能があるだけで結構効率が違うと感じます。

さて、テストの話も書いてみようかと思ったのですが、そろそろ眠くなって来たので、今日はこれまで。

irof式が実装できたよ。そう、Scalaならね! (Re: irof文が実装できたよ。そう、Scalaならね!)

See: irof文が実装できたよ。そう、Scalaならね!

返り値が思い通りにならないことに困ってらっしゃったようなので(?)、実装してみました。

object Main {
  case class irof[A](val condition: Boolean)(blockA: => A) {
    val thunk: () => A = () => blockA
    def elof[B <: A](blockB: => B): A = if(condition) thunk() else blockB
  }

  implicit def irofToA[A](i: irof[A]): Any = if(i.condition) i.thunk()

  def main(args: Array[String]) {
    val x: String = irof(args.length > 0) {
      "foo"
    } elof {
      "bar"
    }
    println(x)
  }
}

これの問題点は、elofの型制約のせいで、

val x: Any = irof(args.length > 0) {
  "foo"
} elof {
  1
}
 println(x)

などが通らない事ですが、たぶん解決するのが難しい…(頑張れば解決できるかも)