Как мне вернуть копию объекта?

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

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

2 ответа

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

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

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

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

Итак, как вы подходите к этому, чтобы изучить каждый из типов Схемы (или, вернее, подмножество типов Схемы, с которыми вы заботитесь) и выяснить, что означает дублирование объекта этого типа. Если вы делаете это очевидным образом, вы должны получить набор специализированных процедур, таких как 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> (определить x (список 1 2 3 4))
guile> (определить y (expr-returning x))
guile> (определить cx (y))
хитрость> х
(1 2 3 4)
guile> cx
(1 2 3 4)
guile> (set-cdr! x 'foo)
хитрость> х
(1 . Фу)
guile> z
(1 2 3 4)
и т.п.
Другие вопросы по тегам