Rifat писал(а):
И про то, что можно на её основе сделать персистентные контейнеры, то есть контейнеры, которые запоминают каждую свою модификацию и при желании можно вернуться к предыдущей версии и посмотреть что там было.
...
Единственное, остался один неясный момент.
...
И на каком-то этапе может так произойти, что не хватит памяти для сохранения этой истории
А зачем нужна эта история? Если предполагается нечто вроде мини-СУБД, то обычно в подобных случаях функционал шире со спецификой предметки (к примеру, версии нужны в контексте транзакций, журналов операций, существует возможность сброса/загрузки на диск и т.д.). Но исходя из презентации речь, вроде как, об универсальных контейнерах и алгоритмах, аля STL. Однако типовая сфера применения "персистентных" универсальных контейнеров -- immutable-коллекции как в функциональных языках, или по их мотивам -- на примере facebook-фреймворка для JavaScript:
http://facebook.github.io/immutable-js/, где версии, как таковы, используются для внутренней реализации "виртуального копирования" структур, в стиле:
A = [1,2,3,4,5,6];
B = A;
B[1] = 12234;
Здесь при присваивании "B = A" не выполняется копирования контейнера (массива), лишь используется указатель. При изменении данных вида "B[1] = 12234" создаются "версии" только необходимых элементов, части исходной структуры. В последующем "история" освобождается при уничтожении объектов (т.е. при выходе из области определения переменных и т.п.). В дополнение, практика обычно требует и транзитных преобразований, т.е. "по месту", временный перевод структур из immutable в mutable (плюс "ленивые" вычисления по вкусу, как тип Seq по ссылке выше -- для избегания по возможности создания промежуточных структур при различных вычислениях).
Для таких техник необходимы:
- реализация политики каких-то smart-pointer, для разруливания владения, освобождения и т.д.;
- предположение, что в виртуальных копиях обычно выполняется лишь частичная модификация данных (т.е. не передел всего и вся, иначе нет никакой эффективности).
Такова типовая необходимость в "версиях" в стандартных контейнерах, и нет концептуальных непоняток с их "накоплением".
Однако, в дополнение возникает сомнение, зачем подобные техники и "STL" в целом в языке, который целенаправленно не приспособлен к обобщённым алгоритмам. И Ваша презентация тому кричащий пример, как и некоторые темы здесь на форуме. Согласно презентации, необходимость реализации "типов-ключей" и соответствующих операций вида "AssignAddrToAddr", "CompareKeyAddr" и т.д., фактически, для каждого случая применения, а особенно при использовании стандартных же базовых типов -- чисел, строк и т.д., в том числе и как составных данных, со стандартными же операциями -- мягко говоря, не юзабельно.
Вот здесь был пример реализации "STL" для Pascal при отсутствии generic-ов:
viewtopic.php?f=26&t=2036&start=100#p101400, где, в некотором смысле, имеется схожий подход в архитектуре. Не в курсе, насколько подобные выкрутасы целесообразны в Оберонах (не использую, имею лишь поверхностные знания), но взглянуть есть смысл. Там также применялись "типы-ключи", но по-иному -- как "типы-поля" для структур данных, в которых "перехватываются" ключевые операции от контейнеров (был интерфейс и для деревьев).
Правда, для удобства в том же Pascal-е были (и есть) некоторые базовые языковые конструкции. К примеру, определение операций "индексации" для произвольных "свойств" в структурах аля:
n.Map[3.14] := 'Pi'
Или применение встроенных типов вида "variant" или "TVarRec" (или как там тип-запись назывался для аргументов функций, определяемых как "array of const") для передачи "открытых" массивов как variadic-параметров.
Не знаю, как подобные удобняшки стандартно реализуются в Обероне, но есть подозрение, что окольными путями (вряд ли тогда в них есть смысл).
P.S. Документация от проекта AntiDot:
Вложение:
Guide.pdf [143.87 КБ]
Скачиваний: 95