2012-01-23 4 views
2

Scheme имеет установленный автомобиль! и set-cdr !, но никаких ограничений! ,Есть выражения, такие как (set! C (cons 3 c)) способ добавления элемента в список?

ли такие выражения, как

(комплект! С (против 3 с))

, который помещает элемент 3 в списке с, собственно/только/лучшим/обычным способом изменить список?

+0

«cons - это процедура создания пары»: язык программирования схемы, 3-е изд., Стр. 133. http://www.scheme.com/tspl3/objects.html#./objects:h1 – drb

ответ

1

Это правильный способ изменения списка c. Но такое использование редко. Возможно, вы могли бы рассказать нам больше о том, что вы пытаетесь сделать.

+0

Я изучаю язык. Мне потребовалось несколько минут, чтобы понять, что небольшая программа, которую я написал, не работала, потому что (список элементов переходов) не изменяет список (как я бездумно предполагал), но возвращает результат размещения элемента в списке. – drb

+4

Немного программ Scheme продолжают модификацию. Вам нужно будет изменить способ программирования программ, если вы хотите использовать Схему. Книга «Маленькая схема» Фридмана и Феллесина - хорошее введение в схему мышления. – user448810

+0

Спасибо, я над этим работаю! – drb

5

(set! c (cons 3 c))

Ну, давайте быть ясно, что это выражение делает:

  • set! принимает переменную в качестве первого аргумента и выражения в качестве второго аргумента. Он вычисляет второй аргумент и присваивает значение переменной.
  • cons принимает значение и список и производит список с заданным значением в качестве главы, а данный список - как его хвост.

Таким образом, (set! c (cons 3 c)) создает список с 3 как головы и c как хвост, и присваивает этот список в качестве значения c. Это изменение видимо только для кода, который обращается к той же привязке c, если есть другие переменные или поля объектов, которые относятся к исходному списку, они по-прежнему относятся к этому исходному списку.

Это можно свободно описать как «добавление элемента в список» в некоторых контекстах, но это свободное описание, потому что вы не берете существующий список и не изменяете его, чтобы иметь новый элемент; скорее, вы создаете список с новым начальным элементом и исходным списком в качестве его хвоста и изменяете примерно (но, возможно, не все) ссылки на старый список, чтобы указать на новый.

Есть две основные вещи, которые я могу думать покинуть сразу, что также может рассчитывать как «добавление элемента в список»:

  • Изменение структуры существующего списка, чтобы добавить новую пару где-то в середина или конец. Если вы действительно строго придерживаетесь терминологии, это единственный случай «добавления элемента в список».
  • Заканчивает элемент перед списком и возвращает его вызывающему или передает его в качестве аргумента другой функции (без набора!). Это даже более свободный язык, чем ваш пример, но это также самый распространенный случай!

Пример первый:

(define (insert-at-second-position! item list) 
    (set-cdr! list (cons item (cdr list)))) 

Пример второй:

(define (list-copy xs) 
    (if (null? xs) 
     '() 
     ;; We call list-copy recursively on the tail, and "add an item" 
     ;; at the front: 
     (cons (car xs) 
      (list-copy (cdr xs))))) 
+0

Спасибо за этот тщательный ответ. Как это часто бывает, неточность выражения фактически показывает неточность в мышлении или концепции, как я выше. – drb

0

Вы должны знать о конструкторах типа, модификаторов и аксессорах.

Пары CONS CONST CONSTructed with cons, что является процедурой из 2 аргументов, первый аргумент (автомобиль) является первым элементом пары, а второй аргумент (cdr) является вторым элементом пары. Для правильных списков требуется, чтобы cdr был списком с нулевым завершением. В противном случае это всего лишь пара.

Селектор пар (автомобиль и cdr) принимают один аргумент, список CONStructed и извлекает первый (используя автомобиль) или остальные (используя cdr) аргумент пары.

Модификаторы (сеттеры) принимают 2 аргумента: существующий CONStruct (пара, автомобиль пары и в основном все, что было построено) и заменяет выбранную конструкцию значением ее второго аргумента.

(set-car! (cons 'a (cons 'b '())) 'c) ;; is the same as 
(set! (car (cons 'a (cons 'b '()))) 'c) 

Есть?