論理型(Boolean)
論理型は、真(true)または偽(false)のいずれかを表すデータ型です。式言語では、真の値を #t、偽の値を #f と記述します。値が論理型かどうかを次の式で検査できます。
(boolean? obj) ; obj は任意のデータ
例2.1
(boolean? #t) => #t (boolean? 0) => #f (boolean? #f) => #t
数量(Quantity)
数量は、一般に数値として扱われるデータ型を拡張したもので、通常の数値と単位付きの数値に分類されます。また、数値は数学上の概念を基に整数・実数に分類され、実数は正確数(exact)と不正確数(inexact)に分類されます。なお、整数は常に実数であり、また正確数となる要件を満たします。
数値定数は、基数接頭辞に続けて、符号および数値を記述します。基数接頭辞が省略された場合は10 進数とみなされます。
例2.2
#b01001001 => 73 ; 2 進数 #o111 => 73 ; 8 進数 #d73 => 73 ; 10 進数 73 => 73 ; 10 進数 \x49 => 73 ; 16 進数
あるオブジェクトが数量型であるかを検査するには、以下の式を用います。
(quantity? obj) ; obj は数量か? (number? obj) ; obj は数値か? (real? obj) ; obj は実数か? (integer? obj) ; obj は整数か?
数値の後に任意の単位が続くものを、単位付き整数と呼びます。単位付き整数は、スタイル指定でページサイズや文字の大きさなどを指定する場合に用いられます。あらかじめ定義されている単位には次のものがあります。
- cm(センチメートル)
- mm(ミリメートル)
- in(インチ)
- pt(ポイント)
- pica(パイカ)
また、必要に応じて単位を定義することも可能です。たとえば、写植で用いられるQ数を定義するには次のように記述します。
(define-unit Q 0.25mm)
参考までに、各単位と長さの比を表2.2に示します。
表2.2 単位と長さ
単位 | 長さの比 |
---|---|
cm | |
mm | |
in | |
pt | |
pica | |
Q |
文字(Character)
文字型は、単一の表示可能な文字を表すデータ型です。文字定数は#\<文字>または#\<文字名>という記法で記述します。
例2.3
#\a ; 英小文字 #\A ; 英大文字 #\( ; 左括弧 #\space ; スペース文字 #\newline ; 改行文字 (integer? obj) ; obj は整数か?
あるオブジェクトが文字であるかを検査するには、以下の式を用います。
(char? obj)
文字列(String)
文字列とは文字の連なりのことで、二重引用符(”)で括って記述します。二重引用符を含む文字列を記述する場合、二重引用符はそのままでは文字列の開始、または終了と認識されてしまいますので、バックスラッシュ(\)[4]を前置してエスケープする必要があります。
あるオブジェクトが文字列であるかを検査するには、次の式を用います。
(string? obj)
例2.4
(string? "Hello, XML!") => #t (string? DSSSL) エラー (string? "DSSSL") => #t (string? ’DSSSL) => #f
リスト(List)
リストとはデータ構造のひとつで、オブジェクトが鎖のように繋がっているものを指します。式言語の基礎となっている Scheme はリスト処理に優れており、リストをあらわすには各要素をスペースで区切って丸括弧で囲むだけです。たとえば、要素 a、b、c、d、e からなるリストは、次のように記述します。
(a b c d e)
Scheme では、リストの先頭を car 部[5]、先頭を除いた残りの部分をcdr 部[6]と呼びます。先の例であれば、 car 部はオブジェクト a、 cdr 部はリスト (b c d e) となります。なお、要素が空のリスト “()” には car 部も cdr 部もありません。
あるオブジェクトがリストであるかを検査するには、次の式を用います。
(list? obj)
ペア(Pair)
ペアはリストに近いデータ構造で、やはり car 部と cdr 部があります。ペアを記述するには、 car 部と cdr 部の間にピリオドを記述する点対(dotted pair)と呼ばれる表記法を用いるか、手続き cons を用います。オブジェクト a、b を要素とするペアの記述例を次に示します。
(a . b) (cons a b)
オブジェクトがペアであるかを検査するには、次の式を用います。
(pair? obj)
リストとペアは混同しやすいのですが、リストがペアになるとは限らず、逆にペアがリストになるとは限りません。特に、リストは最後の要素に空リストが含まれているものを指すので注意してください。以下に、リストあるいはペアになる場合、ならない場合を例示します。
例2.5
(list? ’(a b c)) => #t (pair? ’(a b c)) => #t (list? ’(a . b)) => #f (pair? ’(a . b)) => #t (list? ’()) => #t (pair? ’()) => #f (list? ’(a . (b . ()))) => #t (pair? ’(a . (b . ()))) => #t
[4]一般的な日本語環境では、バックスラッシュは円マーク(¥)として表示されます。
[5]歴史的な理由で“Contents of Address part of Register” に由来した名前です。「カー」と読みます。
[6]Contents of Decrement part of register” に由来します。「クダー」と読みます。
先ほどのlist?あるいはpair?の記述例を見て、なぜ(list? (a b c)) じゃないのだろうか、と疑問に思われたのではないでしょうか。
Scheme では、手続きが呼び出されたときに引数として渡されるのは、引数として記述された表現ではなく、それを評価した結果になります。つまり、(list? (a b c)) は(a b c) を評価した結果を述語手続きlist?に渡すことと同じ意味になります。(a b c) を評価すると、おそらくはエラーになるか、あるいは有効な結果を返すかもしれませんが、いずれにせよ意図することとは異なることが分かるでしょう。
そこで登場するのがクォート[ ’ ][a]です。クォートすることによって、直後にあるリストや式を書かれた通りのもの(リテラル)として扱うことができます。第3 章以降に頻繁に出てくるシンボルを引数に指定する場合もクォートが必要になります。
なお、論理定数、数値定数、文字定数、文字列定数は“それ自身へ” と評価されるので、クォートの必要はありません。
’"abc" => ”abc” "abc" => ”abc” ’12345 => 12345 12345 => 12345 ’#t => #t #t => #t