2

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?

Siva Charan
  • 17,940
  • 9
  • 60
  • 95
Wonger
  • 285
  • 6
  • 18

2 Answers2

4
(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))))
BenMorel
  • 34,448
  • 50
  • 182
  • 322
FooBee
  • 778
  • 7
  • 23
  • This raises an error in the case that the list's `car` is an unbound symbol. (I'm afraid that isn't actually a portably soluble problem, though...) – Matthias Benkard Mar 07 '12 at 10:07
  • I see, but,consider the case :(application-form? '((lambda (x) x) 1)) ,surely the car part (lambda (x) x) is a procedure,but it returns #f – FooBee Mar 07 '12 at 13:04
  • and all type predicates including "procedure?" "pair?" "list?" raises an error in the case that its argument is unbound.so I think our procedure should have the same behave. – FooBee Mar 07 '12 at 13:11
  • You're right, I hadn't thought about the case where the `car` of the form is a compound form itself. Well... I guess that which solution is preferable depends on the exact problem statement. In fact, there is something to be said in favor of just using `(define application-form? pair?)`. :) – Matthias Benkard Mar 07 '12 at 19:14
1

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)))
Matthias Benkard
  • 15,497
  • 4
  • 39
  • 47