К сожалению, это одно из общеизвестных ограничений struct-copy
, большинство из которых вытекают из того, что Сэм Тобин-Хохштадт метко описал как "негигенически склеивающие части структур вместе". (а не низкоуровневое представление о копирующих структурах), и является частью причины , что «struct-copy
безнадежен и не может быть исправлен без существенных изменений в том, как работают структуры». Матиас Фелляйзен описал это как "ахиллесова пята в нашем мире". В сообществе Racket определенно есть желание улучшить эту ситуацию, но по ряду причин это кажется пугающим. Я не знаю никого, кто бы активно работал над этим, и на что похоже принципиальное решение, остается открытым вопросом.
Структуры во многом очень важны для Racket. Концептуально, каждое значение в Racket может быть экземпляром некоторого структурного типа, хотя в действительности система времени выполнения имеет специализированные представления для определенных встроенных модулей. Фактически, я думаю, что текущая работа по замене C на Chez Scheme в реализации Racket может использовать структуры для некоторых вещей, встроенных в устаревшую Racket VM. Это возможно, потому что структуры предлагают сильные возможности инкапсуляции, особенно через инспекторов . Улучшение структуры работы затронуло бы практически весь Racket и повлекло бы за собой множество разрозненных соображений, особенно в отношении обратной совместимости.
Вот несколько советов для дальнейшего чтения о проблемах:
Хорошая новость заключается в том, что, хотя выяснить, как правильно делать общее дело, сложно, подход Racket «языки как библиотеки» позволяет всем программистам и авторам библиотек пробовать разные подходы в своем собственном коде. Существуют различные пакеты Racket, чтобы помочь с функциональным обновлением и другими функциями. Alexis 'struct-update
предоставляет макрос для синтеза таких функций, как timeseries-observations-update
. Джей МакКарти также экспериментировал с улучшениями для структурирования в библиотечном коде. Вы также можете реализовать решение, адаптированное к вашему конкретному варианту использования, от реализации согласованного метода copy
(с racket/generic
или racket/class
) до создания языка, специфичного для домена, который может более естественно выразить вашу проблемную область. Эта ветка списка рассылки , несмотря на тему, охватывает множество подходов к функциональному обновлению в Racket (включая некоторые мои мысли о DSL).