4

The quote (') is used to introduce a pre-evaluated value, so (quote x) results in the symbol x and not what the symbol evalutes to.

Numbers, Booleans, characters and strings are self-evaluating in Scheme, so quoting them doesn't matter.

But why does (quote (1 2 3)) or (quote ()) answers #t to the predicate list?.

Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list 1 2 3)?

Thank you.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Shuzheng
  • 11,288
  • 20
  • 88
  • 186
  • 1
    The answer to [What is the difference between quote and list?](https://stackoverflow.com/questions/34984552/what-is-the-difference-between-quote-and-list) contains some good explanations of what `quote` means and how it relates to `list` – Alex Knauth Sep 01 '16 at 12:28

3 Answers3

3

pre-evaluated value

I'm not sure where you got that term from. I've never used it. It's not "pre-evaluated", it's unevaluated.

This is really all works from the fact Lisp (and Scheme) is Homoiconic: the structure of the program really uses lists and atoms underneath.

quote is the dual to eval: (eval (list '+ '1 '2 '3)) (and since a quoted number is just the number, (eval (list '+ 1 2 3)) does it as well) is the opposite of (quote '(+ 1 2 3)).

An evaluated list is a call, so an unevaluated call is a list.

Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list? 1 2 3)?

You're missing some parentheses here! You get (list? '(1 2 3)) (or (list? (quote (1 2 3)). That is, (list? (list 1 2 3)). Which is true.

You can check the opposite with (eval (list '+ 1 2 3)): you get 6.

Note: Some values just evaluate to themselves (like numbers or functions. You can throw eval at it as many times as you want, and it won't change a thing: (eval (eval (eval 1))) is just 1.)

Ven
  • 19,015
  • 2
  • 41
  • 61
  • Edited: It should be list and not list?. – Shuzheng Sep 01 '16 at 09:02
  • (eval (list + 1 2 3)) returns an error in my Scheme: "Exception: invalid syntax #" – Shuzheng Sep 01 '16 at 09:05
  • you might want `(list '+ 1 2 3)`. Sorry, I only had racket installed. – Ven Sep 01 '16 at 09:18
  • Well, I just tried with Chicken Scheme, and `(eval (list + 1 2 3))` works fine. – Ven Sep 01 '16 at 09:20
  • Thanks, I use Petite Scheme, but lets ignore the implementation details :-) – Shuzheng Sep 01 '16 at 09:20
  • Right. Does this seem to make sense? – Ven Sep 01 '16 at 09:22
  • Is (eval ..) the same thing as entering an expression at the interpreter prompt? – Shuzheng Sep 01 '16 at 09:23
  • 1
    Let's say each `eval` removes a level of `quote`. `quote` is an "evaluation barrier", `eval` is an evaluator. – Ven Sep 01 '16 at 09:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122378/discussion-between-ven-and-nlykkei). – Ven Sep 01 '16 at 09:27
  • 1
    Thank you, Ven. I think I understand it. – Shuzheng Sep 01 '16 at 09:36
  • I think you should remove the ' from "quote is the dual to eval: (eval (list + 1 2 3)) is the opposite of (quote '(+ 1 2 3))." - there should not be double quote right? – Shuzheng Sep 01 '16 at 12:06
  • `(eval (list + 1 2 3))` should be `(eval '(+ 1 2 3))` or `(eval (list '+ '1 '2 '3))` since how it's now `+` gets evaluated twice. – Sylwester Sep 01 '16 at 12:14
  • @Sylwester Right. Racket doesn't care, but it seems Chicken scheme does. – Ven Sep 01 '16 at 12:22
  • @Ven that means rackets procedures are self evaluating, but thats not a portable feature since the reports don't demand this. It's also like some schemes return the value in `display` or perhaps choosing `#f` as the default in `cond` when no `else` is specified. All of them are ok since the spec doesn't specify these. – Sylwester Sep 01 '16 at 12:27
  • @Sylwester answer was edited! Thank you for the clarification. – Ven Sep 01 '16 at 12:30
2

(quote (+ 1 2 3)) = '(+ 1 2 3) = (list '+ '1 '2 '3) = (list '+ 1 2 3) (numbers are self-evaluating, i.e. evaluating to self).

(eval '(+ 1 2 3)) = (+ 1 2 3) = 6. And (eval '(1 2 3)) = (1 2 3) = error.

The first identity is just syntactical. The central identity here is the second one, '(+ 1 2 3) = (list '+ '1 '2 '3). It holds because everything is evaluated in Lisp, but before that, it must be read. Which means, converted from textual source code to actual data structures.

Since ( ... ) parentheses denote lists, reading ( ... ) forms creates lists. Then, evaluating the quoted form just returns that form as is (i.e. non-evaluated). The token + gets read as a symbol +; the literals 1, 2, 3 get read as numbers 1, 2, 3. So the end result is the same as the result of evaluating the form (list '+ '1 '2 '3).

And of course all this still applies without the + inside, as well.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
0

The quote introduces an unevaluated value, not pre-evaluated, whatever that means.

When the expression (quote X) is treated as a form to be evaluated, it simply evaluates to X itself. X is not treated as a form to be evaluated to a value, but rather the resulting value is the syntax X itself.

Quote is a way of the program expressing, "I want to use a piece of my own syntax as a value". And that's precisely what a "literal" is in computer science: a piece of program text reflected back into the program as a run-time value.

In Lisp, atoms other than symbols denote themselves when evaluated. The syntax 3 evaluates to the integer 3. They are the same thing: Lisp syntax is a data structure, and in that data structure, an integer literal 3 is already represented by the object that it denotes.

Thus, under evaluation, there is no difference between (quote 3) and just 3. "Give me the syntax 3 itself" and "give me the value of the syntax 3" are the same: just 3.

Under (quote (1 2 3)), the syntax being quoted is (1 2 3). That syntax is the list object that it looks like; quote just regurgitates it. If were to evaluate the (1 2 3) form, it would be an error: it looks like 1 is being used as an operator or function, with arguments 2 and 3. When quote is itself evaluated, it suppresses this evaluation and just yields the (1 2 3) as-is.

Because the (1 2 3) is a piece of the program syntax, however, there is a restriction in the language that this list may not be modified. An operation like (inc (car (quote (1 2 3)))) which tries to change the list to (2 2 3) invokes undefined behavior. Essentially, the program is trying to modify its own syntax; if for a moment we disregard the additional complexity that Lisp is a compiled language, this is de facto self-modifying code.

Kaz
  • 55,781
  • 9
  • 100
  • 149