2012-03-07 41 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)) 
;=>+ 

我不认为你在这里需要一个宏,一个函数就足够了。 抽象发挥功能:

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

如果列表的“car”是未绑定的符号,则会引发错误。 (我恐怕这实际上不是一个可移植的问题,尽管...) – 2012-03-07 10:07:33

+0

我明白了,但是,考虑一下情况:(application-form?'((lambda(x)x)1)),当然是汽车部分(lambda(x)x)是一个过程,但它返回#f – FooBee 2012-03-07 13:04:44

+0

和所有类型的谓词包括“过程?” “对?” “名单?”在其参数未被绑定的情况下产生错误。因此,我认为我们的过程应该具有相同的行为。 – FooBee 2012-03-07 13:11:36

1

如果列表的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))) 
相关问题