LoginSignup
3
2

More than 5 years have passed since last update.

予約語が無いということ

Posted at

シャドウイング

プログラミング言語 Scheme では予約語というものはない。 たとえば define のような基本的な構文すら define の機能に define という名前が束縛されていると考えることが出来る。

再定義や代入には制限があるので予約語ではないからといってどこにでも現れることが出来るわけではないが、 let などで隠蔽 (shadowing) する分にはどんな識別子でも対象に出来る。

こんなコードは(まった)く正しい。

(let ((define *)
      (a 2))
  (define a 2))

もちろん、ほとんどの場合には単にわかり(にく)くなるだけなので基本的な構文と同じ名前に別の意味を持たせるのは避けるべきだが、 Scheme における識別子の考え方を理解する上では重要な点でもある。

短縮表記

以下のような式を評価すると何が返ってくるか答えられるだろうか?

(let ('-) '1)

' はあくまでも quote を短縮した表記法だ。 そのことを思い出して書き換えると、上記は

(let ((quote -)) (quote 1))

と等しい。

quote もまた単なる識別子であり隠蔽可能であるので、この quote- と同じ手続きに束縛された変数に過ぎず、式を評価した結果は -1 となる。

import

Scheme では、 R6RS からモジュール化の仕組みが追加された。 ライブラリと呼ばれる別のモジュールが公開する機能を import すればその機能が使えるようになる。 ライブラリは規格 (処理系) が提供するものの他に、自分で作ることもできる。

さて、 import(さい)には、名前を変更する機能がある。

たとえば definedef という名前で導入する場合には R6RS ではこのように書ける。

#!r6rs
(import (rename (rnrs) (define def))
        (except (rnrs) define))

(def a 1)
(display a)

この場合は

  • (rnrs) というライブラリから define という名前を def にリネームして導入する
  • (rnrs) というライブラリから define 以外を導入する

ということを指定している。

違いの吸収

Scheme の仕様の改定で変更されたもののひとつとして define が挙げられる。

R6RS の define は束縛する値を省略することが出来る。 その場合は変数を束縛している値は未定義であるが、直後に set! をするような場合には未定義であることを強調する書き方が出来た方が好ましい場合もある。 R7RS では define で変数を定義するときには初期値を省略することは出来ない。

この違いを吸収して R7RS で R6RS 風の define を使おうとすると以下のように書くことが出来る。

(import (rename (scheme base) (define r7rs:define))
        (except (scheme base) define)
        (scheme write))

;; R6RS 風の define を定義する
(define-syntax define
  (syntax-rules ()
    ((_ i)
     (r7rs:define i (if #f #t)))
    ((_ i f)
     (r7rs:define i f))))

(define a)  ; R7RS だが、 R6RS 風の define にできる
(set! a 'foo)
(display a)

まとめ

Scheme では仕様の改定によって新しい機能が追加されることも、既存の機能の挙動が変更されることもある。 また、処理系ごとの差異もかなり大きい。

しかし、基本的な言語機能を予約語として表現しないという性質によって名前の衝突は簡単に回避できるし、別バージョンの共存も簡単に成し得る。 いくつかの言語がバージョンアップと共に予約語の追加で破壊的な衝撃を(もたら)すのと比較すると、穏当(おんとう)に移行可能なのが Scheme なのである。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2