Reputation: 457
Im trying to write a macro that checks a list to see if there is a procedure call, but im not quite sure how to go about it. The first thing that comes to my head is to use the procedure? function to check, but it doesnt work. An example of what im trying to do is the following:
(procedure? (car '(+ 1 2)))
now, car of that list returns +
, but the function still returns false
.
Is there a way to check whether the car of a list is a procedure or not?
Upvotes: 2
Views: 3009
Reputation: 798
(car '(+ 1 2)) => '+ not +
+ is a procedure ,but '+ is just a symbol!
you should check an unquoted variable:
(procedure? (car (list + 1 2))); => #t
;or
(procedure? (car `(,+ 1 2))); =>#t
if the list is of the form '(a b c d),you can check in this way:
(procedure? (eval (car '(+ 1 2)) (interaction-environment)));=>#t
because:
(eval (car '(+ 1 2)) (interaction-environment))
;=>(eval '+ (interaction-environment))
;=>+
I don't think you need a macro here,a function is enough. abstract that function:
(define (application-form? lst)
(procedure? (eval (car lst) (interaction-environment))))
Upvotes: 4
Reputation: 15769
If the car
of the list is permitted to be an unbound symbol, this problem isn't portably soluble. You can, however, solve it in 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)))
Upvotes: 1