Bbit
Bbit

Reputation: 442

Beginner Scheme list print

I am using DrRacket to learn Scheme, The language subset is racket (#lang racket). I have the following list/expression:

(cons (cons (cons 'a 'b) (cons 'c 'd)) (cons (cons 'e 'f) (cons 'g 'h)))

When I press enter I get the following value printed out:

'(((a . b) c . d) (e . f) g . h)

I would expect the result to be:

'((( a . b) (c . d)) ((e . f) ( g . h)))

Can anyone explain what rules scheme uses to decide to print the value the way it does?

Attached is also a screen of the terminal:

enter image description here

Upvotes: 1

Views: 310

Answers (2)

Renzo
Renzo

Reputation: 27414

The result of your expression is:

'((( a . b) . (c . d)) . ((e . f) . ( g . h)))

and not

'((( a . b) (c . d)) ((e . f) ( g . h)))

as you are expecting.

However it is not printed in that way, for the rules of printing of lisp languages. See for instance this page (it is for Common Lisp, but the printing rules are the same for Scheme):

Notice that LISP prints linked lists a special way: it omits some of the periods and parentheses. The rule is: if the cdr of a cons is nil, LISP doesn't bother to print the period or the nil; and if the cdr of cons A is cons B, then LISP doesn't bother to print the period for cons A or the parentheses for cons B. So:

(cons 4 nil)

(4)

(cons 4 (cons 5 6))

(4 5 . 6)

(cons 4 (cons 5 (cons 6 nil)))

(4 5 6)

Upvotes: 2

rsm
rsm

Reputation: 2560

cons creates a pair, which is also a list. So, when you later cons something else to a list, you extend this list.

(cons 'a 'b)
==> (a . b)

(cons 'c '(a . b))
==> (c a . b)

(cons 'd '(c a . b))
==> (d c a . b)

And this is what happens when you cons new pair to another pair/list:

(cons 'something '(c . d))
==> (something c . d)

(cons '(a . b) (c . d))
==> ((a . b) c . d)

Sometimes it's helpful to draw pairs as boxes to see what is going on:

(cons 'a 'b)        (cons 'c 'd)
+---+---+          +---+---+
|   |   |--- b     |   |   |--- d
+---+---+          +---+---+
  |                  |
  a                  c

(cons (cons 'a 'b) (cons 'c 'd))
+---+---+    +---+---+
|   |   |--- |   |   |--- d
+---+---+    +---+---+
  |            |
  |            c
+---+---+
|   |   |--- b
+---+---+
  |
  a

To get ((a . b) (c . d)) you have to:

(cons (cons 'a 'b) (cons (cons 'c 'd) '()))
==> ((a . b) (c . d))

+---+---+        +---+---+
|   |   |------- |   |   |--- NIL/()
+---+---+        +---+---+
  |                |
  |                |
+---+---+        +---+---+
|   |   |--- b   |   |   |--- d
+---+---+        +---+---+
  |                |
  a                c

Upvotes: 3

Related Questions