3

When I do a cons on two atoms, I am getting a . in between.

1]=>(cons 'one 'two)
;Value 1: (one . two)

Why I am getting the . operator. Does it have any meaning? I am using mit-scheme.

I have seen this stackoverflow link but not clear.

UPDATE: The definition of cons in Little Schemer states that, cons takes two arguments, the first one is any S-expression and the second one is any list.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Sreekumar R
  • 573
  • 6
  • 24
  • The `dot` is the normal syntax of pair literals in Scheme. The dot is just omitted, if the cdr of the pair is a list. – ceving Jul 10 '20 at 09:35
  • the Little books are a _little_ confusing for total newcomers. they are aimed at those who already know the language's basics, I think. – Will Ness Jul 11 '20 at 14:55
  • 1
    ``(cons 1 2) = '(1 . 2)`` ---- ``(cons 1 '()) = '(1 . ()) = '(1)`` ---- ``(cons 1 (cons 2 3)) = '(1 . (2 . 3)) = '(1 2 . 3)`` ---- ``(cons 1 (cons 2 '())) = '(1 . (2 . '())) = '(1 . (2)) = '(1 2) = '(1 2 . ())`` ---- ``(cons 1 (cons 2 (cons 3 4))) = '(1 . (2 . (3 . 4))) = '(1 2 3 . 4)`` ---- ``(cons 1 (cons 2 (cons 3 '()))) = '(1 . (2 . (3 . ()))) = '(1 . (2 . (3))) = '(1 . (2 3)) = '(1 2 3) = '(1 2 3 . ())`` . – Will Ness Jul 11 '20 at 15:12
  • 1
    That's a "commandment" that's only true within the confines of that book. As a footnote on page 8 says, "In practice, (cons α β) works for all values α and β". – molbdnilo Jul 15 '20 at 14:27

3 Answers3

2

The procedure cons creates a "cons cell" pointing to the two arguments provided.

A cons cell is a pair of pointers and a list is a single cons cell or a series of cons cells whose second pointer points to another cons cell, and the second pointer of the last cell points to another object .

Note: I use the word "object" for simplicity not in the programming sense.

In a proper list the second pointer of the last cons cell points to an empty list.

In an improper list the second pointer of the last cons cell points to an object that is not an empty list.

Note2: an "empty list" () is a unique value in scheme and is different from a list, In common lisp it is equal to nil, Nil does not exist in scheme.

+-----+-----+
|     |     |
|     |     |
+--+--+--+--+
   |     |
   |     |
   v     v
  obj   obj

A cons cell

+-----+-----+     +-----+-----+     +-----+-----+
|     |     +---->+     |     +---->+     |     |
|     |     |     |     |     |     |     |     |
+--+--+-----+     +--+--+-----+     +--+--+--+--+
   |                 |                 |     |
   |                 |                 |     |
   v                 v                 v     v
   0                 1                 2     3

(0 1 2 . 3) -> (0 . (1 . (2 . 3)))    

An improper list

+-----+-----+     +-----+-----+     +-----+-----+
|     |     +---->+     |     +---->+     |     +----> ()/nil
|     |     |     |     |     |     |     |     |
+--+--+-----+     +--+--+-----+     +--+--+-----+
   |                 |                 |
   |                 |                 |
   v                 v                 v
   0                 1                 2


(0 1 2) -> (0 . (1 . (2 . () )    

A proper list

The dot (when seen in the repl) is used to signify that the final pointer of the list points to an object that is not an empty list and it is therefore an improper list.

This is my understanding at least from common lisp though I am sure it translates to most other lisps (I think Clojure is different (if you consider it a lisp that is)).

Wikipedia page on cons.

~

Kyuvi
  • 360
  • 3
  • 13
1

The dot is just the way Scheme displays a cons cell when the cdr part is not itself a cons cell or the empty list. The dot is not an operator in this case, for example:

(cons 1 2)
=> '(1 . 2) ; a cons pair, a.k.a. a cons cell

(cons 1 (cons 2 3))
=> '(1 2 . 3) ; not a proper list, it doesn't end in '()

If the cdr part is a cons cell or the empty list '(), then we have a list:

(cons 1 '())
=> '(1) ; a proper list, ends in '()

(cons 1 (cons 2 '()))
=> '(1 2) ; a proper list, ends in '()

The definition in The Little Schemer is a simplification, in reality cons can take any type of value for each one of its arguments. By convention if the second argument is a list it'll be considered a list and displayed as such, otherwise it's a plain old cons cell and the dot is there to remind you of this.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • 1
    I am new to **cons cell** and **improper list**. Could you clarify? – Sreekumar R Jul 10 '20 at 11:10
  • Sure! a `cons` cell is the object that's returned when you call `cons`, think of it as a container with two positions. An improper list is a list which doesn't end in the empty list, I provided an example in my answer: `(cons 1 (cons 2 3))`. – Óscar López Jul 10 '20 at 11:14
  • In **Dr. Racket** `(cdr (cdr (cons 1 (cons 2 3))))` is giving 3 and `(cdr (cdr (cdr (cons 1 (cons 2 3)))))` is giving an error of contract violation. It is expecting a pair? but getting 3. I am totally confused. – Sreekumar R Jul 10 '20 at 13:43
  • 1
    Of course, because 3 is not a cons cell, you can't go any further, you've reached the end of the structure. I recommend you read more about `cons` and lists in the wonderful book, "Structure and Interpretation of Computer Languages". Play around with `cons`, `car` and `cdr` until you get the hang of it. – Óscar López Jul 10 '20 at 13:45
  • Thanks!. I am reading it. In fact, I am reading 3 books at a time. That may be the reason. – Sreekumar R Jul 10 '20 at 13:46
1

The little Schemer is lying. cons can take any type as its first and second argument. You can always create a pair with quoted structures like '(1 . 8).

There is no data structure specifically to make lists so Scheme has a trick. They define a list as either the empty list or a cons that has a list as its cdr. Thus '(1 . (2 . (3 . ()))) is a list and if you evaluate it Scheme repl will print (1 2 3) back. If you evaluate '(1 2 3) the reader will turn the input code into '(1 . (2 . (3 . ()))) before the Scheme interpreter gets to evaluate it. A list that ends with '() is called a proper list since it has no dots between the last two elements. eg. '(1 . (2 . (3 . 4))) ; ==> (1 2 3 . 4)

If you give the second argument a proper list is the result always a proper list and you'll not see any dots.

Sylwester
  • 47,942
  • 4
  • 47
  • 79