Education: Racket 言語の基本的なデータ型
はじめに
Racket は Scheme プログラミング言語の実装であり、関数型プログラミングのパラダイムに基づいています。この記事では、Racket の基本的なデータ型について説明します。
1. Racketとは
Racket[1] は、Lisp プログラミング言語の一派である関数型プログラミング言語[2]であり、Scheme[3]を基盤にしています。
2. Racketにおけるデータ
Racket では、さまざまなデータ型が提供されています。ここでは、数字、文字列、文字、リスト、およびシンボルなどの主なデータ型について説明します。
2.1. 不変性 (immutable)
Racket では、一部のデータは不変性[4]です。不変性とは作成したデータが不変、すなわち変更できないことを示します。
ある変数が新たな値を代入した場合は、新たに領域を確保して、そこに値を格納します。元のデータは変更されません。
このため、 データを意図しない変更から守ることができ、データの安全性や並列平行性を向上できます。
3. Racketの基本データ型
この章では、Racket における基本的なデータ型について説明します。
これらのデータ型は、異なる種類の情報を格納するために使用されます。
3.1 数値型
Racket には整数型、有理数型、実数型の 3種類の数値型があります。
数値型の型はnumberとなります。
整数型
整数型は、正負の整数および 0 を表現するために使用します。整数型の型はintegerです。
(define my-integer 42)
上記の例では、変数my-integerに 42 を代入しています。整数型には、以下のような算術演算子を使用できます。
-
+: 加算 -
-: 減算 -
*: 乗算 -
/: 除算 -
quotient: 整数除算 -
remainder': 余りの演算 -
modulo: 剰余演算
有理数型
有理数型は、分数を表現するために使用します。有理数型の型はrationalです。
(define my-rational 3/4)
上記の例では、変数my-rational に 3/4 を代入しています。有理数型には、以下のような算術演算子を使用できます。
-
+: 加算 -
-: 減算 -
*: 乗算 -
/: 除算
実数型
実数型は、小数点以下の桁数を持つ数を表現するために使用されます。実数型の型は、float またはrealです。
(define my-float 3.141592)
上記の例では、変数my-floatに 3.141592 を代入しています。実数型には、以下のような算術演算子を使用できます。
-
+: 加算 -
-: 減算 -
*: 乗算 -
/: 除算
3.2. 文字列型
文字列型は、文字列を表現するために使用されます。文字列型の型はstringです。
文字列は、代入したい文字列"でくくります。
(define my-string "hello")
上記の例では、変数my-stringに文字列"hello"を代入しています。文字列型には、以下のような操作ができます。
-
string-append: 文字列を連結する -
string-length: 文字列の長さを取得する -
string-ref: 文字列の指定した位置にある文字を取得する
3.3. 文字型
文字型は、Unicode 文字を表現するために使用され、文字型の型はcharです。
文字型では、文字を#\fのように#\<文字>の形で記述します。
(define my-char #\あ)
my-char
#\あ
(char->integer my-char)
12354
上記の例では、変数 my-charに文字あを代入しています。文字型には、以下のような比較演算子を使用できます。
-
char=?: 文字が等しいかどうかを比較する -
char<?: 文字の大小関係を比較する -
char>?: 文字の大小関係を比較する -
char<=?: 文字の大小関係を比較する -
char>=?: 文字の大小関係を比較する
3.4. ブーリアン型
ブーリアン型は真偽値をとるデータ型で、型はbooleanです。
ブーリアン型は、真(#t)か偽(#f)のいずれかの値となります。そして、数値の比較など、条件の成否などを表すために使用します。
(define my-boolean #t)
上記の例では、変数my-booleanに#tを代入しています。
ブーリアン型には、ブーリアン型には、以下のような論理演算子が使えます。
-
not: 否定 -
and: 論理積 -
or: 論理和 -
xor: 排他的論理和
3.5. シンボル型
シンボル型は、変数名や関数名などに使われる文字列で、型はsymbolです。
シンボルは、文字列をそのまま記述します。"でくくりません。
その代わり、空白などの区切り文字や#などの文字はシンボルに使えません。」
Racket はシンボルが見付かると、シンボルではなくシンボルにバインドされた値を表示します。
シンボルそのものを記述したいときは、'でシンボルをエスケープします。
(define my-symbol 'hello)
my-symbol
'hello
上記の例では、'my-symbolにシンボルhelloを代入しています。 シンボルを表示するため、先頭に'`がついています。
3.6. ペア型とリスト型
ペア型とリスト型は、LISP 処理系の基本的な概念を示す型で、Racket もそれを踏襲しています。
LISP では、コンスセル[5]という 2つのデータをペアにしたデータが基準となります。
Racket では、コンスセルをペア型で表し、型はpairとなります。
ペア型
ペア型は、2つの要素を持つペアを表していて、cons を使用して作成します。作成したデータをコンスセルと呼びます。
コンスセルは、2つのデータを.で区切って表示します。
このとき最初の要素をcar、次の要素をcdrと呼びます。
(cons 1 2)
'(1 . 2)
上記の例は、car に1、cdr に2を代入したコンスセルを作成します。
図解すると:
+---+---+
| 1 | 2 |
+---+---+
と、なります。
リスト型
リスト型は、複数の要素を 1つにまとめたものです。リスト型の型はlistです。
リストは、各要素を’<空白>'で区切って表示します。
下記は、要素 1 , 2, 3 をもつリストを作成します:
(list 1 2 3)
'(1 2 3)
リスト型の構造
リストは、コンスセルを数珠つなぎにして作成します。
1つめのコンスセルは、car に最初の要素、cdr には 2番のコンスセルへのポインターが入ります。
同様に、2つめのコンスセルは car に 2番めの要素、cdr に 3番目のコンスセルへのポインターが入ります。
最後のコンスセルは、エンドマークとして、空のリスト('())が入ります。
たとえば、リスト( 1 2 3)を図解すると:
+-----+------+ +-----+------+ +-----+-----+
| 1 | o---+---->| 2 | o---+---->| 3 | '() |
+-----+------+ +-----+------+ +-----+-----+
と、なります。
4. 特殊なデータ
Racket では、システムが扱うための特殊なデータ型や定数があります。
このセクションでは、これらを説明します。
4.1. void
void型は値を持たない型で、型はvoidです。
手続きが値を返す必要がない場合に使用されます。
たとえば、下記のコード、
(define void-procedure
(void)) ; ← 値を返さない
は、手続きvoid-procedureを定義しています。void-procedureは値を返す必要がないので、voidを使用しています。
void-procedureは値を返さないので、実行しても何も起きません。
> void-procedure
>
上記のように、void-procedureを実行すると、何も返らずプロンプトが表示されます。
4.2. undefined
undefinedは、未定義の値を表現するために使用される定数です。
Racket で未定義の変数を参照しようとするとundefinedとなり、エラーが発生します。
(define y 1)
(display (+ x y)) ; xが未定義(undefined)なのでエラー
x: undefined;
cannot reference an identifier before its definition
in module: top-level
[,bt for context]
おわりに
この記事では、関数型プログラミング言語 Racket の基本的なデータ型について説明しました。
主なポイントは以下の通りです:
- Racket は関数型プログラミング言語であり、データは不変性を持ちます。
- Racket の基本的なデータ型について説明し、基本的な記述方法や演算子について説明しました。
これらを理解することで、Racket プログラミングの初歩を踏み出しました。
さらに学習を進め、Racket で簡単なプログラムを書いたりすることで、より関数型プログラミング言語への理解を深められるでしょう。
それでは、Happy Hacking!
参考資料
本
Web
-
Racket: 関数型プログラミング言語であり、Scheme を基盤に持つ Lisp 派生の言語 ↩︎
-
関数型プログラミング言語: プログラムを数学的な関数の集合として考えるプログラミングパラダイムの 1つ。副作用を排除することで、プログラムの信頼性や並列処理の実現が可能 ↩︎
-
Scheme: LISP 派生の関数型プログラミング言語で、シンプルな文法での関数型プログラミングが得意 ↩︎
-
不変性: 一度作成されたデータは変更できない性質。グの発生を抑制し、プログラムの安全性を高める ↩︎
-
コンスセル:
cons手続きによって作成されるペア型のデータ。先頭のデータをcar、次のデータをcdrと呼ぶ ↩︎
Discussion