Cons in scheme explanation - scheme

(cons 1 2) gives us (1 . 2).
(cons 3 4) gives us (3 . 4).
So why does (cons (cons 1 2) (cons 3 4)) give us ((1 . 2) 3 . 4)?
Why isn't it ((1 . 2) (3 . 4))?

Well, it wouldn't be ((1 . 2) (3 . 4)) because that would be a list containing two elements, each a cons pair. I'm guessing what you meant was: why isn't it ((1 . 2) . (3 . 4))?
Well, actually the following two expressions are equivalent:
'((1 . 2) . (3 . 4))
'((1 . 2) 3 . 4)
This has to do with how Scheme's dotted notation works in tandem with its representation of proper lists. Remember that this:
'(1 . (2 . (3 . (4 . ()))))
...would simply be printed as this:
(1 2 3 4)
However, this:
'(1 . (2 . (3 . 4)))
...would be printed like this:
(1 2 3 . 4)
Note that Scheme tries to use the simplified list notation as long as it can—it only falls back to explicitly dotting things once it reaches a pair which doesn't have a pair or the empty list as its cdr element.
Therefore, in your original example, the second element of that cons pair is a pair, so Scheme uses the list notation. That lets it drop the second set of parentheses and the extra dot, yielding the result you encountered.

Related

in scheme what is the meaning of dot not on cons? why sometimes it is valid and sometime not

