[Scheme] Quoting

Literal representation

Scheme allows you to write lists as literals using quoting. Just as you can write a literal boolean or number in your program, you can write a literal list if you use the special form quote.

Quote is a special form, not a procedure, because it doesn't evaluate its argument in the usual way. (Its argument is really just a literal representation of a data structure, which may look like a Scheme expression, but it isn't.) For example, the expression (quote (1 2 3)) returns a pointer to a list (1 2 3), i.e., a sequence of cdr linked pairs whose car values are (pointers to) to 1, 2, and 3.

You can use quote expressions as subexpressions of other expressions, because they just return pointer values like anything else. For example, the expression (define foo (quote (1 2 3))) defines (and binds) a variable foo, and initializes its binding with (a pointer to) a three-element list.

We can draw the resulting situation this way:

    +---+    +---+---+      +---+---+      +---+---+ 
foo | *-+--->| * | *-+----->| * | *-+----->| * | * | 
    +---+    +-+-+---+      +-+-+---+      +-+-+---+ 
               |              |              | 
              \|/            \|/            \|/ 
               1              2              3

quote takes exactly one argument, and returns a data structure whose printed representation is the same as what you typed in as the argument to quote. Scheme does not evaluate the argument to quote as an expression--it just gives you a pointer to a data structure.

Note that quote does not generally construct a character string--it constructs a data structure that may be a list or tree or even an array. It's a very general quoting facility, much more powerful than the double quotes around character strings, which only construct string objects.

Scheme provides a cleaner way of writing quoted expressions, using the special single-quote character '. Rather than writing out (quote some-expression), you can just precede the quoted expression with the single-quote character. For example, we can write the same definition of foo as (define foo '(1 2 3)). You don't need a closing quote, because of Scheme's parenthesized prefix syntax--it can figure out where the quoted data structure ends.

Constantness

One subtlety about quote is that a quote expression doesn't create a data structure every time it's called--evaluating the same expression many times may return many pointers to the same structure.

Consider the procedure definition:

(define (foo) 
  '(1 2 3))

The list (1 2 3) may be created when we define the procedure foo, and each time we call it, it may return a pointer to that same list. (Exactly what happens depends on the particular implementation of Scheme, but most work this way, for efficiency reasons. Evaluating the quote expression just fetches a pointer to a data structure that was created beforehand.)

For this reason, it's an error to modify a data structure returned from a quote form. Unfortunately, many Scheme systems don't detect this error, and will let you do it.

If you want a new data structure each time, you should use a procedure like list, which always creates a new data structure. (list, which we'll discuss more later, is a standard Scheme procedure that takes any number of arguments, and creates a list of those items.)

For example, if we want the procedure foo to return a new list (1 2 3) every time, we can write:

(define (foo) 
  (list 1 2 3))

Homoiconicity

Programs often need to refer to literal data values--data that you type directly into the program. In many languages, the only literals are fairly simple values like integers and strings. In Scheme, you can use simple literals or complicated ones that represent (pointers to) data structures like nested lists. Earlier, I showed how to create list literals using quoting.

You've probably noticed that the syntax of Scheme code and the textual representation of Scheme data are very similar. So, for example, (min 1 2) is a combination if it's viewed as code, but it's also the standard textual representation of a list containing the symbol min and the integers 1 and 2.

(A symbol is a data object that's sort of like a string, but with some special properties, which will be explained in the next chapter.)

The resemblance between code and data is no accident, and it can be very convenient, as later examples will show. It can be confusing, too, however, so it's important to know when you're looking at a piece of code and when you're looking at a piece of literal data.

The first thing to understand is quoting. In Scheme, the expression (min 1 2) is a procedure call to min with the arguments 1 and 2. As I explained earlier, we can quote it by wrapping it in the special form (quote ...), however, and get a literal list (min 1 2).

For example, the definition:

(define foo 
  (quote (min 1 2)))

defines and binds foo, initializing the binding with (a pointer to) the list (min 1 2).

Of course, as I explained earlier, we can use ' as a euphemism for (quote ... ). We can define very complicated literals this way, if we want to. Here's a procedure that returns a nested list of nested lists of integers and booleans and symbols:

(define (fubar) 
  '(((1 two #f) (#t 3 four)) 
    ((five #f 6) (seven 8 #t)) 
    ((#f 9 10)) ((11 12 #f))))

that's a pretty useless procedure, but it's very convenient to just be able to type in printed representations of nested data structures and have Scheme construct them automatically for you. In most languages you'd have to do some fairly tedious hacking to construct a list like that.

As we'll see in a later chapter, Scheme also supports quasiquotation, which lets you construct mostly-literal data structures, and create customized variations on them easily; quasiquotation will be discussed in a later chapter.


Reference

An Introduction to Scheme and its Implementation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容