0

私はこれを行うことができるようにしたいと思います:

(mapcar #'quote '(1 2 3 4))

そしてこれを手に入れよう

('1 '2' 3 '4)

ただし、QUOTEは特殊な形式であるため、ファンコールすることはできません。

私はそれをマクロ化しようとしました:

(defmacro quoter (&rest args)
  `(loop for arg in ,@args collect (quote arg)))

(quoter '(1 2 3 4 ))

しかし、私が予想するように、それは私を取得します....

(LOOP FOR ARG IN '(1 2 3 4)
      COLLECT 'ARG)

入力を文字列に変換してからシンボルに変換しても機能しません。アトムだけでなく、入力フォームがある可能性があります。

私はここで何かが欠けていると確信しています。:-)

4

3 に答える 3

4

これにより、必要な拡張が生成されます。

(defmacro quoter (&rest args)
   (loop for arg in args collect `(quote ,arg)))

...しかし、そのようなマクロが実際に高レベルで必要なものである可能性は低いです(マクロで遊ぶだけの場合を除く)。展開は有効なリスト形式ではないため、展開を使用する唯一の方法はMACROEXPAND自分自身を呼び出すことです。そして、呼び出す場合はMACROEXPAND、それを関数にして、その関数を呼び出してみませんか?

于 2013-01-31T08:43:17.970 に答える
3

アイテムをフォームに変換する場合(quote item)は、変換を提供する必要があります。

たとえば(list 'quote item)または

`(quote ,item)

関数内で特殊なフォームまたはマクロを使用する場合は、関数を使用して、のようなものに渡すことができますMAPCAR

CL-USER > (mapcar #'(lambda (item) (list 'quote item)) '(1 2 3 4))

((QUOTE 1) (QUOTE 2) (QUOTE 3) (QUOTE 4))

これは、リストが変数に置き換えられた場合にも機能します。

これをマクロとして記述したい場合は、ソースコードを取得するという問題が発生し、それを変換する必要があります。リストがある場合は、それを直接変換できます。たとえば変数がある場合、(この変数の値がわからないため)できず、生成されたソースに変換を含める必要があります。

例:

CL-USER 119 > (defmacro quoter (list)
                (list 'quote (mapcar (lambda (item) (list 'quote item))
                                     (second list))))
QUOTER

CL-USER 120 > (macroexpand '(quoter '(1 2 3 4)))
(QUOTE ((QUOTE 1) (QUOTE 2) (QUOTE 3) (QUOTE 4)))
T

CL-USER 121 > (quoter '(1 2 3 4))
((QUOTE 1) (QUOTE 2) (QUOTE 3) (QUOTE 4))

しかし、今では何をすべきかわかりません(quoter some-variable)。現在、リストを変換することはできません-それは知られていないためです。次に、実行時の変換に対応するマクロ展開を提供する必要があります...

于 2013-01-31T13:26:52.787 に答える
2

このためのワンライナーは次のとおりです。

(mapcar (lambda (x) `',x) '(1 2 3 4))

引用符の使用法に注意してください。このフォームはいつか便利だと思います。

于 2013-03-25T09:52:06.540 に答える