- ベストアンサー
Lispマクロ定義についての疑問:なぜ展開形がエラーにならずに正しく動作するのか?
- Lispのマクロ定義において、バッククオート内の`,`がついた要素はバッククオートの影響を受けずに展開されます。
- そのため、`(setq ,var (1+ ,var))`の展開形は、`(setq 1 (1+ 1))`となります。
- バッククオート内の`,`は、バッククオートをエスケープするための特別な演算子であり、バッククオートの効果を一時的に無効化する役割を果たします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
どんな環境で試されましたか? >clisp i . . . . I . i i i ooooo o ooooooo ooooo ooooo I I I I I I I I I 8 8 8 8 8 o 8 8 I I \ `+' / I I 8 8 8 8 8 8 I \ `-+-' / I 8 8 8 ooooo 8oooo \ `-__|__-' / 8 8 8 8 8 `--___|___--' 8 o 8 8 o 8 8 | ooooo 8oooooo ooo8ooo ooooo 8 --------+-------- Welcome to GNU CLISP 2.48 (2009-07-28) <http://clisp.cons.org/> Copyright (c) Bruno Haible, Michael Stoll 1992, 1993 Copyright (c) Bruno Haible, Marcus Daniels 1994-1997 Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998 Copyright (c) Bruno Haible, Sam Steingold 1999-2000 Copyright (c) Sam Steingold, Bruno Haible 2001-2009 Type :h and hit Enter for context help. [1]> (setq x 1) 1 [2]> (defmacro inc (var) `(setq var (1+ var))) INC [3]> (macroexpand '(inc x)) (SETQ VAR (1+ VAR)) ; T [4]> (inc x) *** - SETQ: variable VAR has no value The following restarts are available: USE-VALUE :R1 Input a value to be used instead of VAR. STORE-VALUE :R2 Input a new value for VAR. ABORT :R3 Abort main loop Break 1 [5]> (defmacro inc (var) `(setq ,var (1+ ,var))) INC Break 1 [5]> (macroexpand '(inc x)) (SETQ X (1+ X)) ; T Break 1 [5]> (inc x) 2
その他の回答 (1)
- kmee
- ベストアンサー率55% (1857/3366)
マクロとバッククオートの展開に誤解があるようです #1さんの実行例を良く見てください。 (defmacro inc (var) `(setq var (1+ var))) → (macroexpand '(inc x)) →(SETQ VAR (1+ VAR)) varは「var」のまま。 (defmacro inc (var) `(setq ,var (1+ ,var))) → (macroexpand '(inc x)) → (SETQ X (1+ X)) ,varがxに置き換わる。(「xの評価」に置き換わる、ではない) 実行の前に(setq var 1)してあった、とか、 (defmacro inc (x) `(setq x (1+ x))) で定義してたとかはないですか? (inc x) のあとで x だけで評価したらちゃんと変わってますか?
補足
xyzzyなのでcommonlispだと思います。 (defmacro inc (var) `(setq var (1+ var))) の定義でやるとエラーになるということでしょうか?