Как мне вернуть копию объекта? - PullRequest
0 голосов
/ 24 февраля 2011

Мне нужно реализовать функцию с одним аргументом - obj - которая возвращает выражение Scheme, которое при оценке вернет копию obj.

Любые идеи о том, как поступитьс проблемой?

Ответы [ 2 ]

1 голос
/ 25 февраля 2011

Если вы хотите, чтобы ваша процедура могла дублировать любой объект, то этот объект может быть любым из базовых типов Схемы. В силу того, что является различными типами, они имеют разные«Природы», или структура, или что у вас есть, и поэтому создание копии объекта одного типа обязательно будет включать разные стратегии, чем создание копии другого объекта другого типа.

Так какВы подходите к этому, чтобы исследовать каждый из типов Схемы (или, вернее, подмножество типов Схемы, с которыми вам нужно работать) и выяснить, что означает дублирование объекта этого типа.Если вы делаете это очевидным образом, вы должны получить набор специализированных процедур, таких как COPY-NUMBER, COPY-SYMBOL и т. Д. (Спойлер: многие из этих процедур не будут очень интересными.)

Объединение этих специализированных процедур в одну процедуру, которая может дублировать любой объект, который вы даете, сводится к определению реального типа объекта и вызову процедуры COPY-FOO для выполнения работы (вы также можете расширить процедурув соответствии).Вы можете действительно легко организовать это с помощью COND и предикатов определения типа:

(define (copy-object obj)
  (cond ((number? obj) (copy-number obj))
        ((boolean? obj) (copy-boolean obj))
        ...
        ))

Это общий шаблон проектирования для выполнения операции с датумом независимо от его типа, называемого «диспетчеризация по типу».На самом деле это довольно плохой способ сделать общее программирование, не то, чтобы это имело слишком большое значение в этой ситуации.

Последнее, что нужно добавить, это то, что вы возвращаете то, что вы можете оценить, чтобы получить копии.Могу также сказать вам, что это прямо: инкапсулировать вызов COPY-OBJECT внутри лямбда-выражения без аргументов:

(define (expr-returning obj)
  (lambda () (copy-object obj)))

Тогда вы можете делать такие вещи, как

guile> (define x (list 1 2 3 4))
guile> (define y (expr-returning x))
guile> (define cx (y))
guile> x
(1 2 3 4)
guile> cx
(1 2 3 4)
guile> (set-cdr! x 'foo)
guile> x
(1 . foo)
guile> z
(1 2 3 4)
<i>etc.</i>
1 голос
/ 24 февраля 2011

Я предполагаю, что вы хотели написать "функцию, возвращающую expr [которая принимает] obj [и] возвращает выражение Scheme, которое при оценке ..."

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

Надеюсь, это полезно; извините за такую ​​непрозрачность ...

...