Как узнать, является ли значение переменной символом, привязанным к процедуре на схеме?

Я знаком с Common Lisp и пытаюсь изучить некоторые схемы, поэтому я пытался понять, как я буду использовать Scheme для вещей, которые я обычно кодирую на Common Lisp.

В Common Lisp есть fboundp, который сообщает мне, привязан ли символ (значение переменной) к функции. Итак, я бы сделал это:

(let ((s (read)))
  (if (fboundp s)
      (apply (symbol-function s) args)
      (error ...)))

Возможно ли это в схеме? Я пытался найти это в спецификации R6RS, но ничего похожего не нашел.


person Jay    schedule 21.09.2009    source источник


Ответы (2)


Сюда?

  1. проверьте, если это символ
  2. оцените символ, используя EVAL, чтобы получить его значение
  3. проверьте, является ли результатом процедура с PROCEDURE?
person Rainer Joswig    schedule 21.09.2009
comment
ЭЙ, это работает! :-) И после сохранения результата в переменной p я могу просто использовать его как процедуру, как в (p ag1 arg2). Спасибо! - person Jay; 21.09.2009
comment
не работает в CL (SBCL), потому что вызов eval для несвязанного символа дает ошибку. В CL следует использовать boundp - person dbow; 05.08.2017
comment
@dbow в вопросе уже говорилось, что в Common Lisp вы используете boundp и fboundp; вопрос был в том, как это сделать в Scheme, и этот ответ прямо отвечает на него - person xdavidliu; 02.03.2018

В Scheme функции не привязаны к символам, как в Common Lisp. Если вам нужно знать, действительно ли значение является процедурой, вы можете использовать предикат procedure?:

(if (procedure? s) (do-something-with s) (do-something-else))

В переносимой Scheme нет прямого способа достичь того, что хочет сделать ваш примерный код, поскольку символы в Scheme представляют собой просто унифицированные строки, в которых отсутствуют слоты значений / функций / списков Common Lisp.

Вы можете попробовать что-то вроде:

(define function-table (list `(car ,car) `(cdr ,cdr) `(cons ,cons) `(display ,display)))

(let* ((s (read))
       (f (cond ((assq s function-table) => cadr)
                (else (error "undefined function")))))
    (apply f args))

т.е. определение вашего собственного отображения "хороших" функций. Это будет иметь то преимущество, что вы можете ограничить набор функций только «безопасными» или чем-то еще.

person Dirk    schedule 21.09.2009
comment
Это будет иметь то преимущество, что вы можете ограничить набор функций только безопасными или чем-то еще. - Хорошо, но на самом деле идея заключалась не в том, чтобы перечислить все функции. Напишите новый, и он будет доступен. В целях безопасности я могу гарантировать, что все вызываемые таким образом функции находятся в одном конкретном пакете. - person Jay; 21.09.2009
comment
@Dirk: Я имел в виду Common Lisp. Я полагаю, что в схеме это невозможно. - person Jay; 21.09.2009
comment
@Jay: В Scheme нет ничего похожего на пакеты. Модульная система (начиная с R6RS) совершенно другая (по сравнению с Common Lisp). - person Dirk; 21.09.2009