What happened in scheme when defining a symbol to be something else?

Viewed 92

I'm a beginner of the Scheme language.

Recently I found that the data type symbol can be displayed using quote, like this:

> 'E
E
> (quote E)
E

However, if the code below executed, every kind of quote may fail:

> (define 'E 123)
> 'E
E: undefined;
 cannot reference an identifier before its definition
> 'abc
abc: undefined;
 cannot reference an identifier before its definition

So what happend when code (define 'E 123) being executed?

2 Answers

First you asked Scheme to evaluate (define 'E 123). Let's put a quote in front of that, to see what it looks like without the ' shorthand. You can always do this: quote any expression to ask Scheme, "What do you think this value is?"

 > '(define 'E 123)
=> (define (quote E) 123)

Well, in Scheme, (define (x ...) ...) is a shorthand for (define x (lambda (...) ...)): it's just a convenient shorthand for defining a function. So in this case (define (quote E) 123) is the same as (define quote (lambda (E) 123)). Thus, the symbol you are redefining is quote, and you define it to be a function of one parameter which always returns 123.

Next you asked to evaluate 'E. Again let's expand that to look through the shorthand:

 > ''E
=> (quote E)

You now call the quote function you defined, and pass it the variable E as an argument. But E has not previously been defined, so this fails. If you wanted to, you could first define E to have any value, and then perhaps 'E would return 123. It rather depends on what Scheme evaluator you are using: the one I found does not much appreciate it when you try to redefine quote, but apparently yours does not mind, so I suspect you would get 123, and that you would get the same result if you defined abc and then evaluated 'abc.

in general (define name ...) is converted in (bind name) at the beginning of the scope and in the place where define appears, it is executed (set! name ...). You need to define a symbol, not a (quote name). Because define is a special form, the rules of evaluation are particular, not general application -- define is not a function call.

Related