В вашей программе 'xor
- это символ, а не процедура. В приведенной ниже программе xor
относится к реальной процедуре, а не является символом -
(apply (car (list xor)) (list #t #t))
; #f
(apply (car (list xor)) (list #t #f))
; #t
или просто -
(apply xor (list #t #f))
; #t
Когда вы пишете '(xor #t #t)
, xor
заключен в кавычки и превращен в символ -
(car '(xor #t #t))
; 'xor
Вы можете использовать квази-цитирование `(...)
, но чаще всего отменяете ,...
все, что не хотите преобразовывать в символ -
(apply (car `(,xor #t #t)) (cdr `(,xor #t #t)))
; #f
(apply (car `(,xor #t #f)) (cdr `(,xor #t #f)))
; #t
Предположительно s-выражения будут построены где-нибудь еще -
(define sexpr1 (list xor #t #t))
(define sexpr2 (list xor #t #f))
(apply (car sexpr1) (cdr sexpr1)) ;#f
(apply (car sexpr2) (cdr sexpr2)) ;#t
Если s-выражения содержат данные в чисто кавычках, вы можете eval выражение, используя пространство имен .
Мы добавляем racket/base
, чтобы разрешить применение процедуры. Процедура в вашей программе, xor
, включена в racket/bool
-
(define (run-sexpr sexpr)
(parameterize ((current-namespace (make-base-empty-namespace)))
(namespace-require 'racket/base)
(namespace-require 'racket/bool)
(eval sexpr)))
(run-sexpr '(xor #t #t)) ;#f
(run-sexpr '(xor #t #f)) ;#t
Выше мы eval
все s-выражение, но это может быть нежелательно. Чтобы программа работала, нам нужно всего лишь eval
, чтобы превратить символ 'xor
в значимую процедуру xor
. Возможно, это ближе всего к вашей первоначальной цели -
(define (run-sexpr sexpr)
(parameterize (...)
(...)
(apply (eval (car sexpr)) ;only eval car
(cdr sexpr)))) ;apply cdr verbatim
(run-sexpr '(xor #t #t)) ;#f
(run-sexpr '(xor #t #f)) ;#t