Как проверить, является ли символ процедурой или нет - PullRequest
2 голосов
/ 07 марта 2012

Я пытаюсь написать макрос, который проверяет список, чтобы увидеть, есть ли вызов процедуры, но я не совсем уверен, как это сделать. Первое, что приходит мне в голову, это использовать процедуру? функцию для проверки, но она не работает. Пример того, что я пытаюсь сделать, это следующее:

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

сейчас, car из этого списка возвращает +, но функция по-прежнему возвращает false.

Есть ли способ проверить, является ли автомобиль списка процедурой или нет?

Ответы [ 2 ]

3 голосов
/ 07 марта 2012
(car '(+ 1 2)) => '+ not +

+ - это процедура, но '+ - это просто символ!

вы должны проверить переменную без кавычек:

(procedure? (car (list + 1 2))); => #t
;or
(procedure? (car `(,+ 1 2))); =>#t

если список имеет форму '(a b c d), вы можете проверить это следующим образом:

(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))))
1 голос
/ 07 марта 2012

Если 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)))
...