Scheme: When I cons two atoms I am getting a dot in the middle. Why?

1.4k Views Asked by At

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.

3

There are 3 best solutions below

5
Óscar López On BEST ANSWER

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.

0
Kyuvi On

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.

~

0
Sylwester On

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.