Scheme には min
と max
という1つ以上の real number の最小値および最大値を返す手続きがあります。R5RS から R7RS に至るまで、その numerical tower に沿って一貫して定義されています。(ただし R6RS では positive infinity と negative infinity についての記述が追加されていました。)
ところが上の定義には問題があります。引数によっては最小値や最大値が定義できない場合があるのです。「引数の集合は有限個の実数の集合なんだから、常に最小値と最大値が存在するだろう」というのは数学的に正しいですが、Scheme の場合 NaN が real number に含まれています。NaN は(NaN 自身を含め)どの real number と比較した場合でも false (#f
)になるとされているため、NaN が引数に出てくると total order になりません。
このことが関係して、min
や max
に NaN を渡すと一見奇妙な振舞いをする実装もあります。例えば Gauche や Ypsilon は引数の順序によって返る値が変わります:
$ gosh -V
Gauche scheme shell, version 0.9.4 [utf-8,pthreads], x86_64-unknown-linux-gnu
$ gosh
gosh> (min +nan.0 1)
+nan.0
gosh> (min 1 +nan.0)
1.0
gosh> (max +nan.0 1)
+nan.0
gosh> (max 1 +nan.0)
1.0
gosh>
$ ypsilon
Ypsilon 0.9.6-update3 Copyright (c) 2008 Y.Fujita, LittleWing Company Limited.
> (min +nan.0 1)
1.0
> (min 1 +nan.0)
+nan.0
> (max +nan.0 1)
+nan.0
> (max 1 +nan.0)
1.0
>
ちなみに R5RS/R7RS では NaN や infinity は実装拡張とされ、NaN がサポートされていない実装では問題ありません。
参考: