Apparent 'eval' of quote symbol in CLISP - lisp

Some output from the CLISP REPL:
[1]> (list 'list 1 2 3)
(LIST 1 2 3)
[2]> (list 'list '(1 2 3))
(LIST (1 2 3))
[3]> (list 'quote 1 2 3)
(QUOTE 1 2 3)
[4]> (list 'quote '(1 2 3))
'(1 2 3)
The first three, I understand exactly what's going on: The list function is passed a symbol ('list or 'quote) and so the result is a list that begins with the list or quote symbol. It's the fourth that confuses me. Why doesn't it return (QUOTE (1 2 3))?
I realise that if you enter (QUOTE '(1 2 3)) into the REPL, you get '(1 2 3) back, so the expression are equivalent in that sense. But (LIST 1 2 3) is equivalent to (1 2 3), and yet the first expression doesn't return that.
It seems inconsitent that (list 'quote 1 2 3) returns a list with the first item being a quote symbol, but (list 'quote (1 2 3)) returns a quoted list. Especially since expressions like (list 'list ...) seem to always return a list beginning with the symbol - so far, at least, quote is the only 'special case' like this.
It's not the easiest question to articulate, so I'm hoping I've managed to get my confusion across. Can anyone explain why quote gets treated in this seemingly-unique way?

'something is the same as (quote something) for the lisp reader. Even when nested it will be the case. The next expressions I will double quote so that after evaluation one of the quotes are still in there.
When printing the implementations can choose what to output where there are several possible representations, so some implementations would print the evaluation of ''something as
(quote something) while others may use the abbreviation 'something.
'(quote 1 2 3) cannot be abbreviated since a quoted form only has one argument. Thus here both lisp systems would print (quote 1 2 3).
Here is a way to look at your last expression:
(let ((data (list 'quote '(1 2 3))))
(format nil
"whole thing: ~a first element: ~a second-element: ~a"
data
(car data)
(cadr data)))
This will either evaluate to "whole thing: '(1 2 3) first element: QUOTE second-element: (1 2 3)" or "whole thing: (QUOTE (1 2 3)) first element: QUOTE second-element: (1 2 3)".
Since the printer never sees if the input is abbreviated and the data has the same structure in memory the output is never affected by how you input the data. Thus (quote (quote (1 2 3))) will print the same as ''(1 2 3).
You have the same behaviour with cons cells but the standard dictates how the rules are. (cons 1 (cons 2 (cons 3 '()))) would be (1 . (2 . (3 . ()))) but is actually just printed (1 2 3) However if you (cons 1 2) you get (1 . 2) showing that print treats the output differently based on the cdr. However the reader can read any of these and they will all print the same eg. '(1 . (2 . (3 . ()))) ==> (1 2 3) and (+ . (2 . ( 3 . ()))) ; ==> 5
Numbers can have as many visual forms as there are bases below the number in question.
(let ((*print-base* 16))
(print 255)) ; prints FF (255 in hexadecimal)
list does not have any abbreviation or specialness in Lisp. It's not even a primitive function but it's very helpful as it removes the inconvenience of having to cons by hand everytime. It can be defined like this:
(defun my-list (&rest lst)
lst)
(my-list 1 2 3 4) ; ==> (1 2 3 4)

Note that a REPL (the READ-EVAL-PRINT-LOOP) does three things:
reading using the function READ
evaluating using the function EVAL
and printing the result using something like the function PRINT
To understand what is going on you have to look at all three functions.
Let's look at the third form:
(list 'quote 1 2 3)
This is read as a list of five elements:
LIST
(QUOTE QUOTE)
1
2
3
EVAL then evaluates the arguments, and calls the function list with the four results and returns a new result, a list of four elements:
QUOTE
1
2
3
PRINT then takes this list and writes it as: (QUOTE 1 2 3). There is no abbreviated way to print it.
Let's look at the fourth form:
(list 'quote '(1 2 3))
This is read as a list of three elements:
LIST
(QUOTE QUOTE)
(QUOTE (1 2 3))
eval calls list with two arguments:
QUOTE
(1 2 3)
eval then returns a list of length two:
QUOTE
(1 2 3)
print now can print this list in two different ways:
(QUOTE (1 2 3)) or the abbreviated form '(1 2 3). Here a quote character is in front of a single expression.
Your implementation used the first version.

Related

cons two elements outputs the wrong result

#lang racket
I need to create a pair from an element and a list
however when I do (cons 2 (list 1 2 3)) I get (2 (1 2 3)), I want to get (2 . (1 2 3))
how do I get the dot in ?
Since (cons a b) is the same as (a . b) we get that (2 . (1 2 3)) is the same as (cons 2 (list 1 2 3) which is the same as (list 2 1 2 3). To confirm:
> (cons 2 (list 1 2 3))
'(2 1 2 3)
> '(2 . (1 2 3))
'(2 1 2 3)
Note that the printer prints (2 1 2 3) and not (2 . (1 2 3)). The printer attempts to use the dot only when absolutely needed.
There is a difference between the syntax that explains the structure, how it's stored and how display would represent it.
For a list of two elements there are two ways you can represent it (1) and (1 . ()). When this list is displayed it will always prefer the one with the least parentheses. Thus '(2 . (1 2 3)) will always be printed as (2 1 2 3) by display. If you don't want that you can make yourself a cons-write like:
;; displays cons always as dotted
(define (cons-write x)
(if (pair? x)
(begin
(display "(")
(cons-write (car x))
(display " . ") ; spaces are important
(cons-write (cdr x))
(display ")"))
(write x)))
(cons-write '(1 2 3 4)) ; prints (1 . (2 . (3 . (4 . ()))))

Whats the difference between '((1 2)(3 4)) and '('(1 2 )'(3 4)) in lisp?

The length of
(length (car '('(0)'(1 2 3)'(6 7))))
is being show 2 while the same
(length (car '((0)(1 2 3)(6 7))))
is correctly shown 1. so what does the the first expression actually represent?
The quote character ' is a reader macro. 'anything expands into (quote anything). So the first expression is shorthand for:
(length (car (quote ((quote (0))
(quote (1 2 3))
(quote (6 7)))
The first quote causes the parameter to be treated literally. That means that the quote expressions inside it are just lists that happen to begin with the symbol quote.
So the CAR of that list is the sub-list (quote (0)). It contains 2 elements: the symbol quote and the list (0).
CL-USER 8 > '((0)(1 2 3)(6 7))
((0)
(1 2 3)
(6 7))
CL-USER 9 > '('(0)'(1 2 3)'(6 7))
((QUOTE (0))
(QUOTE (1 2 3))
(QUOTE (6 7)))

List Item Evaluation

I'm learning lisp and have a question about a simple list:
(setq stuff '(one two three (+ 2 2)))
stuff ; prints "one two three (+ 2 2)"
(setq stuff (list `one `two `three (+ 2 2)))
stuff ; prints "one two three 4"
The first setq creates a list "one two three (+ 2 2)". The second list creates "one two three 4". Why does the first list not evaluate the (+ 2 2), but the second one does? I read in the Emacs Lisp intro documentation that when the list is built that it evaluates from the inside out. Why doesn't the first list evaluate the addition before adding it to the list?
This is elisp in emacs 24.
' is not equivalent to list, it's shorthand for quote. You're really doing this:
(setq stuff (quote (one two three (+ 2 2))))
The argument to quote is the expression (one two three (+ 2 2)).
From http://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html: "The special form quote returns its single argument, as written, without evaluating it".
Looks like you're coming to grips with the evaluation semantics of Lisp, so keep playing around!
You can think of quote as suppressing evaluation of its argument. This allows you to write expressions that you can manipulate or pass around. It is also used to write data structures that should not be evaluated as function calls.
Data structures:
'(1 2 3) ; => '(1 2 3)
(1 2 3) ; => Lisp error: (invalid-function 1)
;; The Lisp reader sees the number 1 in the function position and tries to call it, signalling an error.
Syntax transformations:
(setq x '(string-to-int "123"))
(setf (car x) 'string-to-list)
x ; => '(string-to-list "123")
Delayed evaluation:
(setq x '(message "Hello World")) ; => '(message "Hello World")
(eval x) ; => "Hello World"
There is a closely related special operator called syntax quote, written using the backtick. It allows you to evaluate individual forms in a quoted expression using the comma ( , ) operator. It is like quote with an escape hatch.
`(1 2 (+ 3 4)) ; => '(1 2 (+ 3 4))
`(1 2 ,(+ 3 4)) ; => '(1 2 7) ;; Note the comma!
Syntax quote also permits list splicing using the ,# syntax:
`(1 2 ,#(+ 3 4)) ; => '(1 2 + 3 4)
As you can see, it splices the subsequent expression into the containing one. You probably won't see it all that often until you start writing macros.
list on the other hand is a simple function. It evaluates its arguments, then returns a new data structure containing these items.
(list 1 2 (+ 3 4)) ; => '(1 2 7)

mcons in dr racket

I'm having trouble reading output from dr racket. By default it displays lists using mcons. For example, sicp exercise 2.32 produces:
> (subsets (list 1 2 3))
(mcons
(mcons
'()
(mcons
(mcons 3 '())
(mcons
(mcons 2 '())
(mcons
(mcons 2 (mcons 3 '()))
(mcons
(mcons 1 '())
(mcons
(mcons 1 (mcons 3 '()))
(mcons
(mcons 1 (mcons 2 '()))
(mcons (mcons 1 (mcons 2 (mcons 3 '()))) '()))))))))
'())
I'm having trouble reading this. Is there a way to make the output look like:
(() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))
Thanks!
Do you know what language are you using in your #lang line? The rest of the instructions below are assuming that you're using a #lang line.
If you are in #lang r5rs and you display or write the values, you should see the output you expect.
> (define p (list 1 2))
> (display p)
(1 2)
> (set-car! p 'one)
> (display p)
(one 2)
If you just type the values bare in Interactions, DrRacket will print them, and that uses the representation you're seeing. In DrRacket, you can customize the way that values print. Here's the process, step-by-step:
Go to the Language menu, and select Choose Language. You should see the language dialog pop up.
If the button on the lower left says Show Details, click it, and the dialog window should expand to include customizations.
Look for the Output Style option. There should be four choices: Constructor, Quasiquote, write, and print. Select write style, and then press Ok to confirm the customization.
Once you do this, then:
> (display (list 1 2))
(1 2)
> (write (list 1 2))
(1 2)
> (list 1 2)
{1 2}
It will still print slightly differently than you expect, using curly braces, because it's trying to notate that the list structure is mutable.
If this bothers you, we can fix that. Add the following line near the top of your program (but after the #lang line).
(#%require r5rs/init)
This line pulls in a Racket-specific module called r5rs/init that tries to improve r5rs compliance; in particular, the braces should finally print as round ones for mutable pairs.
> (display (list 1 2))
(1 2)
> (write (list 1 2))
(1 2)
> (list 1 2)
(1 2)

Scheme Macros - Pair in the transform but list as output?

Let's say I have the following macro in R5RS Scheme:
(define-syntax pair-test
(syntax-rules ()
((_ (a b . c))
(quote (a b . c)))))
The macro transforms an input pair to an output pair, as one would expect:
(pair-test (1 2 . 3))
==> (1 2 . 3)
I can also pass a list to the macro, as allowed by the spec. However, the output is a list instead of a pair:
(pair-test (1 2 3))
==> (1 2 3)
What exactly is going on here? Why is the output a list instead of a pair?
Could c be (3 . ()) in the second case? I'm not positive but that would make sense to me. And then quoting (a b . c) would be (1 2 . (3 . ())) which is (1 2 . (3)) and (3) is a proper list, so (1 2 3)?
To see what's happening here, you need to know that a list in Scheme is a recursive chain of pairs of elements and other lists. Any data that follows the form of a list will always be printed as a list. Once you know how basic lists are constructed, you'll be able to see what's happening inside your macro.
Pairs in Scheme can be created using the . operator, or using the cons function. Here's a simple pair of numbers:
(quote (1 . 2))
==> '(1 . 2)
(cons 1 2)
==> '(1 . 2)
To create a list of 1 in Scheme, you can make a pair out of something and the empty list:
(quote (1 . ()))
==> '(1)
(cons 1 (list))
==> '(1)
A list of 2 is a pair of something of something on the left side, and a list of 1 on the right side. Likewise, a list of 3 is one element paired with a list of 2:
(quote (1 . (2 . (3 . ()))))
==> '(1 2 3)
(cons 1 (cons 2 (cons 3 (list))))
==> '(1 2 3)
To see what your macro is doing, you can rearrange the (quote (a b . c)) to be more explicit:
(quote (a . (b . c)))
(cons (quote a) (cons (quote b) (quote c)))
Now you can see that this form looks very similar to when you're constructing a list. If (quote c) results in a list, then the whole expression will be a list. In the case of (pair-test (1 2 3)), c becomes (3 . ()):
(quote (a . (b . c)))
==> (quote (1 . (2 . (3 . ()))))
==> '(1 2 3)
(cons (quote a) (cons (quote b) (quote c)))
==> (cons '1 (cons '2 '(3 . ())))
==> '(1 2 3)
This value is printed by the REPL as a list because it is a "proper list". Each right side (cdr) is a list, all the way up to the empty list at the end, so this value perfectly follows list form. The REPL assumes you'd like to see the result as a list, so it gets printed without a . present.
You'd see '(1 2 . 3) for (pair-test (1 2 . 3)), because this is how the REPL prints "improper lists". If the last element in the chain of pairs is not the empty list, the value is considered an "improper list", and will be printed differently:
(quote (1 . (2 . 3)))
==> '(1 2 . 3)
(cons 1 (cons 2 3))
==> '(1 2 . 3)