Hatena::ブログ(Diary)

駄文生産所 このページをアンテナに追加 RSSフィード

2011-06-14

「ここがヘンだよScala言語」について

ここがヘンだよScala言語」はテレビ番組「そこがヘンだよ日本人」を意識して、初学者や他文化の者がScalaを学ぶ上でハードルとなるであろう部分をいくつか挙げたものだ。ゾマホンケビンのように、その文化にあまり理解がない、もしくは多少の演出のある状態で、Scalaを見たときにはこう見える、ということだ。だから、「”本気でそうあるべきだ”と考えていたらタダの馬鹿だ」という内容も含んでいる。

これを通して伝えたかったことは、Scalaには、他文化から見れば不自然なもの、コンテキストによって意味解釈が異なるもの、背後の思想やJVMとの連携のための都合など、使いこなす上で乗り越えなければならないハードルが、それなりに多く含まれているということだ。そしてそれが、私の感覚で言う「難しさ」「複雑さ」だということだ。ハマリどころを潰す材料になればよいと思う。

2011-06-11

ここがヘンだよScala言語

Scalaを触ったり言語仕様を眺めた上で、ストレスを感じたものをいくつか挙げる。おそらくコミュニティでの議論は既に終了しているであろうし、無意味な作業に感じられて仕方がないが、某所でまとめると言ってしまったので、我慢して進める。

突撃されると面倒なので一応述べておくが、別にScalaダメだとか、Scalaが使えないとか言いたいわけではない。この程度の訓練は必要なのだ、ということだ。


追記

びっくりするほどのバカだと思われている節があるが、ScalaJavaの思想を知った上で、あえて記述している部分も多分にある。一応。

捉え違いしている部分や、Scala的な考え方が知りたい方は、コメントをご覧になるのが良いでしょう。


if式の返り値

val v1 = if (1 < 2) {"a"} 
println(v1)

val v2 = if (1 < 2) {"a"} else {"b"}
println(v2)

v1はUnit、v2は"a"。else節が無い場合、「最後に評価された式を、返り値とする」というルールから外れる。

2.8.1、2.9.0等、現行の版では、v1、v2ともに"a"が返る。ルール通りの動きで問題はない。


除外インポート

import scala.collection.mutable.{_, Map => _, Set => _}

サンプルはMapSet以外の全クラスインポート。ここで、"_"にワイルドカードとしての役割と、消去の役割をもたせている。こんなのよく通したな。


typeと別名インポート

typeがあるなら別名インポートはいらないのでは?


forのネスト

for(i <- 0 to 10; j <- 0 to 10; k <- 0 to 10) {
  print(i + ":" + j + ":"+ k)
}

ループが一つなのか、三つなのか、ぱっと見で分からない。必要だったのか?


for内包表記中のifとif式

for(n <- List(1,2,3,4,5) if n % 2 == 1) yield print(n + " ") // OK

val n = 3
val = if n % 2 == 1 // コンパイルエラー
}

内包表記中のifと、if式は違う。


forとforEach

クロージャとforEachメソッドをサポートするなら、for式は必要ないのでは?

yieldは好みじゃない。特例だから


タプルのインデックス

コレクションは0オリジン、タプルは1オリジン


overrideの有無

どちらかにして欲しい。


インスタンス生成の責務

わざわざクラスオブジェクトとしての振る舞いをobjectに括りだしたのだからインスタンス生成の責務はobjectに渡せば良かったのでは?


インスタンス生成時のnewの有無

class, caseクラスobject場合によってnewを付けたり、外したり。


コンストラクタ

基本コンストラクタと、thisを用いて定義するコンストラクタ。分ける必要があったのか?


プレースホルダ

"ACBED".sortWith(_ > _) 

複数の引数を取る場合、異なるオブジェクトに同じ名前を付けることになり、順番に依存する。


Mutatorの定義

class Foo {
  var bar: Int = _
  
  def bar_=(value: Int) {
    this.doSomething
    this.bar = value
  }
}

特別なメソッドの書き方。


似ているキーワード

None、Nothing、Null、null、Nil。一つ一つ意味と用法を覚える。


mutableなSet,Mapと、immutableなSet,Map

性質の異なるものを、わざわざ同名にする必要はあったのか?


コロンで右結合

通常の左結合の演算子が混じると面倒。


パラメータ境界

foo[A <: T]、bar[A >: T]、boo[A <% T]。このときコロンで右結合は関係あるんだろうか?

UML的なsuper-subの矢印の方向とも逆なので、Scala用の解釈として覚える。

パーサーやらの都合は知らないが、foo[ A.isSubtypeOf[T] ]、bar[ A.isSupertypeOf[T] ]、とかのほうが読み下すには良いと思う。


暗黙の型変換

implicitにやるよりは、必要になった時点でtoString()のようなフレームワークで指定したconverterメソッドを呼び出す方が好み。言語機能に同じような役割の新要素を追加するよりマシ。


notメソッド

unless文をサポートしないなら、Booleanにnotメソッドくらいは装備しておいて欲しい。


コンパニオンの参照

class A {
  def companion = A  // 名前を直に指定するのはカッコ悪い
  def foo = this.companion.defaultValue
}

object A {
  val defaultValue = 10
}

コンパニオンを取得するメソッドくらい装備しておいて欲しい。


unsignedがない

32ビットunsignedなら、4ByteをByteでとってLongに変換。低いレイヤネットワーク関連で面倒な思いをしている人も多いことだろう。


おわり

キリがなく、面倒なのでやめる。触れたのは氷山の一角だ。省略可能な部分、型周辺、アノテーション周辺、"/:"や":\"などの演算子周りには、おそらく気持ちの悪い部分がゴロゴロ転がっている。

一貫性から外れ、特例を知らなければならない件が散見される。そもそも覚えるべきことが多い。現状、Scalaはそこそこ覚悟のいる環境だと思う。

「訓練されたScalaプログラマ」には複雑さは見えないんじゃないか』というまつもと氏の言には大いに同意する。まぁ慣れれば助数詞のように気にならなくなるのだろう。


2009-05-22

Scalaユーザ会

ということで、新宿、豆蔵へ。

Scalaの概要とか、Scalaで作っているアプリ自慢とか、重箱の隅な文法紹介とか、数独のSolverを絡めたScala紹介とか、Lift紹介とか、Liftで作った業務アプリの紹介とか、その辺りの話を聴く。

秋には翻訳本が出版予定であるとのこと。Squeak界隈ではbobと双璧をなす存在であるlexも共著者。

Programming in Scala: A Comprehensive Step-by-step Guide

Programming in Scala: A Comprehensive Step-by-step Guide

ScalaJavaよりずっといいので、EclipseのPluginがまともになったら流行ると思う。今RubyやPythonでWebアプリを作っているような層に。

StrutsとかPHPで泥臭くやっている層には利用されないだろうなぁ。

妙に疲れてたんで、二次会には出ずに退散。