Scalaの特徴の1つは引数が1つのメソッドを演算子のように呼び出せることです(Rubyも同じですね)。背景には、基本型を廃して「全てオブジェクト」とする、言語の文法から演算子を廃する、という設計哲学があるようです。
しかし演算子の優先順位まで消滅して1 + 2 * 3 = 9になってしまうと(全て左結合させると ((1 + 2) * 3) になる)非常に混乱しますので、コンパイラが特殊なメソッド名だけ結合の優先度を変更します。
class MyInt(v: Int) {
val i = v
def +(a: MyInt): MyInt = {
new MyInt(i + a.i)
}
def *(a: MyInt): MyInt = {
new MyInt(i * a.i)
}
def plus(a: MyInt): MyInt = {
new MyInt(i + a.i)
}
def mult(a: MyInt): MyInt = {
new MyInt(i * a.i)
}
}
val a = new MyInt(1)
val b = new MyInt(2)
val c = new MyInt(3)
val r1 = a + b * c
val r2 = a plus b mult c
println("r1:" + r1.i)
println("r2:" + r2.i)
r1:7 r2:9
演算子もメソッドの一種ではありますが、上記のように旧来の演算子と同名のメソッドはやはり、優先度において特別です。単純に別名のメソッドで置き換えると、結合順序が狂います。
こうまでして文法上から演算子を廃したのはなぜだろう?誰かにメリットがあるはずなのだけど、何が嬉しいのかわからん…。
優先度と言えばScalaは優先度付けのルールがJavaと違います。例えば、Javaはシフト演算が比較より優先ですが、Scalaは優先度が同じです。
(JavaならOK、ScalaではNG) scala> 1 < 1 << 2 <console>:8: error: value << is not a member of Boolean 1 < 1 << 2 ^ (本来やりたいこと) scala> 1 < (1 << 2) res1: Boolean = true
上記の例のように、Scalaで「(1) < (1 << 2)」のつもりで「1 < 1 << 2」と書くと、左から結合されて「(1 < 1) << 2」になって型エラー(※)が起き、ちょっと不思議な気持ちになります。
あえてJavaと違う優先度にしたのはなぜだ…。
(※)1 < 1はBooleanを返し、Booleanクラスは左シフトメソッド << を定義していないため、エラーになる。
ScalaとJavaでシフト演算子の優先度が違うのは、決して嫌がらせではなくて「Scalaの優先度は、メソッド名の先頭の1文字で決まる」ルールから来ているようです。
素人目線だと2文字見れば良かったんじゃ…?と思いますが、そうすると何か大変なことがあったのでしょう。たぶん。
それはさておき、Scalaで中間記法を使ったときの優先度は、低い順から、
(all letters) 注: アルファベットとか
|
^
&
< >
= !
:
+ -
* / %
(all other special characters) 注: ~ とか ? とか
注: Scala言語仕様Version 2.8の6.12.3 Infix Operationsより
となっています。シフト(<<)やビット演算(& |)は、比較演算(== !=)よりも「優先度が低い」はずです。
scala> 1 & 2 == 5 <console>:8: error: overloaded method value & with alternatives: (x: Long)Long <and> (x: Int)Int <and> (x: Char)Int <and> (x: Short)Int <and> (x: Byte)Int cannot be applied to (Boolean) 1 & 2 == 5 ^ (& が優先なら) scala> (1 & 2) == 5 res40: Boolean = false (== が優先なら、こっちが期待値) scala> 1 & (2 == 5) <console>:8: error: overloaded method value & with alternatives: (x: Long)Long <and> (x: Int)Int <and> (x: Char)Int <and> (x: Short)Int <and> (x: Byte)Int cannot be applied to (Boolean) 1 & (2 == 5) ^
ビット演算の方が優先度が低いので、上記の例のように「1 & (2 == false)」と解釈されて、型エラーになります。
scala> 1 < 2 == false res41: Boolean = false (< が優先なら) scala> (1 < 2) == false res42: Boolean = false (== が優先なら、こっちが期待値) scala> 1 < (2 == false) <console>:8: error: overloaded method value < with alternatives: (x: Double)Boolean <and> (x: Float)Boolean <and> (x: Long)Boolean <and> (x: Int)Boolean <and> (x: Char)Boolean <and> (x: Short)Boolean <and> (x: Byte)Boolean cannot be applied to (Boolean) 1 < (2 == false) ^
比較演算の方が優先度が低いので、「1 < (2 == false)」と解釈され、型エラーになるかと思ったら、なりません。意味がわかりません。
言われると嬉しいこと、嫌なことは人によって様々かと思います。
僕は、下に行くほど、やる気が減ります。
内容が提案や批判と似ていても、
「あーあ、わかってないなー。ビシッと俺様が正論でシメてやらんとダメだな!」
的な言い放し無責任感が備わると評論、…というイメージで使ってます。
評論されると、内容はそれなりでも一番やる気が萎えます。なんでかわからんけど。
メモ: 技術系?の話はFacebookから転記しておくことにした。
家のノートPCでSeaMonkeyを使っていると、画像が一部表示されないサイトがあります。
色んなサイトが該当しますが、例えば、らばQだと何の嫌がらせなのか、記事中の画像「だけ」表示されません。その一方で、背景や、らばQのバナーは出ますので、サイトやネットワークの問題ではなさそうです。
またIEやChromeで見ると画像が表示されますので、ファイアウォールなどに遮断されているわけでもなさそうですし、ノートPCとは別のデスクトップPC(Windows 7 64bit版)のSeaMonkeyで見ても画像が表示されますから、SeaMonkey自体の問題でもなさそうです。
SeaMonkeyのProfile Managerを起動(引数に -pを付けて起動する)して、新しくProfileを作ると画像が表示されたので、どうやらノートPCのSeaMonkeyのProfileに原因がありそうです。
新規Profileから設定をやり直すのも面倒くさいし、今まで使っていたProfileを何とかしようとして、キャッシュクリアとか、Cookie全消しとか、色々やってみたものの、一向に改善されません。困りました。
もうProfileがぶっ壊れてもいいや、という覚悟でProfileのディレクトリから適当に「blocklist.xml」ファイルと「adblockplus」「safebrowsing」ディレクトリを消してみたら、見事に復活しました。うーん、わけわからんな…。
節分から1日ずれちゃいましたが、節分の話でも。
北海道では節分に殻つきの落花生を撒きます。「鬼は外ー」は「雪(※)に向かって落花生を投げる」という意味でした。
もちろん店には大豆も(食べる用なのか?)売っていますが、撒くのは必ず落花生です。
しかし、関東、関西でその話をすると、大抵の人に「なんで落花生?大豆じゃないの?」と驚かれます。「うちもそうだよ」って言われたことはない…はず…たぶん。
そういや、なんで大豆or落花生なのだろう。小豆じゃダメなのかねえ??
(※)この時期の北海道はほぼ確実に雪が積もっているから、地面ではなく雪に向かって投げることになります。
パナソニックの半導体事業改革が完了 - EE Times Japanを読んで。
いつもは「絶対、事前にリークしてるでしょ」と思うくらい、ニュースが正確で早い(社内通達よりも)のですが、今回はニュースと社内通達が同時でした。珍しい〜。
推測するに、
辺りですかね。当たっても別に嬉しくないけど。
メモ: 技術系の話はFacebookから転記しておくことにした。
< | 2014 | > | ||||
<< | < | 01 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | - |
合計:
本日: