2012-03-07 3 views
1

手続き呼び出しがあるかどうかを調べるためにリストをチェックするマクロを書こうとしていますが、どうすればいいかわかりません。私の頭に最初に来るのは、この手順を使うことです。チェックする機能はありますが、うまく動作しません。やろうと何イムの例は以下の通りです:シンボルが手続きかどうかをチェックする方法

(procedure? (car '(+ 1 2))) 

今、そのリストの車は+を返しますが、機能はまだfalseを返します。

リストの車が手続きかどうかを確認する方法はありますか?

答えて

2
(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)) 
;=>+ 

マクロが必要ないとは思いますが、機能は十分です。機能 抽象:リストのcarが結合していないシンボルが許可される場合

(define (application-form? lst) 
     (procedure? (eval (car lst) (interaction-environment)))) 
+0

これは、リストの 'car'がアンバウンドシンボルである場合にエラーを発生させます。 (実際に移植可能な問題ではないのではないかと恐れています...) –

+0

私は見ていますが、ケースを考えてみましょう。(アプリケーション形式? '((λ(x)x)1))、確かに車の部分(lambda(x)x)は手続きですが、#f – FooBee

+0

と "procedure?"を含むすべての型述語を返します。 "ペア?" "リスト?"引数がunboundである場合にエラーを発生させます。私は、私たちのプロシージャは同じ振る舞いを持つべきだと私は考えます。 – FooBee

1

、この問題は、移植溶解しません。しかし、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))) 
関連する問題