ここのところ「比較的新しいコンパイラ系のプログラミング言語を何か1つ身につけたいものだな」という気分が高まっていた。
最初に候補として挙がったのはSwiftやKotlinだったのだが…、スマホアプリ開発に限定されない、もっと汎用的な言語の方が望ましい。ScalaはJava系だし(そして、Javaは普段全く使わないし)、Rustは難しそうだし…、と始められないでいたところに出会ったのが、Go。「Goは言語仕様がコンパクトでシンプル」とどんな入門書にも書いてある。
それで年が明けてから、(Web上のGo言語入門なんかを読みながら)Rubyで書いたプログラムをGoで書き直すことを通して「Gopher修行」に勤しんでいたのだが…、思わぬバグで躓いた。RubyとGoの間に非常に些細な(しかし重要な)違いがあったのだ。
具体的に言うと、「負の数の剰余演算結果の符号が異なる」のである。例えば、Rubyで「-1 % 2」とやると結果は「1」だが、Goでは「-1」なのだ。
と言うワケで、様々なプログラミング言語で「1 % 2」「1 % -2」「-1 % 2」「-1 % -2」と書いた場合の結果を比較してみた(ただし当然、プログラミング言語によって「Mod」や「%%」「\」等、演算子に用いられている記号は異なる)。
結論から言うと、C、C#、C++、CoffeeScript、D、Excel VBA、Go、Hot Soup Processor、Java、JavaScript、Kotlin、なでしこ、OCaml、PHP、Rust、Scala、Swift、TypeScript、Visual Basic(.NET)では、それぞれ「1」「1」「-1」「-1」となる(分子の符号と一致する)。ところが…、
Common Lisp、Crystal、Excel関数、Lua、Perl、Python2、Python3、R、Rubyでは、「1」「-1」「1」「-1」となる(分母の符号と一致する)のだ! Excel VBAは「1」「1」「-1」「-1」なのに、Excelの「MOD」関数は「1」「-1」「1」「-1」だとか、いったいどういうこっちゃ…。
更に驚くべきはSchemeで、何と「1」「1」「1」「1」となる!
本当は、Cobol、Fortran、Dart、F#、Haskell、Objective-C、Pascal、Prolog、Smalltalk、と、調べてみたいプログラミング言語は他にもいろいろあるのだが…。ま、この辺で。
※ Schemeの結果だけどうしても謎だったので、もう少し調べてみた。Schemeで「(mod 1 10)」(「mod 1 -10)」「(mod -1 10)」「(mod -1 -10)」をそれぞれ評価してみると…、「1」「1」「9」「9」が返ってきた! なるほど…、世の中いろいろなプログラミング言語があるものである。

0