本コンテンツの大部分は、末尾に記載させていただいたブログからの引用、インスパイヤです。ご了承下さい。
数学の世界で + は演算子である。5歳の子供でもそれを知っている。そして私やあなたが老いて死にゆくまで、+ は演算子でありそこに疑念の入る余地はない。
プログラミングの世界でもふつう + は演算子である。CでもJavaでもPerlでも + は演算子であり、それ以上でもそれ以下でもない。
ところが驚くべきことに、Iolanguageの世界では + は演算子*1ではないのである。
嘘だと思うなら、エディタを立ち上げて、次のようにしてみるといい。
Number + := method(v, (call target asSimpleString) .. (v asSimpleString))
1 + 2
123 + 456
あなたは今、Number#+ メソッドを再定義した。そうしたら1 + 2は12という答えを返した。そう、Iolanguageの世界で + は演算子ではなく、ユーザが再定義可能なひとつのメッセージに過ぎないのだ。
私が知るかぎりIolanguageにシンタックスシュガーなんて存在しない。(極力シンタックスシュガーを用意しない方針だったはず。)
疑い深いあなたはこれだけでは納得しないかも知れない。そしてきっと、他の演算子についても試してみるのだろう。
Sequence multi := Sequence getSlot("*")
Sequence * := method(v,
buffer := list()
for(i, 1, v,
buffer append(call target))
buffer join)
Number plus := Number getSlot("+")
Number + := method(v,
(call target asSimpleString) .. (v asSimpleString))
Number minus := Number getSlot("-")
Number - := method(v,
res := call target minus(v)
if(res > 0, res, "unknown world for me."))
Number div := Number getSlot("/")
Number / := method(v,
str := call target asString(0) split(".") at(0)
str split(v asString) size minus(1))
Number multi := Number getSlot("*")
Number * := method(rightv,
leftv := call target asSimpleString
strlen := leftv size
if(strlen > rightv,
leftv,
emptysize := rightv minus(strlen)
rest := emptysize % 2
leftemptysize := emptysize div(2) floor plus(rest)
rightemptysize := emptysize minus(leftemptysize)
buffer := list()
for (i, 1, leftemptysize,
buffer append("*"))
buffer append(leftv)
for (i, 1, rightemptysize,
buffer append("*"))
buffer join))
Number doublemulti := Number getSlot("**")
Number ** := method(v,
self * v * v)
1 + 2
123 + 456
9 - 4
21 - 34
12345 * 20
3333456456 / 3
3333456456 / 5
12345 ** 7
納得した?
そうIolanguageの世界では + だけでなく、演算子のほとんどがメッセージ呼び出しなのである。
演算子をメッセージにする利点は2つある。1つは今見たようにそれが再定義可能であることだ。しかしより大きな利点は2つ目にある。
上で再定義した(ry
(...力尽き)
という...
という大部分が引用だった。後悔はしていない。反省はしている。
原文記事書いた方に怒られるかもしれないけど、真摯に受け止める。