20

Common Lispを学習していますが、2つのコンマと組み合わせた2つのバッククォートの使用法を理解するのに問題があります。

``(a ,,(+ 1 2))

つまり、次のように評価される理由がわかりません。

`(A ,3)

そのようなものではなく:

`(A 3)

フォームの前にある2つのバッククォートを評価するために、両方のコンマが「消費」されたため、どのコンマも残されてはならず、まだ1つ残っていると自分自身に説明しています。どのように見えるでしょうか

``(a ,,(+ 1 2))

リストと'のみを使用しますか?

4

2 に答える 2

27

スペックから

これは、Common LispHyperSpecがネストされたバックティックについて言っていることです

バッククォート構文がネストされている場合は、最も内側のバッククォート形式を最初に展開する必要があります。これは、複数のコンマが連続して発生する場合、左端のコンマが最も内側のバッククォートに属することを意味します。

R5RSスキームの仕様には、バックティックに関する次の詳細も含まれています。

準引用符フォームはネストできます。置換は、最も外側のバッククォートと同じネストレベルに表示されるクォートされていないコンポーネントに対してのみ行われます。ネストレベルは、連続する各準引用の内部で1ずつ増加し、各非引用の内部で1ずつ減少します。

また、通常の見積もりと同様に、評価ごとに1つのバッククォートのみが折りたたまれることを覚えておいてください。再帰的ではありません。

実行中のルール

これらの3つの詳細がどのように相互作用するかを確認するために、例を少し拡張してみましょう。この表現...

``(a ,,(+ 1 2) ,(+ 3 4))

これに評価されます(SBCL表記で):

`(A ,3 ,(+ 3 4))
  1. 左のバッククォートが折りたたまれたため(+ 1 2)、一致するコンマ(HyperSpecによると2番目のコンマ)によってエスケープされました。
  2. 一方、は(+ 3 4)展開するのに十分なコンマがありませんでした(これはR5RSが言及していることです)。
  3. バッククォートが再帰的に拡張されないため、1つのバッククォートのみが折りたたまれました。

両方のコンマを展開する

他のバッククォートを取り除くには、別のレベルの評価が必要です。

(eval ``(a ,,(+ 1 2) ,(+ 3 4)))

両方のバックティックがなくなり、わかりやすいリストが残ります。

(A 3 7)
于 2011-09-26T01:18:01.177 に答える
2

No, both commas were consumed. There were two levels of quoting and two levels of commas. Now there's one level of quoting and one level of commas. In fact, GNU Common Lisp (2.44.1) evaluates your expression as

(list 'a 3)

That's exactly the same thing as

`(a ,3)

but more explicitly has "evaluated" both commas.

于 2011-09-26T00:47:59.723 に答える