what is the meaning of dot, other than just cons notation?
dot as I know is just cons notation. so I don't understand the meaning here:
why:
> (equal? . 8)
Exception: invalid syntax (equal? . 8)
Type (debug) to enter the debugger.
but:
> (equal? . ((quote . ((a . (b . (c . ()))))) . ('(a b c))))
#t
what is the meaning of the dot here?
The syntax gets parsed and for a Scheme reader '(1 . (2 . ())) gets parsed and creates the same structure as '(1 2). Basically proper lists are singly linked lists where the last cdr points to the empty list.
(somefun . (5)) is the same as (somefun 5) for the reader. When the source code is turned in to a data structure, the interpreter won't know if you wrote the one or the other. Hovever (somefun . 5) doesn't get parsed to a function with one argument since the argument list itself is a number. the parser parsed it into a data structure, but your scheme implementation responsible to compile it or interpret it failed. You may use dotted list in data and some syntax like lambda for rest arguments, but it is very limited. Most of the time using dotted pairs in code fails.
A Scheme system will display structure only one way. eg. if you put in '(1 . (2 . ())) you will se (1 2) back since a dot with a list or empty list cdr gets special list visualization. If you do '(1 . (2 . 3)) it can start using the special rule since the cdr is a pair, but the next won't fly ending it up as (1 2 . 3). If you evaluate '(equal? . ((quote . ((a . (b . (c . ()))))) . ('(a b c)))) you get (equal? '(a b c) '(a b c)) back and that is because it is the simplest visualization of that structure. As code they read to the same structure and evaluate the same.
The most common problem when learning Scheme is to understand the list structure. Eg. how to create ((1 2) (3 4)) using cons and how to access the 4. If you knew it is really ((1 . (2 . ()) . ((3 . (4 . ())))) you see the 4 is after fllowing the cdr, car, cdr, then car or the simplified (cadadr '((1 2) (3 4))). The visualizer will just omit the dot and the extra set of parentheses in the cdr if it has them. eg. '((a) . (b)) will become ((a) b)

Behavior of "unquote" when used as the second to last symbol in a quasiquoted proper list

I am trying to produce the list (1 unquote 2) using quasiquote. I have tried this:
`(1 unquote 2)
However, in Racket, MIT Scheme and Chez Scheme, I get a dotted list: '(1 . 2).
So I tried this:
`(1 'unquote 2)
However, I get (1 'unquote 2).
I finally got the list I wanted using this technique:
`(1 unquote 2 ,((lambda (x) x) 'unquote) 2) ; Returns: '(1 unquote 2)
Why do I get a dotted list out of a quasiquoted proper list when unquote is the second to last element in the quasiquoted list?
Actually, it does not always produce a dotted list. For example:
`(1 unquote (list 2 3 4)) ; Returns: '(1 2 3 4)
Please explain this strange behavior of unquote when it is the second to last element in a quasiquoted list.
(a b c) is a shorthand for (a . (b . (c . ()))).
So (quasiquote (1 unquote 2)) is really (quasiquote (1 . (unquote 2))) which is '(1 . 2).
(Or if you want to fully expand it, (quasiquote (1 unquote 2)) is (quasiquote . ((1 . (unquote . (2 . ()))) . ())))
Similarly, (quasiquote (1 unquote (list 2 3 4))) is really (quasiquote (1 . (unquote (list 2 3 4)))) = (quasiquote (1 . (2 3 4))) = '(1 2 3 4).
By the way, an easier way to produce '(1 unquote 2) using quasiquote is:
`(1 ,'unquote 2)
According to R5RS,
Unpredictable behavior can result if any of the symbols quasiquote,
unquote, or unquote-splicing appear in positions within a <qq
template> otherwise than as described above.
And your positions are not "as described above" - the form must be (unquote expression ...).
It has been upgraded to a syntax violation in R6RS.
[writing an answer rather than a comment because it's impossible to format backticks properly in a comment. Lisp/Scheme still handles this better than markdown ;-) ]
As others have explained (esp. Sorawee), unquote (aka ,) is a special name that is treated specially when inside an quasiquoted list (aka the backtick). To prevent its special meaning, a simple workaround is to make sure the special name doesn't appear textually.
Note that unquote does not have a special meaning inside quote (by contrast to inside quasiquote).
Thus this will work in all variants of Scheme:
(define unquote-sym 'unquote) ; `unquote` is inside `quote`, so it's a mere symbol here
`(1 ,unquote-sym 2) ; '(1 unquote 2)

cons return a list and pair in scheme

I just started to learn scheme. My question is why does (cons 3 (4)) return a list (3 4) but (cons (4) 3) returns a pair ((4) . 3)? should (cons 3 (4)) returns (3 . (4)) as well?
Both (3 4) and (3. (4))are the list (cons 3 (cons 4 '()))), and if you enter '(3 . (4)) in your REPL, you will most likely see '(3 4) as the result.
The difference you're seeing is just an output convention; a pair where the cdr is a list is not printed with dot notation.

Can someone explain the difference between Cons and Append in scheme?

I read both of them and they seem to both construct a single list, what's their difference?
cons is the constructor for all pairs.
A proper list is () (the empty list, aka nil) or a pair where the cdr is a proper list. Any chain of pairs where the last one has () as it's cdr is a proper list (in addition to the empty list itself).
A dotted list is a pair that does not have a proper list as it's cdr. Thus a chain of pairs where the last cdr is not () matches this.
;; dotted lists
(cons 1 2) ; ==> (1 . 2)
(cons 1 (cons 2 3)) ; ==> (1 2 . 3) or (1 . (2 . 3))
;; proper lists
(cons 1 '()) ; ==> (1) or (1 . ())
(cons 1 (cons 2 '())) ; ==> (1 2) or (1 . (2 . ()))
append is a procedure that uses cons to make a list with all the elements of the argument lists left to right. A common implementation of append for just two lists would be:
(define (append lst tail)
(if (null? lst)
tail
(cons (car lst)
(append (cdr lst)
tail))))
append will fail if one of the arguments except the last is not a proper list. Tail and can be any value:
(append '(1 2 3) '(4 5)) ; ==> (1 2 3 4 5) or (1 . (2 . (3 . (4 . (5 . ())))))
(append '(1 2 3) '(4 5 . 6)) ; ==> (1 2 3 4 5 . 6) or (1 . (2 . (3 . (4 . (5 . 6)))))
(append '(1 2 3) #f) ; ==> (1 2 3 . #f) or (1 . (2 . (3 . #f)))
(append '(1 2 . 3) '(4 5 . 6)) ; ==> error `car` of number not allowed

Pairing pairs in racket

Using racket cons function I can pair two numbers into one pair for example (cons 1 2) would return a pair (1 . 2), but I can't use cons to make a pair of two pairs, (cons (cons 1 2) (cons 3 4)) returns ((1 . 2) 3 . 4), what I want is ((1 . 2) . (3 . 4))
How can I do such a thing ?
The two datums ((1 . 2) 3 . 4) and ((1 . 2) . (3 . 4)) are exactly the same. So don't worry, you've got it right.

Resources