操作对象

:: scheme

介绍一些对象上的操作,包括lists, numbers, characters, strings, vectors, bytevectors, symbols, booleans, hashtables, 以及 enumerations

常量和引用

语法 : constant

返回 : constant

constant 是可以自我解释的一些常量,例如数字,布尔值,字符,字符串或者二进制向量.常量是不可改变的

> 3.2

3.2

> #f

#f

> #\c

#\c

> "hi"

"hi"

> #(3 4 5)

'#(3 4 5)

语法 : (quote obj)

语法 : 'obj

返回 : obj

'obj 是等价于"(quote obj)"的。这种缩写会被scheme的reader自动转换为更长的形式。

qoute 禁止对于普通的obj进行解析,这使得obj可以像数据一样被使用。尽管所有的scheme的对象都可以被引用,但是对于常量的引用是没有必要的。比如,数字,布尔值,字符,字符串以及二进制向量。

被引用和自解析的常量是不可以被修改的。也就是说不可以通过"set-car!","string-set!"之类的操作修改一个常量。scheme的实现需要保证在这种操作试图运行的时候抛出异常。如果这种对于不可修改的常量的修改没有被侦测到,那么其后果是不确定的。scheme的实现可以在不同的常量之间共用存储来节省空间。

> (+ 2 3)

5

> '(+ 2 3)

'(+ 2 3)

> 'a

'a

> 'cons

'cons

> '()

'()

> '7

7

语法 : (quasiquote obj ...)

语法 : `obj

语法 : (unquote obj ...)

语法 : ,obj

语法 : (unquote-splicing obj ...)

语法 : ,@obj

返回 : 见下文

这六者之间是有一一对应的等价关系的。都会在scheme的reader中被转换。 quasiquotequote是非常类似的,除了它允许部分被引用的对象被去引用.在quasiquote中允许存在unquote以及unquote-splicing的子表达式被解析,但是其他所有的都还是被引用的(不会被求值) 每一个unquote的表达式都会被求值然后返回值作为unquote的中的值. 每一个unquote-splicing的子表达式的求值结果会和外面的list或者vector拼接起来. unquote以及unquote-splicing只可以在quasiquote中使用.

quasiquote有可能是嵌套的,每个quasiquote都会引入一层新的引用,然后每一层unquote以及unquote-splicing都会去掉一层引用. 所以一个被嵌套了n层的quasiquote表达式必须要去引用n次.

> `(+ 1 1)

'(+ 1 1)

> `(+ 2 ,(* 3 4))

'(+ 2 12)

> `(a b (,(+ 2 3) c) d)

'(a b (5 c) d)

> `(a b ,(reverse '(c d e)) f g)

'(a b (e d c) f g)

> (let ([a 1] [b 2])
    `(,a . ,b))

'(1 . 2)

> `(+ ,@(cdr '(* 2 3)))

'(+ 2 3)

> `(a b ,@(reverse '(c d e)) f g)

'(a b e d c f g)

> (let ([a 1] [b 2])
   `(,a ,@b))

'(1 . 2)

> `#(,@(list 1 2 3))

'#(1 2 3)

> '`,(cons 'a 'b)

'`,(cons 'a 'b)

> `',(cons 'a 'b)

''(a . b)

> `(a (unquote) b)

eval:1:0: unquote: expects exactly one expression

  at: (unquote)

  in: (quasiquote (a (unquote) b))

> `(a ,(+ 3 3)  b)

'(a 6 b)

> `(a (unquote (+ 3 3) (* 6 6)) b)

eval:3:0: unquote: expects exactly one expression

  at: (unquote (+ 3 3) (* 6 6))

  in: (quasiquote (a (unquote (+ 3 3) (* 6 6)) b))

> (let ([x '(m n)]) ``(a ,@,@x f))

eval:4:0: unquote-splicing: invalid context within

quasiquote

  at: (unquote-splicing x)

  in: (quasiquote (quasiquote (a (unquote-splicing

(unquote-splicing x)) f)))

> (let ([x '(m n)])
    (eval `(let ([m '(b c)] [n '(d e)]) `(a ,@,@x f))
         (make-base-namespace)))

eval:5:0: unquote-splicing: invalid context within

quasiquote

  at: (unquote-splicing x)

  in: (quasiquote (let ((m (quote (b c))) (n (quote (d e))))

(quasiquote (a (unquote-splicing (unquote-splicing x)) f))))

可以吧unquote和unquote-splicing当做quasiquote的辅助关键词. 在他们被视作辅助关键词的上下文环境中单独是一种语法错误