Схема для начинающих распечатать список - PullRequest
1 голос
/ 30 сентября 2019

Я использую DrRacket для изучения Scheme. Подмножество языков - ракетка (#lang racket). У меня есть следующий список / выражение:

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

Когда я нажимаю клавишу ввода, я получаю следующее значение:

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

Я ожидаю, что результатбыть:

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

Кто-нибудь может объяснить, какая схема правил используется для принятия решения о печати значения, как это происходит?

Прилагается также экран терминала:

enter image description here

Ответы [ 2 ]

3 голосов
/ 30 сентября 2019

cons создает пару, которая также является списком. Итак, когда вы позже cons что-то еще добавляете в список, вы расширяете этот список.

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

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

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

И это то, что происходит, когда вы cons новая пара для другой пары / списка:

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

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

Иногда полезно нарисовать пары в виде блоков, чтобы увидеть, что происходит:

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

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

Чтобы получить ((a . b) (c . d)), вам необходимо:

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

+---+---+        +---+---+
|   |   |------- |   |   |--- NIL/()
+---+---+        +---+---+
  |                |
  |                |
+---+---+        +---+---+
|   |   |--- b   |   |   |--- d
+---+---+        +---+---+
  |                |
  a                c
2 голосов
/ 30 сентября 2019

Результат вашего выражения:

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

, а не

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

, как вы ожидаете.

Однако это не печатается таким образом,по правилам печати языков лисп. Смотрите, например, эту страницу (это для Common Lisp, но правила печати те же для Схемы):

Обратите внимание, что LISP печатает связанные списки особым образом: он пропускаетнекоторые периоды и скобки. Правило таково: если cdr минуса равен нулю, LISP не потрудится напечатать точку или ноль;и если cdr для cons A равен cons B, то LISP не печатает период для cons A или круглые скобки для cons B. Итак:

(cons 4 nil)

(4)

(минусы 4 (минусы 5 6))

(4 5,6)

(минусы 4 (минусы 5 (минусы 6 ноль)))

(4 5 6)

...