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). :D

Автор:  Пётр Кушнир [ Среда, 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 секунд. Потом они улучшили алгоритм учёта слабых ссылок и стало полегче (плюс я ещё там где-то что-то руками стал вызывать, там поколенческая сборка мусора, что создаёт ещё дополнительные особенности).

Автор:  budden [ Понедельник, 24 Декабрь, 2018 13:27 ]
Заголовок сообщения:  Re: Standard Container Library

В последней обертоновской сборке не собирается (точнее, в нашей пророщенной от неё, но скорее всего, дело не в пророщенности, а в модификации объекта только для чтения).

Вложения:
несобирается-scl.png
несобирается-scl.png [ 29.28 КБ | Просмотров: 6572 ]

Автор:  Дмитрий Дагаев [ Понедельник, 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/