Как отличить постоянные списки от динамически создаваемых списков? - PullRequest
2 голосов
/ 06 февраля 2012

Я студент, завтра у меня тест, и я увидел, что в прошлом году возник такой вопрос: написать код схемы, который отличает '(a b) от (list 'a 'b), без использования побочного эффекта (нет set!, set-car! ..)
Понятия не имею, как это сделать.у кого-нибудь есть идея?

Причина, по которой есть разница, заключается в том, что '(a b) создает статический объект в памяти, на который ссылаются.И (list 'a 'b) - это приложение, которое создает объект динамической памяти.


Мой учитель ожидает код, который либо дает другой ответ, в соответствии с входными данными, либо тот, что один вход вызывает бесконечный цикл.

Пример кода, который использует побочные эффекты:

(define lst (lambda () '(a b)))
(set-car! (lst) 'g)
(display (lst)) (newline)
;;; prints (g b)

(define lst1 (lambda () (list 'a 'b)))
(set-car! (lst1) 'g)
(display (lst1)) (newline)
;;; prints (a b)

Причина в том, что lambda откладывает вычисление значения, а в случае (list 'a 'b)создание нового списка каждый раз, когда вызывается (lst1).

Для тех, кто жалуется, что вопрос не очень хороший: курс посвящен компиляторам, и он хочет, чтобы мы понимали, какие эффекты все имеет, до генерации кода.

1 Ответ

3 голосов
/ 06 февраля 2012

Есть вопрос к вопросу, что объекты можно отличить по месту в памяти. См. Предикаты эквивалентности в разделе 6.1, особенно описание экв? .

В частности:

(define x '(a b))
(define y (list 'a 'b))

(eqv? x y)
(eqv? y x)
(eqv? x x)
(eqv? y y)

все имеют четко определенные значения.

Как вы заметили,

(eqv? '(a b) '(a b))

зависит от реализации. Если ваш экзаменационный вопрос спрашивает, что произойдет в неопределенной ситуации, я очень хочу ответить «Foo». :) Без лишнего контекста это бессмысленный вопрос.

С другой стороны,

(eqv? (list 'a 'b) (list 'a 'b))

четко определено.

...