The behavior of quote
is specified in R6RS, appendix A.3. For '1
, the relevant rule is 6sqv:
(store (sf1 ...) S1[ 'sqv1 ]) → (store (sf1 ...) S1[ sqv1 ])
Time to break this down.
The "S → T" notation defines one step in evaluating a term, where "S" evaluates to "T".
Since store
and the sf1
non-terminals appear the same on both the left and right sides, you don't need to understand them to understand how '1
evaluates. If you need something, think of store
as "storage environment" and the sfn
as pairs of names and values; (store ((x 1) (y 2)) S)
means the identifier x
is associated with the value 1
and y
with 2
when evaluating the term S
.
If you're not familiar with the S[e]
notation, it refers to a term with one "hole" (an term with a []
in it) filled with e
. There are two related syntax elements: terms with holes (S[]
) and terms with a hole filled by a value (S[e]
). Holes are a little (but only a little) like unnamed variables. One important difference is that a term is allowed only one hole. Holes are perhaps best explained by example. All of the following are S[]
:
Note that a hole can only appear where a sub-term is syntactically valid; [] 2)
is not a term-with-hole. S[0]
would be a term with 0
substituted into the hole:
(+ 0 1 2)
(list 0 'a "foo")
(cond ((= x 0) 0)
((> x 0) 1)
(else -1))
When a value is given for a hole, the term S[]
is also called a "context". This comes from one of the primary uses for terms-with-holes: to match any term containing the given value. S[e]
is any term that contains e
as a valid sub-term, so S[]
is the context that e
appears in. In short, S1['sqv1]
is a stand-in for any term that contains a quote.
Note the second term provides two different contexts for quote-terms: (list [] 'a "foo")
, (list 'bar [] "foo")
. This suggests that you shouldn't think of holes too much as just being unnamed variables.
If you're wonder why context terms and holes are used, they're an alternative to recursive definitions. Without contexts, → would have to be defined recursively over the structure of terms (Scheme's grammar defines the structure). Substitution in lambda calculus is an example of structural recursion, as are any tree-processing functions you might define in Scheme (though Scheme syntax is quite different than the syntax used to define → and lambda calculus substitution).
(define (tree-depth tree)
(if (pair? tree)
(max (tree-depth (car tree))
(tree-depth (cdr tree)))
1
) )
Next, let's examine the meaning of sqv
, which is short for "self-quoting values". This is a non-terminal from the Scheme grammar, given in appendix A.2.
sqv ::= n | #t | #f
n ::= [numbers]
sqv is simply a number or boolean.
All together, the 6sqv evaluation rule means that a quoted number or boolean evaluates to the number or boolean; the quote is simply discarded.
What this signifies for your homework is that you can't tell the difference between 1
and '1
with a normal function, since sub-terms are evaluated before the function is called. You'll need a macro.
Why go through all this just to say that "'1
evaluates to 1
"? Firstly, answering "why" takes more than answering "what". Also, it will hopefully help you go beyond the question, learning a little bit how to read Scheme's formal semantics, give you a taste of computational theory concepts and lead to many more questions.