あるポイント位置で仕様がマッチに失敗しても、構文エラーがシグナルされるとは限りません。そのかわりバックトラッッキング(backtracking)が開始されます。バックトラックはすべての選択肢をマッチングするまで行なわれます。最終的に引数リストのすべての要素は仕様内の要素のいずれかとマッチしなければならず、仕様内の必須要素は引数のいずれかとマッチしなければなりません。
構文エラーが検出されてもその時点では報告されず、より高位レベルの選択肢のマッチングが終わった後、実際のエラー箇所から離れたポイント位置でエラーが報告されるかもしれません。しかしエラー発生時にバックトラックが無効ならエラーは即座に報告されるでしょう。ある状況ではバックトラックも自動的に再有効化されることに注意してください。&optional
、&rest
、&or
により新たな選択肢が設定されたとき、または部分リスト、グループ、インダイレクト仕様が開始されたときはバックトラックが自動的に有効になります。バックトラックを有効、または無効にした場合の影響は、現在処理中のレベルの残り要素と低位レベルに限定されます。
何らかのフォーム仕様(すなわちform
、body
、def-form
、def-body
)をマッチングする間、バックトラックは無効になっています。これらの仕様は任意のフォームにマッチするので、何らかのエラーが発生するとしたらそれは高位レベルではなく、そのフォーム自体の内部でなければなりません。
バックトラックはクォートされたシンボル、文字列仕様、または&define
キーワードとのマッチに成功した後にも無効になります。なぜなら通常これは構文が認識されたことを示すからです。しかし同じシンボルで始まる一連の選択肢構文がある場合には、たとえば["foo"
&or [first case] [second case]
...]
のように、通常は選択肢の外部にそのシンボルをファクタリングすることによりこの制約に対処できます。
ほとんどのニーズは、バックトラックを自動的に無効にする、これら2つの方法で満足させることができますが、gate
仕様を使用して明示的にバックトラックを無効にするほうが便利なときもあります。これは高位に適用可能な選択肢が存在しないことが分かっている場合に有用です。let
仕様の例を参照してください。