了解方案中的符号

时间:2018-11-09 19:42:35

标签: scheme

您能帮助我理解为什么以下表达式的值中包含7个符号(包括重复项)吗?

​'('a ',(string->symbol "b") 'c))

2 个答案:

答案 0 :(得分:1)

您可以编写一个检查元素是否为符号的函数。
为了清楚起见,将元素与其“符号”配对:

(define (sym-check ls)
  (cond ((null? ls) '())
        ((not (pair? ls)) (cons ls (symbol? ls)))
        ((pair? (car ls)) (cons (map sym-check (car ls)) (sym-check (cdr ls))))
        (else (cons (sym-check (car ls)) (sym-check (cdr ls))))))

> (sym-check '('a ',(string->symbol "b") 'c))
'(((quote . #t) (a . #t)) ((quote . #t) 
                           ((unquote . #t) 
                            ((string->symbol . #t) ("b" . #f)))) 
                          ((quote . #t) (c . #t)))

您将得到七个#t
请注意,',是符号quoteunquote的“简写”,

> (quote (unquote (string->symbol "b")))
',(string->symbol "b")

和使用list而不是引用给出的结果截然不同:

> (sym-check (list 'a ',(string->symbol "b") 'c))
'((a . #t) ((unquote . #t) ((string->symbol . #t) ("b" . #f))) (c . #t))

这与将引用排除在引用列表之外是相同的:

> (sym-check '(a ,(string->symbol "b") c))
'((a . #t) ((unquote . #t) ((string->symbol . #t) ("b" . #f))) (c . #t))

答案 1 :(得分:1)

{'('a ',(string->symbol "b") 'c))的计算结果如下:

((quote a) 
 (quote (unquote (string->symbol "b"))) 
 (quote c))

我可以数7,是的。评估引用表达式的结果是7个符号。

方案系统具有一个读取器,该读取器将'x转换为(quote x),并且,`,@对应于带有quasiquote的表单, unquoteunquote-splicing。这意味着代码`(a b c ,d e f)变为(quasiquote (a b c (unquote d) e f))。然后,实现中的macos将其转换为(list* 'a 'b 'c d '(e f))或执行相同操作的类似表达式。但是,使用'`(a b c ,d e f)只是成为值(quasiquote (a b c (unquote d) e f)),因为这是被引用的表达式。 Scheme无法扩展为普通的引号表达式。

通常在引用的基准中引用字符是一个错误。初学者不了解目的,因此无处不在。但是实际上您只需要使用外部引号即可。 (+ 4 5)9,而'(+ 4 5)(+ 4 5)。看到区别了吗?