Wonger
Wonger

Reputation: 457

How to check if a symbol is a procedure or not

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

Answers (2)

FooBee
FooBee

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

Matthias Benkard
Matthias Benkard

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

Related Questions