Как мне вернуть копию объекта?
Мне нужно реализовать функцию одного аргумента - 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) и т.п.