奇妙なことに、Ubuntu 12.04 64 ビットで、Clojure 1.4.0 と Java(TM) SE ランタイム環境 (ビルド 1.7.0_06-b24) で異なる結果が表示されます。
user=> *clojure-version*
{:major 1, :minor 4, :incremental 0, :qualifier nil}
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294
user=> (type 1)
java.lang.Long
user=> (def max-plus-one (+ Integer/MAX_VALUE one))
#'user/max-plus-one
user=> max-plus-one
2147483648
user=> (type max-plus-one)
java.lang.Long
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
4294967294
clojure.core が numerics に使用する Java クラスをいつでもチェックして、機能がどのように実装されているかを確認できます。
+ 演算子の実装:
(defn +
"Returns the sum of nums. (+) returns 0. Does not auto-promote
longs, will throw on overflow. See also: +'"
{:inline (nary-inline 'add 'unchecked_add)
:inline-arities >1?
:added "1.2"}
([] 0)
([x] (cast Number x))
([x y] (. clojure.lang.Numbers (add x y)))
([x y & more]
(reduce1 + (+ x y) more)))
long を追加する Java 実装:
final public Number add(Number x, Number y){
return num(Numbers.add(x.longValue(),y.longValue()));
}
編集: Clojure 1.2.1 でテスト済み Clojure 1.2.1
で簡単なテストを行ったところ、そのバージョンの Clojure で正確な動作が得られました。
user=> *clojure-version*
{:major 1, :minor 2, :incremental 1, :qualifier ""}
user=> (def one 1)
#'user/one
user=> (class 1)
java.lang.Integer
user=> (def max-plus-one (+ Integer/MAX_VALUE one))
#'user/max-plus-one
user=> max-plus-one
2147483648
user=> (class max-plus-one)
java.lang.Long
user=> (+ Integer/MAX_VALUE Integer/MAX_VALUE)
java.lang.ArithmeticException: integer overflow (NO_SOURCE_FILE:0)
Clojure 1.4.0 ではなく、Clojure 1.2.x でテストを行ったと思います。REPL の *clojure-version* の値は何ですか?