🎾

Racketにおけるシンボルの基本

2023/09/20に公開

はじめに

この記事では、Racket におけるシンボルについて詳しく説明します。
シンボルは、Racket プログラミングで変数名や関数名などに使われる基本的な要素であり、プログラムの可読性や効率性に寄与します。

1. シンボルの基本概念

Racket プログラミングにおいて、シンボルは一意の識別子(Identifier)[1]として変数名や関数名に使用されます。
シンボルは、通常単一の単語や文字列で表され、変数名や関数名などの識別子として使用されます。

1.1 シンボルの不変性

Racket プログラミングにおいて、シンボルは一度定義されたら不変[2]です。
これは、値が一度設定されると変更できないことを意味します。
この不変性は、プログラムの安定性を確保するために重要であり、変数や関数が予期せぬ変更を受けないことを保証します。

たとえば、下記のコードtest.rkt:

test.rkt
(define x 10)
(writeln x)      ; 10
(define x 20)   ; xの値を、20に変更
(writeln x)

上記のコードを実行すると、下記のエラーが発生します:

test.rkt:5:8: module: identifier already defined
  at: x
  in: (define-values (x) 20)

このように、すでに定義済みのシンボルxには値を上書きできません。

1.2 シンボルのスコープ


Racket のシンボルは、スコープに応じて値が異なる場合があります。
コードにすると、以下のようになります:

(define x 10)
(define y 20)

(writeln x)  ; 10
(writeln y)  ; 20
(let ([x 30])      ;  ローカルスコープで、同一シンボル`x`を使用
    (writeln  x))   ; 30

このように、2番目のxでは 30`` が表示されます。 letブロック内でx`の値が書き換えられているためです。

2. シンボル の作成

Racket のシンボルは、任意の文字列から作成できます。英数字だけでなくほかの言語の文字も使えます。
また、-,*などの記号も使えます。

以下のシンボルは、すべて問題なく使えます:

  • one+two
  • シンボル
  • -its-a-symbol-

2.1. 大文字と小文字

シンボルは大文字と小文字を区別します。シンボルHelloとシンボルhelloは別のシンボルです。このため、同一オブジェクトかどうかをチェックする関数eq?の結果は、偽(#f)となります。

コードにすると、下記のようになります:

(eq? 'Hello 'hello)

#f

2.2. シンボルに使えない文字

シンボルには、スペースや特殊記号 (()[]{}",'、`、;#|\) が使えません。

スペースは区切り文字として機能します。そのため、スペースを含む文字列は 1つのシンボルとしては使えません。
特殊記号は Racket でデータを表現するために使用します。シンボルとデータを区別するため、シンボルには使えません。

  • my symbol: (スペースを含む )
  • a,b: (,を含む)

また、数字や文字列などのデータ型もシンボルとしては使用できません。

  • "abc": (文字列はシンボルにできない)

以下のような文字列はシンボルとして使えます。

  • 1a: (数字から始まる文字列でも可)
  • 1+1: (数字+記号でも可)

2.3. シンボル のエスケープ

Racket でシンボルを扱うには、シンボルをエスケープする必要があります。エスケープは、シンボルの先頭に'を追加します。

例:
hello'hello

シンボルは、|でくくってもエスケープできます。
この場合は、スペースなど特殊な文字を含んだシンボルを作成できます。
たとえば、|hello world|hello worldというシンボルになります。

コードにすると、下記のようになります:

(define x '|hello world|)  ; 'hello world'シンボルを作成
x

'|hello world|   ; スペースを含んだシンボルは、'|'でくくられて表示される

2.4. エスケープ文字を使ったシンボルの作成方法

\を使うと、空白や特殊記号を含んだシンボルが作成できます。
たとえば、hello\ worldとすればhello worldというシンボルが作成できます。

コードにすると、下記のようになります:

(define x 'hello\ world)
x

'|hello world|

2.5. 文字列から シンボルを作成する

関数string->symbolは文字列を引数として受け取り、シンボルを返す関数です。
string->symbol を使って、文字列からシンボルを作成できます。

(string->symbol "hello world")
'|hello world|

2.6. シンボルと同一性 (interned)

Racket におけるシンボルは interned[3] です。つまり、同じ名前のシンボルは同一のオブジェクトであることが保証されています。
同一オブジェクトなので、eq?関数の結果で#tが返ります。

コードでは、下記のようになります:

(define x 'hello)
(define y (string->symbol "hello"))
(eq? x y)   ;   xとyは値が同一のシンボルなので真

#t

おわりに

この記事では、Racket におけるシンボルについて説明しました。
シンボルは Racket プログラムで変数や関数などに使用され、Racket プログラミングの基本となります。

この記事や参考資料をもとにシンボルについての理解を深め、Racket プログラミングスキルを向上させましょう。

それでは、Happy Hacking!

参考資料

Webサイト

脚注
  1. 識別子 (Identifier): プログラム内で使用される変数名や関数名などの名前を指す用語。 ↩︎

  2. 不変 (Immutable): 値が一度設定されると変更できない性質。 ↩︎

  3. 同一性 (Interned): 同名のシンボルが同一のオブジェクトであることの保証。 ↩︎

GitHubで編集を提案

Discussion