2

私の理解では、次を使用して作成されたリストを変更することは合法ではありませんquote

(let ((numbers '(3 2 1)))
  (set-car! numbers 99)  ; Illegal.
  numbers)

を使用して作成されたリストはどうquasiquoteですか? を使用して作成されたリストを変更することは合法quasiquoteですか?

(let ((numbers `(3 2 1)))
  (set-car! numbers 99)  ; Legal?
  numbers)

(let ((numbers `(,(+ 1 2) 2 1)))
  (set-car! numbers 99)  ; Legal?
  numbers)
4

1 に答える 1

2

The short answer is no, this isn't "legal", and certainly this should never be done in a program that aims to be portable. R6RS and R7RS have almost identical language around this, so I'll just quote from R6RS, Section 11.17 Quasiquotation:

A quasiquote expression may return either fresh, mutable objects or literal structure for any structure that is constructed at run time during the evaluation of the expression. Portions that do not need to be rebuilt are always literal.

Section 4.2.8 of R7RS has the same language, except that it says "newly allocated" instead of "fresh".

Since it is an error to attempt to modify literals in Scheme, it is an error to modify the result of a quasiquote form. This is something that you may seem get away with sometimes, but it will bite you sooner or later. The real catch here is that "portions that do not need to be rebuilt are always literal". Other portions may or may not be literal.

More specifically for OP posted code, `(3 2 1) is guaranteed to evaluate to a list literal by the semantics of quasiquote described in Section 11.17 of R6RS:

Semantics: If no unquote or unquote-splicing forms appear within the <qq template>, the result of evaluating (quasiquote <qq template>) is equivalent to the result of evaluating (quote <qq template>).

R7RS contains similar language in Section 4.2.8. Since (quote (3 2 1)) creates a list literal, the expression `(3 2 1) must also evaluate to a list literal.

On the other hand, OP code `(,(+ 1 2) 2 1) must evaluate (+ 1 2) and insert that result into the resulting structure. In this case, unquote is used via the , operator, so the resulting list structure may or may not be a list literal.

To take one more example, consider the quasiquoted expression `(,(+ 1 2) (2 1)). Here the main result is a list structure which may or may not be a list literal, but the element (2 1) of the resulting structure is guaranteed to be a list literal since it does not need to be rebuilt in the construction of the final result.

于 2021-11-10T13:10:05.923 に答える