OberonCore https://forum.oberoncore.ru/ |
|
Standard Container Library https://forum.oberoncore.ru/viewtopic.php?f=47&t=6234 |
Страница 5 из 6 |
Автор: | Wlad [ Суббота, 24 Март, 2018 01:23 ] |
Заголовок сообщения: | Re: Standard Container Library |
Причём, заметьте, что должно исполняться обязательное условие именно агрегирования, а не наследования наших прикладных классов-"множеств" предметки от классов-коллекций! Этим самым, прежде всего, мы избавляемся от типичной тяжелейшей ошибки проектирования: привнесения на уровень понятия "множество" нашей предметной области, через наследование, понятий и элементов конкретной реализации. Примером такого же подхода является, например, реализация понятия "активный объект". Широко практикуется наследование (в том или ином фреймвоке или библиотеки классов) от класса (условно) Thread с переопределением унаследованного метода Exec(ute)|Run. А ведь активные объекты нашей предметной области НЕ являются реализацией функционала аспектов многопоточности в подлежащей операционной системе или среды исполнения. (Кто не понял это предложение, перечитайте его ещё раз.) Но именно это и утверждается через наследование от класса-потока... Этим самым ломается основной принцип абстрагирования - удаление незначащих или лишних деталей. А ведь через наследование (не важно - public, protected или private), мы ещё крепче привязываемся к таким деталям и ломаем требование стратификации и разделение на уровни представления системы. |
Автор: | Дмитрий Дагаев [ Суббота, 24 Март, 2018 11:34 ] |
Заголовок сообщения: | Re: Standard Container Library |
Полной отвязывание элементов предметной области, универсальный интерфейс реализации контейнеров, агрегирование (а не наследование) Vector, List, Map в прикладные типы предметки... Убедительно, есть над чем подумать. |
Автор: | Илья Ермаков [ Суббота, 24 Март, 2018 16:39 ] |
Заголовок сообщения: | Re: Standard Container Library |
Wlad, поддерживаю высказанные мысли. |
Автор: | Дмитрий Дагаев [ Среда, 11 Апрель, 2018 14:42 ] |
Заголовок сообщения: | Re: Standard Container Library |
Обновил scl, теперь версия 1.2 на обертоне. Произошли архитектурные изменения, навеянные, спасибо, Владимир Витальевич. 1. На элементы списка или map теперь не накладывается никаких ограничений (раньше было Elem = RECORD (List.Elem) .. END). Примеры ObxLists, ObxMaps. 2. Все контейнеры теперь наследуются от общего интерфейса Base.Container. ObxContainers демонстрирует работу через контейнеры, реализованные как Vector, List, Map, а также абстрактную фабрику пользовательских типов. 3. SclObxDictionary показан как композиция и агрегирование контейнеров. 4. SclObxObjects использует Traverse для обхода рекурсивных структур с контейнерами. 5. SclObxKeys показывает возможные варианты работы с компараторами, спасибо Владиславу Фольцу за его комментарии в части компараторов. |
Автор: | Пётр Кушнир [ Среда, 11 Апрель, 2018 22:48 ] |
Заголовок сообщения: | Re: Standard Container Library |
Кажется, каждый компонент с коллекциями проходит одни и те же этапы, как наш Lists. |
Автор: | Пётр Кушнир [ Среда, 11 Апрель, 2018 22:57 ] |
Заголовок сообщения: | Re: Standard Container Library |
Следующим этапом надо ввести коллекцию с параметрическим полиморфизмом по принципу "объект-параметр", как в ListsKeys (ListsObxKeys). |
Автор: | Пётр Кушнир [ Среда, 11 Апрель, 2018 23:00 ] |
Заголовок сообщения: | Re: Standard Container Library |
И ещё weak reference на объекты в списках, как в ypkSysRef. |
Автор: | Дмитрий Дагаев [ Четверг, 12 Апрель, 2018 14:03 ] |
Заголовок сообщения: | Re: Standard Container Library |
Пётр Кушнир писал(а): И ещё weak reference на объекты в списках, как в ypkSysRef. А вот это вполне может быть, и с учетом ypkSysRef. |
Автор: | Wlad [ Пятница, 27 Апрель, 2018 23:22 ] |
Заголовок сообщения: | Re: Standard Container Library |
Пётр Кушнир писал(а): И ещё weak reference на объекты в списках, как в ypkSysRef. Почему? Зачем? Что даёт? От чего спасает? В чём помогает? Можно - в общих словесных рассуждениях и - с примерчиком на экран-два кода. |
Автор: | Пётр Кушнир [ Суббота, 28 Апрель, 2018 08:58 ] |
Заголовок сообщения: | Re: Standard Container Library |
Я делал агентную систему на ББ, там шина сообщений, броадкаст, блабла. Сначала агенты были модули, потом захотелось агентов-объектов, сделал агенты-объекты через "просто список ссылок", но там надо было регистрировать вручную, долго и нудно. Плюс слегка противоречит концепции агентов, как неких "самостоятельных сущностей". Покопался и сделал хук в Kernel.NewObj чтобы выслеживать объекты на этапе создания, проверять тип и нужные сразу неявно регистрировать. Выяснилось, когда неявно добавляешь в объект в список агентов, то в клиентском коде уже нет такого места, где можно было бы явно убрать из списка, поэтому понадобились WeakRef (честно украл у Ермакова И.Е.), такой вид ссылки, которая зануляется при смерти/сборке конкретного объекта. А клиентский кот сам решал, когда убрать объект-агент из собственных внутренних реестров, которые типа охраняли объект от сборки мусора. И ещё для View вне зоны видимости окна, до него никакие сообщения не долетают, а тут вот, долетает, через стороннюю шину и слабую ссылку, что не мешает жыть всему GUI. Плюс это полезно для т.н. скрытых фабрик, у которых тоже бывает проблема с неявной выгрузкой модуля-имплементации. Код не дам, давно это было. |
Автор: | Wlad [ Вторник, 01 Май, 2018 19:39 ] |
Заголовок сообщения: | Re: Standard Container Library |
Пётр Кушнир писал(а): Сначала агенты были модули, потом захотелось агентов-объектов, сделал агенты-объекты через "просто список ссылок", но там надо было регистрировать вручную, долго и нудно. Плюс слегка противоречит концепции агентов, как неких "самостоятельных сущностей". Покопался и сделал хук в Kernel.NewObj чтобы выслеживать объекты на этапе создания, проверять тип и нужные сразу неявно регистрировать. Честно говоря не понял трудностей на этом этапе.Обычно, на этапе создания нам известен тип/класс объекта. Следовательно, все нюансы создания известны. В том числе и сама процедура создания. Сами (сопутствующие) операции создания, можно сгруппировать тем или иным способом (в том числе и в некую «фабричность»). Пётр Кушнир писал(а): Выяснилось, когда неявно добавляешь объект в список агентов, то в клиентском коде уже нет такого места, где можно было бы явно убрать из списка, поэтому понадобились WeakRef (честно украл у Ермакова И.Е.), такой вид ссылки, которая зануляется при смерти/сборке конкретного объекта. А что такое «неявное добавление» в список агентов? «Зануляются» ВСЕ ссылки на уничтожаемый экземпляр объекта? Зачем? Мои вопросы могут выглядеть наивными, но я никогда ещё не пользовался (и не приходил к необходимости формирования понятия «слабых ссылок/указателей») в своих системах. У меня есть лёгкое подозрение, что необходимость в «особенных» ссылках/указателях появляется при ошибках в проектировании архитектуры и концепций системы. Пётр Кушнир писал(а): А клиентский кот сам решал, когда убрать объект-агент из собственных внутренних реестров, которые типа охраняли объект от сборки мусора. И ещё для View вне зоны видимости окна, до него никакие сообщения не долетают, а тут вот, долетает, через стороннюю шину и слабую ссылку, что не мешает жыть всему GUI. У меня есть вопрос. В данном случае элементы поддержки связности по спискам, случайно, не были внесены в сами объекты-агенты (например, в виде полей next и prev)? Пётр Кушнир писал(а): Код не дам, давно это было. «Понимаем...»(с)Товарищ Сухов
|
Автор: | Пётр Кушнир [ Вторник, 01 Май, 2018 20:12 ] |
Заголовок сообщения: | Re: Standard Container Library |
Wlad писал(а): Честно говоря не понял трудностей на этом этапе. Основной смысл в том, что агентами становились разнотипные сущности, которые уже лежали по своим спискам, etc. В сочетании с т.н. механизмом примесей (или аспектов, как-то так я их называл тогда) а позже с помощью "изобретённых" мной ссылок на методы конкретных объектов, базовый класс типа не был нужен, то есть определялся на этапе создания не базовый класс, а наличие поля с примесью или наличие метода HANDLE с VAR-параметром типа ANYREC. Обычно, на этапе создания нам известен тип/класс объекта. Следовательно, все нюансы создания известны. Wlad писал(а): У меня есть вопрос. В данном случае элементы поддержки связности по спискам, случайно, не были внесены в сами объекты-агенты (например, в виде полей next и prev)? Нет, собственно говоря, меня не интересовало, как там объект лежит в списке. Viewы например хранятся так, объекты в каком-нибудь fifo-queue хранятся иначе. Основной интерес был в том, что агентами становились уже готовые, старые сущности. КОнечно, если с нуля проектировать, то можно было просто взять готовый абстрактный класс AbstractAgent да и всё. Но проблему авто-регистрации/де-регистрации это бы не решило.Wlad писал(а): Мои вопросы могут выглядеть наивными, но я никогда ещё не пользовался (и не приходил к необходимости формирования понятия «слабых ссылок/указателей») в своих системах. У меня есть лёгкое подозрение, что необходимость в «особенных» ссылках/указателях появляется при ошибках в проектировании архитектуры и концепций системы. Ну вот как раз "агенты" были тогда прецедентом, когда "ссылки/указатели" со стороны системы рассылки сообщений задерживали объекты в памяти, хотя все остальные, значимые ссылки на них уже были потеряны, занулены и вообще, объект уже должен был сдохнуть. Поэтому понадобилось понятие агента, такого объекта, который типа сам по себе, в условиях системы со сборщиком мусора: неявно занесён в список, который не мешает сборщику работать, при этом о прямой ссылке на объект заботятся другие механизмы, не связанные с глобальной объектной системой. Модули ББ, по сути, тоже занесены в некий список, что позволяет методами ядра по ним бегать и дёргать процедуру HandleMessage, хотя модуль рассылающий не импортирует модуль получающий. |
Автор: | Пётр Кушнир [ Вторник, 01 Май, 2018 20:17 ] |
Заголовок сообщения: | Re: Standard Container Library |
Wlad писал(а): «Понимаем...»(с)Товарищ Сухов Ну да, где-то это всё есть, в каких-то репозиториях, просто в архивах старых девелоперских сборок ББ, но вот так чтобы тыкнуть, где это было, я уже не можу) |
Автор: | Wlad [ Вторник, 01 Май, 2018 23:49 ] |
Заголовок сообщения: | Re: Standard Container Library |
Пётр Кушнир писал(а): .... Вы меня извините, у меня сейчас какая-то накопившаяся многолетняя усталость. Плюс я сейчас не на своём привычном месте разработчика систем, а - занимаюсь чёрти чем по сути. Некая разновидность депресняка образовалась... Мозг просто отказывается схватывать с лёту концепции и идеи, если они не закреплены в собственном опыте разработок. Отдохнуть и перейти в привычное русло и "проблемы" - сами собой поисчезают (такое уже бывало на границе 90-х-2000-х со мной. Тогда, кстати, тематика оберонов очень помогла вернуться в привычное рабочее русло). Разжёвывать, конечно же, не прошу, но пару-тройку ссылок по тому, на чём основывались ваши решения, я бы не отказался увидеть здесь. |
Автор: | Пётр Кушнир [ Вторник, 01 Май, 2018 23:54 ] |
Заголовок сообщения: | Re: Standard Container Library |
Про примеси Про агенты Вот, собственно, пример, примеси называются деталями, во viewtopic.php?f=47&t=4175&hilit=+%D0%B4%D0%B5%D1%82%D0%B0%D0%BB%D0%B8 |
Автор: | Jordan [ Пятница, 01 Июнь, 2018 23:27 ] |
Заголовок сообщения: | Re: Standard Container Library |
Приемлем ли вариант кодогенерации контейнеров. Пишем в текстовом файле пример кода: Код: {$mode objfpc}{$H+} unit U(NAME)Vector; interface uses U(NAME); type (TYPE)Vector = class private Total: Longword; Pos : Longword; Data: array of (TYPE); public constructor Create(Count: Longword = 128); destructor Destroy; override; procedure PushBack(const Value:(TYPE)); function GetValue(Position: Longword): (TYPE); procedure SetValue(Position: Longword; const Value: (TYPE)); property Index[i: Longword]: (TYPE) Read GetValue Write SetValue; Default; function Size(): Longword; end; implementation constructor (TYPE)Vector.Create(Count: Longword); begin Total := Count; SetLength(Data, Total); Pos := 0; end; destructor (TYPE)Vector.Destroy; begin end; procedure (TYPE)Vector.PushBack(const Value: (TYPE)); begin if (Pos + 1 >= Total) then begin Total := Total * 2; SetLength(Data, Total); end; Data[Pos] := Value; Inc(Pos); end; function (TYPE)Vector.GetValue(Position: Longword): (TYPE); begin GetValue := Data[Position]; end; procedure (TYPE)Vector.SetValue(Position: Longword; const Value: (TYPE)); begin Data[Position] := Value; end; function (TYPE)Vector.Size(): Longword; begin Size := Pos; end; begin end. Консольная прога заменяющая определенные слова в файле. Запускаем call main Critter TCritter UCritterVector На выходе Код: {$mode objfpc}{$H+} unit UCritterVector; interface uses UCritter; type TCritterVector = class private Total: Longword; Pos : Longword; Data: array of TCritter; public constructor Create(Count: Longword = 128); destructor Destroy; override; procedure PushBack(const Value:TCritter); function GetValue(Position: Longword): TCritter; procedure SetValue(Position: Longword; const Value: TCritter); property Index[i: Longword]: TCritter Read GetValue Write SetValue; Default; function Size(): Longword; end; implementation constructor TCritterVector.Create(Count: Longword); begin Total := Count; SetLength(Data, Total); Pos := 0; end; destructor TCritterVector.Destroy; begin end; procedure TCritterVector.PushBack(const Value: TCritter); begin if (Pos + 1 >= Total) then begin Total := Total * 2; SetLength(Data, Total); end; Data[Pos] := Value; Inc(Pos); end; function TCritterVector.GetValue(Position: Longword): TCritter; begin GetValue := Data[Position]; end; procedure TCritterVector.SetValue(Position: Longword; const Value: TCritter); begin Data[Position] := Value; end; function TCritterVector.Size(): Longword; begin Size := Pos; end; begin end. Сама прога Код: program main; {$mode objfpc}{$H+} uses SysUtils;//, UnitGenCode; var Line : string; Input : text; Output: text; begin assign(Input, 'GenCode.pas'); assign(Output, ParamStr(3) + '.pas'); rewrite(Output); reset(Input); while not eof(Input) do begin readln(Input, Line); Line := StringReplace(Line, '(NAME)', ParamStr(1), [rfReplaceAll]); Line := StringReplace(Line, '(TYPE)', ParamStr(2), [rfReplaceAll]); //writeln(Line); writeln(Output, Line); end; close(Input); close(Output); end. Смысл понятен получаем, типизированный контейнер. К примеру такая приблуда встраивается в IDE. Есть кнопка хАчу вектор, нажал указал тип данных в векторе и собсно файлик добавился, подключился к проекту. Минимум усилий не нужно вносит изменения в язык. Чисто внешняя фенечка. Не ограничиваться только вектором а реализовать основные контейнеры, списки, стеки, очереди, всякие пулы объектов, кольцевые очереди на массиве и т.д Это проще, чем фичевать язык компилятор. И такой кодогенератор, пишется для любого языка. Костыль конечно. Но если через IDE автоматизировать, не думаю, что будет выглядеть как что то чужеродное. |
Автор: | budden [ Воскресенье, 23 Декабрь, 2018 22:56 ] |
Заголовок сообщения: | Re: Standard Container Library |
А можно поинтересоваться насчёт слабых ссылок: что будет с производительностью GC, если таких объектов будет много? В SBCL я начал лепить их где только можно, их стали десятки-сотни тысяч, и закончилось тем, что сборка мусора стала занимать 30 секунд. Потом они улучшили алгоритм учёта слабых ссылок и стало полегче (плюс я ещё там где-то что-то руками стал вызывать, там поколенческая сборка мусора, что создаёт ещё дополнительные особенности). |
Автор: | Дмитрий Дагаев [ Понедельник, 24 Декабрь, 2018 18:07 ] |
Заголовок сообщения: | Re: Standard Container Library |
Со всеми сборками не тестировал, используйте Код: Process (VAR co: Base.Container вместо IN
|
Автор: | budden [ Среда, 26 Декабрь, 2018 01:24 ] |
Заголовок сообщения: | Re: Standard Container Library |
Спасибо. |
Страница 5 из 6 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |