Schemeでは、数値タワーは数値とその階層構造のロジックを 表すデータ型のセットです。

タワー内の各型は概念的に、より基本的な型の「上に」位置しているため、整数は有理数であり、数値でもありますが、その逆は必ずしも真ではありません。つまり、すべての数値が整数であるとは限りません。この非対称性は、言語が数値型の暗黙的な強制を、意味上の問題を発生させることなく、一方向にのみ安全に許可できることを意味します。つまり、整数を有理数に強制すると、情報は失われず、関数によって返される値に影響を与えることはありませんが、ほとんどの実数を整数に強制すると、関連する計算が変更されるため (たとえば、実数の 1/3 はどの整数とも等しくありません)、許可されません。
スキーム内
基本的に、数値タワーは、数値の集合論的特性を実装しやすい言語機能でコード化するように設計されています。つまり、すべての整数は暗黙の分母が 1 である有理数であり、すべての実数は暗黙の虚数部が 0 である複素数です。実際には、これらの特性が算術的に重要にならない限り、実装によってこれらの特性を無視することで時間とスペースを節約できます。また、数値の無視できる要素を削除することで数値を標準表現に縮小する際の表現の効率も向上します。
最も一般的な型 はnumber、いくぶん紛らわしい名前が付けられています。これは、複素数よりも一般的な型であるが、Scheme で定義されている標準的な数学演算で使用可能なすべての数学的値を表すために存在します。したがって、たとえば、正の無限大と負の無限大 (+inf.0および-inf.0、ここでの仮数は濃度までの近似値を意味します) を表します。これは、少なくともいくつかの数値演算が有効に適用できる数学的オブジェクトであるためです (たとえば、無限大に加算または乗算して無限大を生成したり、濃度を無限大と比較したりできます。この場合、無限大は常にどの有限値よりも大きくなります)。[1]より技術的なレベルでは、 Lisp では、 IEEE 754numberで定義されている厳密に数値ではない値の種類に対して、型階層内での場所が提供されるだけです。
Schemeプログラミング言語は、このモデル内ですべての算術を定義します。[2] [3]一部の実装では、タワーを拡張または適応する場合があります。JVM用のScheme実装であるKawaは、タワーを拡張して、四元数[4]と数量[5]の両方を含めます。数量とは、単位を持つ数値のサブタイプ化の方法です。たとえば、グラム数をメートル数に意味のある形で加算することはできません。これは、数量を介して、数値が次元解析から派生したロジックを継承し、数値間の関係における意味を支配し、したがって数値間の有効な算術的相互作用を支配するためです。
もう 1 つの一般的なバリエーションは、タワーまたはその一部の正確なバージョンと不正確なバージョンの両方をサポートすることです。R 7 RS Scheme は実装にこれを推奨していますが、厳密には必須ではありません。この場合、暗黙の強制の許容性を判断するために同様のセマンティクスが使用されます。不正確さは数値の伝染特性であり、[6]正確な値と不正確な値の両方を含む数値演算は、精度が実質的に無限である場合 (たとえば、検出可能な繰り返しを含む) または演算結果の精度がそのオペランドの不正確さに依存しないことが証明できる場合を除き (たとえば、少なくとも 1 つの被乗数が 0 である一連の乗算)、式に現れる最も正確な不正確な数値と少なくとも同じ精度の不正確な戻り値を生成する必要があります。
他の言語
ほとんどのプログラミング言語と言語実装は Scheme のような数値タワーをサポートしていませんが、実装の単純さが許す限り、一部の言語では限定的または一貫性のないサポートを提供しています。たとえば、Python はPEP3141 [7]を介して同様の構造を提供し、 Scheme の例を引用していますが、実際には有理数 ( fractions) は独自のモジュールからインポートする必要があり、有理数と複素数はどちらも通常の数値リテラルとは少し異なる構文を使用します。これは、Python の構文が Lisp ほど明示的ではないためです。
したがって、次の Scheme の例では次のようになります。
1 -2 +3 ⇒ 1 ⇒ -2 ⇒ 3 1/3 ⇒ 1/3 72/6+8/3i ⇒ 12+8/3i ; 強制: 標準形( + 3+2i 2-2i ) ⇒ 5 ; 強制: 標準形( - 3-62/32i 1+inf.0i ) ⇒ 2-inf.0i ; 強制: 無限基数( > 3+0/2i 3 ) ⇒ #f ; 強制: 3 ≯ 3
次の Python の例では次のようになります。
1 ; - 2 ; + 3
⇒ 1
⇒ - 2
⇒ 3
1 / 3
⇒ 0.3333333333333333
inf = float ( 'inf' ) # 無限大はファーストクラスではありません
from fractions import Fraction
x = Fraction ( 1 , 3 )
y = Fraction ( 2 , 3 )
x + y
⇒ Fraction ( 1 , 1 ) # 強制変換なし
( 3 + 2 j )
⇒ ( 3 + 2 j )
complex ( x , inf )
⇒ ( 0.3333333333333333 + infj ) # 強制変換: 等式違反
a = 1 / 3
b = Fraction ( 1 , 3 )
caz = complex ( a , 0 )
cbz = complex ( b , 0 )
a == b
⇒ False
caz == cbz
⇒ True # 等式違反の証明
complex ( x + y , - inf )
⇒ ( 1 - infj ) # 強制: 等式は保持されます
( 3 + 0 j ) > 3
⇒ トレースバック (最新 の 呼び出し が最後):
⇒ ファイル "<stdin>" 、 行 1 、 < module >内 # 強制なし: 型エラー⇒ TypeError : '>' は'complex'と'int'のインスタンス間ではサポートされていません
Python の例では、型強制のセマンティクスの一貫性のない適用によって数値の問題が自由に発生することがわかります。Python1 / 3では は 1 を 3 で割る呼び出しとして扱われ、浮動小数点数が生成されますが、複素数内に有理数を含めることは明らかに許容されていますが、それが正しくない場合でも、暗黙的に有理数から浮動小数点数または整数に強制されます。
Smalltalkもこのモデルに従うプログラミング言語ですが、Number のスーパークラスとして ArithmeticValue と Magnitude があります。
Schemeの数値タワーはCommon Lispの数値型の階層に触発されたものである。[8] [9]
番号
/ \
リアルコンプレックス
/ \
有理数フロート
/ \
整数比
参考文献
- ^ 「アルゴリズム言語Schemeに関する改訂7版レポート:6.2.4:実装拡張」(PDF)。
- ^ 「アルゴリズム言語Schemeに関する改訂版レポート:6.2.1:数値型」(PDF)。
- ^ 「アルゴリズム言語Schemeに関する改訂7版レポート:6.2.1:数値型」(PDF)。
- ^ 「Kawa リファレンスドキュメント: 12.4. クォータニオン」。
- ^ 「Kawa リファレンスドキュメント: 12.5 数量と単位」。
- ^ 「アルゴリズム言語スキームに関する改訂7レポート:6.2.2:正確性」(PDF)。
- ^ 「PEP 3141 – 数値の型階層」。
- ^ 「Schemeに関する改訂2レポート:II.6.:数値」(PDF)。
- ^ 「Common Lisp 言語、第 2 版: 2.1: 数値」。
