リストをチェックしてプロシージャ呼び出しがあるかどうかを確認するマクロを作成しようとしていますが、その方法がよくわかりません。私の頭に最初に浮かぶのは、手順を使用することですか?チェックする関数ですが、機能しません。私がやろうとしていることの例は次のとおりです。
(procedure? (car '(+ 1 2)))
現在、そのリストの car は を返します+
が、関数はまだ を返しますfalse
。
リストの車が手順かどうかを確認する方法はありますか?
(car '(+ 1 2)) => '+ not +
+は手続きですが、'+はただの記号です!
引用符で囲まれていない変数を確認する必要があります。
(procedure? (car (list + 1 2))); => #t
;or
(procedure? (car `(,+ 1 2))); =>#t
リストが '(abcd) の形式の場合、次の方法で確認できます。
(procedure? (eval (car '(+ 1 2)) (interaction-environment)));=>#t
なぜなら:
(eval (car '(+ 1 2)) (interaction-environment))
;=>(eval '+ (interaction-environment))
;=>+
ここではマクロは必要ないと思います。関数で十分です。その機能を抽象化します。
(define (application-form? lst)
(procedure? (eval (car lst) (interaction-environment))))
リストのがバインドされていないシンボルであることが許可されている場合car
、この問題は移植可能に解決できません。ただし、Guileで解決することはできます。
(define (procedure-symbol? x)
(and (symbol? x)
(let ((var (module-variable (interaction-environment) x)))
(and var
(variable-bound? var)
(procedure? (variable-ref var))))))
(define (application-form? lst)
(procedure-symbol? (car lst)))