定義と束縛 - Alexandria

概要

このページではCommon Lispの汎用ユーティリティであるAlexandriaにおける定義・束縛系のオペレータを紹介します。

define-constantマクロ: 安全な定数の定義

Alexandriaのdefine-constantマクロは、定数を安全に定義できるオペレータです。

ANSI Common Lispにおける標準であるdefconstantはすでに使用されているシンボルを定数として定義してもエラーになりません。このような仕様だと名前の衝突が発生しても分からないまま使ってしまうというリスクがあります。

Alexandriaのdefine-constantdefconstantで定義を行う前に名前の衝突が発生していないかどうかを確かめてから定義してくれます。名前の衝突がある場合は Restart 付でエラーを通知します。

以下にサンプルを示します。

;; あらかじめインポートしておく
(shadowing-import 'alexandria:define-constant)
; => T

;; 変数を定義しておく
(defvar web "www.google.co.jp")
; => WEB

;; ANSI標準の defconstant は同じシンボルを定数として使用してもエラーにならない
(defconstant web "www.yahoo.co.jp")
; => WEB
web
; => "www.yahoo.co.jp"

;; Alexandria の define-constant は同じシンボルを使うとエラーになる
;; Restart は3種類用意されている
;;  - continue: 新しい値で定数を再定義する
;;  - ignore: 古い値を保持したままにする
;;  - abort: メインループに戻る(処理系が提供するrestart)
(define-constant web "www.google.co.jp")
; ** - Continuable Error
; WEB is an already defined constant whose value "www.yahoo.co.jp" is not equal
;      to the provided initial value "www.google.co.jp" under EQL.
; If you continue (by typing 'continue'): Try to redefine the constant.
; The following restarts are also available:
; IGNORE         :R1      Retain the current value.
; ABORT          :R2      Abort main loop

:r1
; => WEB

web
; => "www.yahoo.co.jp"

;; 元の値と新しい値が等価ならエラーは通知されない
;; :test キーワード引数で等価性判定述語を指定できる(標準は eql)
(define-constant web "www.yahoo.co.jp" :test #'string=)
; => WEB

if-letマクロ: letif

Alexandriaのif-letマクロは複数の条件判定を行い、全て真である場合にはthen-formを、1つでもnilがある場合はelse-formを実行します。ifandを組み合わせたような動作ですが、実際にはそれぞれの条件判定の結果を変数に束縛する機能があるため、ifandletを組み合わせたものとなります。
(if-let ((a 1) (b nil)) a b)
; => NIL

when-letマクロ: letwhen

when-letマクロは前節のif-letマクロの亜種です。if-letthen-formは1つの式に限られますので、もし複数式を実行したい場合は明示的にprognしなければなりません。when-letekse-formがない代わりにthen-formが暗黙的にprognされるため、複数の式を列挙することができます。それ以外はif-letと同じです。

when-let*マクロ: let*when

when-let*マクロは直線的な束縛を行うlet*形式のwhenです。
(when-let* ((a 1) (b a)) t)
; => T
letは並列的な束縛ですが、let*は直線的・逐次的な束縛です。そのため、上記サンプルのように、手前の束縛を使って次の束縛をすることができます。

0 件のコメント :

コメントを投稿