OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 16:08

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 76 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
СообщениеДобавлено: Пятница, 25 Январь, 2019 05:58 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
И это, я подозреваю, что тебе нежен не Оберон, а Модула-3 - она лучше ложится на твои фантазии


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 25 Январь, 2019 08:56 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1428
Если по-простому, нужно решить три вещи:
  1. Что параметризовать: процедуры и типы или сразу модули.
  2. Чем параметризовать: только типами, или еще и значениями, или опять же модулями.
  3. Как параметризовать: размножение кода или универсальный код но с ограничениями на типы параметров.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 25 Январь, 2019 12:09 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Ну я читаю этот отчёт, он далеко не идеален. Например, вынос SYSTEM из языка - это просто такой нехороший трюк: мы тут все чистенькие, а в канализации сами копайтесь. Выкидывание параллельности просто не сработало вообще, т.к. она вернулась в ББЦБ и Активный Оберон. Параллельность очень трудна, компилятор без её поддержки - это плохой, дешёвый в худшем смысле слова инструмент. ООП а-ля C++ - это вообще ошибка проектирования, индустрия это уже осознала. В тренде JavaScript, Rust, Golang, вечно зелёным остаётся SQL. 1С тоже прекрасно обошёлся без объектов. Включение типов - это уже ошибка уровня "не знать математику", поскольку LONGINT не является подтипом REAL. Хотя когда я об этом здесь написал, некоторые пытались путём риторики это загладить, дабы с Вирта нимб не осыпался. На самом деле очень опасная ошибка, причём ошибка проектирования в чистом виде, которая чревата техногенными катастрофами. Арифметика - это вообще одна большая ошибка проектирования. В языке высокого уровня обязательно должны быть целые неограниченной точности. Если я ворочаю миллиардами, то мне не обязательно константное время выполнения сложения. Вирт продаёт калькулятор, в котором x + 1 может завершиться авостом, а может вернуть неправильный результат. В лиспе x + 1 всегда вернёт правильный результат (ну, если не оптимизировать по скорости с потерей безопасности). Авост может случиться, только если заниматься какой-нибудь дикой комбинаторикой, когда циферки не поместятся в памяти компьютера. Даже в презренном 1С применена другая система числовых типов, потому что стандартный для всех этих ассемблеров++ числовой системы типов не хватает даже для пивного ларька, не то, что для Роснефти. Вирта частично оправдывает то, что на рынке большинство калькуляторов такие, но мне такой калькулятор не нужен. А это сделано в Обероне и исправить это, оставаясь в его рамках, невозможно!

И наконец, требования к языкам резко меняются, если учесть существование IDE. Например, явная квалификация модулей делает код очень многословным, а отсутствие иерархической организации модулей ограничивает масштабируемость. В ББЦБ придумали лежащее вне языка (довольно корявое) соглашение о директориях. И кстати, оно говорит об отсутствии в языке такого понятия, как библиотека, но это к слову. В А2 дикая директория с 1600 файлами. Многословность кода делает его более труднопостижимым и через это снижает надёжность, поэтому с ней нужно бороться всерьёз. При этом способность человека помнить контекст не используется, т.е. мозг работает неэффективно. Наличие IDE позволяет мгновенно определить, из какого модуля импорт, а разумно определённый язык позволяет в большой мере защититься от ошибок совпадающих имён. SQL уже много лет назад показал, как это надо делать. В этом смысле обероны, можно сказать, устарели даже по сравнению с Java, для которой люди более-менее научились делать IDE. Обероны позволяют IDE, но самих IDE я пока не видел.

Лишить команды параметров - это вообще непонятно что за безобразие. Видимо, тут рисуется образ кнопки, на которую надо нажать. Но в норме диалог происходит в консоли, а не путём нажатия кнопок. Индустрия это тоже прекрасно осознала - в Windows всё администрирование теперь можно делать через скрипты, без всяких кнопок. И на практике это требование отсутствия параметров всё равно не выполняется, ни в ББЦБ, ни в А2.

Т.е. спасибо за рекомендацию по чтению, честно сказать, меня всегда такие статьи подбешивают. Потому что они повествуют о жизни в тюрьме. Я Вам в ответ посоветую почитать что-нибудь по Common Lisp. Я его учил по CLTL2. https://www.cs.cmu.edu/Groups/AI/html/cltl/cltl2.html . Разрыв шаблона гарантирован. Причём Вы начнёте жалеть о том, что раньше не прочитали. Если осилите, конечно, потому что текста там много и написано он нелегко. Да и сам лисп снаружи непригляден, не так легко докопаться до стройного каркаса тех концепций, на котором он построен. Я этот обероновский отчёт проглядел меньше чем за час и подумал над всеми пунктами, а лисп нужно месяц в режиме погружения осознавать. К сожалению, я не знаю ни одной статьи, описывающей лисп достаточно коротко, чтобы сократить время на ознакомление и при этом чтобы преимущества были выражены доходчиво.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 25 Январь, 2019 12:36 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
А касабельно модулы-3, тут более сложная тема, чем с этим отчётом, просто ввиду объёма труда. Если я вдруг вернусь к разработке ЯП, то почитаю. Пока же задача разработки ЯП на повестке дня не стоит, поэтому и читать незачем. Целых два механизма в модуле-3 вызывают вопросы - это обработка исключений и ООП. Про ООП я уже написал. С исключениями даже на уровне общей философии непонятно, что делать. Вроде как считается, что в Расте хорошо придумали, но я на Расте не писал, поэтому не могу ничего сказать. Я к тому, что скорее всего в модуле-3 мало интересного на сегодняшний день.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 26 Январь, 2019 16:32 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
А ты книжку Project Oberon читал?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Январь, 2019 00:48 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Нет, собираюсь прочесть в ближайшее время - сейчас по плану чтение всей доступной документации по А2 и около.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Январь, 2019 07:43 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
budden писал(а):
Нет, собираюсь прочесть в ближайшее время - сейчас по плану чтение всей доступной документации по А2 и около.
Ну вот сначала Прожект нужно читать, потом доки по А2.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 13:10 

Зарегистрирован: Пятница, 11 Январь, 2019 21:33
Сообщения: 88
budden писал(а):
скорее всего в Modula-3 мало интересного на сегодняшний день.
Напишу кратко: не уверен.
По Modula-3 есть отдельная тема на форуме, не будет ли лучше, не связанные с полиморфизмом вопросы, обсудить там?..


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 19:44 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
Сейчас для меня наиболее актуален вопрос, чем я буду кормить семью. Даже до этого был более актуален вопрос, как русифицировать A2 и сделать управление окнами с клавиатуры. До полиморфизма становится всё дальше и дальше. Возможно, и никогда уже к нему не вернусь. Так что не будем пока что обсуждать.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 20:56 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
budden писал(а):
2. Моё безкультурье - я плохо знаю ML-образные языки. Т.е., чтобы я понял, нужны ссылки на какие-то короткие объяснялки сути заимствованных концепций. Например, я не понимаю, зачем нужны проекции. Если это аналог указателя на элемент записи, то я бы из минимализма постарался бы от этого отказаться. Потому что возникает проблема времени жизни, и чтобы её решить, нужно нагородить ещё костылей. Т.е. тут нужно принять за аксиому, что мы жертвуем частью производительности ради простоты.

Проекции не аналог указателя на элемент записи. Указатель на элемент структуры непосредственно содержит адрес конкретного объекта (члена записи). Если допустить такие указатели, то, действительно, есть заморочки с их корректностью.
Проекция это то, что торчит справа от точки, напр. "p.field" -- условно, значение смещения от адреса самой записи, т.е. её начала. Компилятор этими смещениями манипулирует неявно, а типы-проекции декларируют этот механизм явным. Это сам тег ".field". Может быть, вместо ключ. слова "proj" как раз лучше и применить "tag", а то при виде "proj" не всегда возникает необходимая ассоциация, хоть понятие и математическое (тот же индекс массива или структуры, иными словами):
Код:
// Пусть тогда будет такой формат:
// type proj = tag <поле> of <контейнер>  -- проекция на конкретное поле известного типа-контейнер
// type proj = tag <тип>                  -- проекция на неизвестное поле типа <тип> неизвестного контейнера

type
    MyRec = record
        a: integer;
        b: string;
        c: string;
        sub: record
                f1: float;
                f2: float;
             end;
    end;

var
    r, r1: MyRec;
    p1: tag a of MyRec;         // проекция на поле a
    p2: tag sub of MyRec;       // проекция на поле sub
    p3: tag sub.f2 of MyRec;    // проекция на вложенное поле sub.f2
    p4: tag string;             // проекция типа string, неизвестного поля любого контейнера

// операции полностью эквивалентны (для компилятора эти операции есть одно и тоже,
// он вправе заинлайнить и прочее необходимое оптимизировать, всё что нужно),
// эквивалентность аналогична и для случая, если бы "r" был бы указателем/ссылкой
r.a := 10;
p1[r] := 10;

// ... аналогично
r1.a := 20;
p1[r1] := 20;  // проекция совместима как для r, так и для r1

r.sub.f1 := 1.3;
p2[r].f1 := 1.3;

r.sub.f2 := 2.4;
p3[r] := 2.4;


// инициализируем проекцию p4 в зависимости от условия:
if r.a > 0 then
    new(p4, b of MyRec)  // формат как и при объявлении типа: (... of ...)
else
    new(p4, с of MyRec)
end;

p4[r] := "str";

Проекции заменяют в т.ч. "классический" оператор "with" в Паскалях ("сокращённый" доступ к полям).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 20:59 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Тогда "расширенные" проекции комплексных контейнеров, т.е. тех, которые, в отличие от базового record, содержат набор записей, пусть задаются через ключ. слово "by" (мол теги продуцируются таким-то типом):
Код:
var
    f1: tag integer by vector;
    f2: tag float;
    f3: tag string;

// целочисленный вектор с двумя дополнительными полями,
// начальной ёмкостью 1000
new(f1, 1000, [f2, f3]);

var h: handle := f1.add(10);
f2[h] := 3434.35;
f3[h] := "str";

// поиск по полю f3
h := f1.find(f3, "str");

Выше в примере реальная структура вектора как (integer, float, string) не запакована в явный статический тип record, и в результате, напр., для универсальных алгоритмов не требуется создавать операции вида compare, "<" и т.п., используются базовые возможности поверх проекций (при потребности, конечно же, можно оформить свои функции, как и типы). Ранее в теме был примерчик, как может выглядеть альтернатива для плюсового multi_index (один и тот же стиль и средства как для статических типов (с потенциалом вплоть до полного инлайнинга кода, если так приписано компилятору), так и для динамических структур, формируемых в runtime).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 21:02 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Тогда проекции на стандартный массив пусть задаются через ключ. слово "case" -- выбор по константе (фактически, по сути это те же константы, но с учётом понятия "измерений" массива):
Код:
type
    Arr1 = array 10 of integer;
    Arr2 = array 10, 20 of integer;
var
    i: integer;

    arr, arr1: Arr1;
    p1: case 2 of Arr1; // проекция на элемент 2

    arr2: Arr2;
    p2: case 0, 5 of Arr2;   

    p3: case integer; // неизвестная проекция типа integer

arr[2] := 10;
i := p1[arr]; // i = 10;

p1[arr1] := 20;
i := arr1[2] // i = 20

arr2[0, 5] := 30;
i := p2[arr2];

new(p3, case 2, 18 of Arr2);
p3[arr2] := 40;


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 21:09 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
budden писал(а):
P.S. А вообще в оберонах интересно было бы переоберонить Вирта, т.е. ещё упростить оберон. Насчёт собственно оберонов я не в курсе, а в КП явно упрощение не доведено до конца:

- и модули, и объекты являются единицей инкапсуляции.
Т.е. одно понятие инкапсуляции продублировано в двух
схожих, но различных явлениях в языке. Это значит,
что простота недополирована.
- модули заодно являются единицей инкапсуляции и единицей сборки. Неортогонально, а значит, простота и тут недополирована.
[...]
Вот придумать бы такой идеализированный оберон, в котором всё ортогонально, без дублирования и в котором реализована линейная оболочка ортогональных векторов, а не жалкий огрызок оной.

В околооберонных кругах попытка "по-ортогональному переоберонить Оберон" имеется -- проект СЛанг:
https://forum.oberoncore.ru/viewtopic.php?f=12&t=6227#p103613

, где есть понятие unit как некий универсальный контейнер для интерпретации модуля, типа, единицы компиляции. Рациональное зерно в таком приёме имеется. Ранее в теме в примерчиках была попытка мимикрировать под классы типов с учётом принципов классического паскалевского синтаксиса. В рамках абстрактных типов всегда есть потребность оперировать параметрами типов, даже при использовании т.н. ассоциированных типов (и констант, в целом большое количество параметров может создавать неудобства):
Код:
type
    // абстрактный тип имеет параметр и ассоциированные типы
    Container[C] = abstract
        type A; // ассоциированный тип, требует последующего определения
        type B; // ...

        virtual fn contains(in c: C; e1: A; e2: B): boolean;
        virtual fn first(in C): A;
        virtual fn last(in C): B;
    end;

    MyRec = record
        n, m: integer;
    end;

open Container[MyRec]
    type A = integer;
    type B = integer;

    fn contains(in r: MyRec; e1, e2: integer): boolean :=
        (r.n = e1) and (r.m = e2);
    fn first(in r: MyRec): integer := r.n;
    fn last(in r: MyRec): integer := r.m;
end;

В СЛанг есть множественное наследование (через ключ. слово extend, "подключение" unit-а через use) как расширение unit-ов, фактически, возникает пересечение типов (есть и объединение, но только в замкнутой краткой форме вида "(T1|T2)"), в таком стиле (введём и "ассоциированные unit"-ы):
Код:
abstract unit Container
    unit A;
    unit B;

    virtual fn contains(in c: Container; e1: A; e2: B): boolean;
    virtual fn first(in Container): A;
    virtual fn last(in Container): B;
end;

unit MyRec
    n, m: integer;
end;

// "extend unit ..." -- расширяем unit такой-то,
// "extend ..." -- чем расширяем
extend unit MyRec extend Container
    unit A = integer;
    unit B = integer;

    fn contains(in r: MyRec; e1, e2: integer): boolean :=
        (r.n = e1) and (r.m = e2);
    fn first(in r: MyRec): integer := r.n;
    fn last(in r: MyRec): integer := r.m;
end;

// ещё одно расширение MyRec:
extend unit MyRec
    fn difference(in r: MyRec): integer :=
        r.last() - r.first();
end;

Ассоциированные типы, по сути, есть те же параметры типа, параметры также применяются:
Код:
abstract unit Container[A, B]
    virtual fn contains(in c: Container; e1: A; e2: B): boolean;
    virtual fn first(in Container): A;
    virtual fn last(in Container): B;
end;

unit MyRec
    n, m: integer;
end;

extend unit MyRec extend Container[integer, integer]
    fn contains(in r: MyRec; e1, e2: integer): boolean :=
        (r.n = e1) and (r.m = e2);
    fn first(in r: MyRec): integer := r.n;
    fn last(in r: MyRec): integer := r.m;
end;

Можем локализовано "расширять" по месту:
Код:
unit MyRec
    unit A: Numeric; // Numeric -- абстрактный unit
    unit B: Numeric;

    n: A;
    m: B;
end;

var rec: extend unit MyRec unit A = integer; unit B = integer end;

// в краткой форме, "расширяем" лишь в рамках параметров:
var rec: MyRec[unit A = integer; unit B = integer];
var rec: MyRec[A = integer; B = integer];


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 21:13 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Насчёт понятия модуля. Здесь рядом на форуме была дискуссия по поводу названия Компонентный Паскаль. Однако, толком так и нет нигде конкретных определений, что именно есть компоненты (даже приведенные ссылки на вики также детально не раскрывают суть).
Но, во всяком случае, в КП прослеживается некая аналогия с понятиями и терминами из материальной инженерии (в информационной или программной инженерии -- некая каша в таких вопросах). Исторически, под компонентами понимаются функциональные составляющие системы -- на конструкторском этапе разработки выделяются/создаются элементы системы в разрезе их функций -- в данном случае функция понимается как предназначение, роль (без конкретики исполнителя роли, напр., сопротивление такое-то). Обычно принципиальные схемы и есть схемы компонентов, где все условные оболочки устройств "вскрыты", и отражаются связи между функциональными элементами в разрезе всей системы (или в рамках необходимого аспекта). На этапе технологического проектирования/производства возникают модули -- конкретные исполнители определенных в системе ролей, конкретные устройства (напр., плата со всеми сопротивлениями и пр., часто слово модуль присутствует непосредственно в названии). Соотношение компонент <-> модуль может быть как один ко одному, или один модуль может реализовывать множество ролей-компонентов, или же для реализации одной роли может требоваться множество модулей. Понятие интерфейса возникает именно между модулями.

Паскалевские модули лучше интерпретировать как технологические единицы конструкторских компонент. В общем случае вариантов интерпретации множество (кроме сборки изделия как монолитный исполнительный exe-шник или аля dll). Возможна разная языковая среда/платформа, с динамикой загрузки/компиляции модулей, с поддержкой вариативности функционала (модулей) и пр., даже возможны варианты некой "множественности" модуля (понимая его как синглтон). К примеру, в упомянутой выше RT Java, а точнее Safety-Critical Java, есть предложения любопытных приёмов над модулями (там возникают схожие понятия в иной терминологии, кроме жабских пакетов -- домены, порталы и пр.). Возможна прозрачная организация репликаций вычислений -- избыточные вычисления для контроля (напр. для контроля работы памяти или в целом оборудования, кроме того, что компилятор в исполнимом коде может инъектировать контролирующие спец-операции в дополнение или вместо аппаратных средств) -- загружается определенное количество экземпляров необходимого модуля, каждый модуль отображается (привязывается) в собственную область памяти или исполнимое устройство и т.п., при вызове процедур (методов) клиентами модуля прозрачно для клиентов одновременно отрабатывают все заданные экземпляры модуля, затем производится оценка консенсуса (результаты должны быть одинаковыми, или необходимо подтверждение 2 из 3 и т.п.), в случае успеха результат процедуры передаётся клиенту.

Unit-ы выше от СЛанг не конкретизируют жёстко понятие модуля, позволяют по-своему под потребности перейти к реализации технологических единиц (вплоть до введения ключ. слова module). Простейшая форма -- файлы с одним или множеством unit-ов, и т.д.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 21:15 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Trurl писал(а):
Если по-простому, нужно решить три вещи:
  1. Что параметризовать: процедуры и типы или сразу модули.
  2. Чем параметризовать: только типами, или еще и значениями, или опять же модулями.
  3. Как параметризовать: размножение кода или универсальный код но с ограничениями на типы параметров.

В идеале, параметризовать необходимо unit (и операции) как выше -- т.е. всё, возникает однородная форма. Параметризовать и перечислимыми константами (что есть те же конструкторы типов, и статические базовые массивы в них нуждаются). Вводить какие-то фундаментальные ограничения на параметры типов, вроде как, нет резона. К примеру, решение для Оберон-ов от Clemens Szyperski и Paul Roe (с разрешением только указательных типов), вроде бы, не имеет широкого применения.

Выше была модель полиморфных типов, т.е. это не просто какие-то макро-шаблоны. Существует возможность мономорфизации, т.е. создания кода в единственном экземпляре для необходимого сочетания типов, чем занимаются (или пытаются), вроде как, в том же Rust-е. Одним из пионеров в вопросах мономорфизации был MLton (вариант реализации ML), у них там и исследования какие-то были по поводу. В общем, по их оценкам раздутие кода относительно минимально, что-то вроде не более 30% (в любом случае, автоматизируется та работа, которая иначе выполняется вручную или с помощью иных генераторов).
Инлайнить полиморфный код или нет -- уже производный другой вопрос, регулируется общими положениями, через атрибуты типов или прагмы и пр. Напр., ожидаемо, что арифметические операции инлайнятся и т.д.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 22:13 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1428
PSV100 писал(а):
К примеру, решение для Оберон-ов от Clemens Szyperski и Paul Roe (с разрешением только указательных типов), вроде бы, не имеет широкого применения.

Имеет, только замаскированное.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 29 Январь, 2019 23:22 

Зарегистрирован: Понедельник, 11 Сентябрь, 2017 13:23
Сообщения: 1557
> В околооберонных кругах попытка "по-ортогональному переоберонить Оберон" имеется -- проект СЛанг:
Спасибо. Если будет возможность к этому вернуться - обязательно посмотрю. Остальное даже некогда почитать...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 30 Январь, 2019 15:32 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Чур меня! чур меня! чур меня!..


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 01 Февраль, 2019 19:40 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Info21 писал(а):
Чур меня! чур меня! чур меня!..

Предлагаю посмотреть на проблематику в том числе и с другой стороны. Здесь на форуме неоднократно возникали дискуссии насчёт полиморфизма вокруг множественного наследования, реализации "интерфейсов" и т.п. Из того, что вспомнилось и удалось нарыть основное:
https://forum.oberoncore.ru/viewtopic.php?f=47&t=4175
https://forum.oberoncore.ru/viewtopic.php?p=74239#p74250

В самом деле, "компоненты" можно моделировать через композицию -- "агрегаты" содержат в себе необходимые "детали" (по своей сути -- полиморфные), согласно принципам и терминологии по первой ссылке выше, где даже предлагаются некоторые средства автоматизации инициализации "деталей" в "агрегате" (однако, через интроспекцию, т.е. всё же закулисно вне контрактов самой системы типизации). Условные "детали" можно создавать и динамически по потребности, напр., согласно второй ссылке выше, по необходимости создаются объекты вида Reader-ов, Writer-ов и т.п., и применяются соответствующие алгоритмы. Некоторые "детали" могут быть и в единственном экземпляре для обслуживания целого домена (прикладного типа), как Slider в примерах (ссылка 2, как я понимаю, аля "токены").
И, фактически, как таковой нет потребности в каком-то явном механизме "интерфейсов" (как языковые средства).

Возникающие особенности. Ключевые -- две. Применяется лишь механизм динамической диспетчеризации вызовов (гипотетически, компилятор в меру возможности иногда выполняет девиртуализацию). И возникает косвенный уровень доступа. Напр., пусть для некоего прикладного "агрегата" необходимо адаптировать "деталь" -- некий Reader нуждается в доступе к владеющему им "агрегату" (конкретный тип "детали" знает, как работать с "агрегатом" заданного типа и нуждается в доступе к состоянию объекта-"агрегата"):
Код:
TYPE
    MyReader = POINTER TO RECORD (Reader)
        ...
        MyData: POINTER TO MyRec;
        ...
    END;

Может быть через средства метаинформации возможны и некоторые универсальные операции в "деталях" (т.е., без контрактов типов, через ANYPTR, возможна реализация универсальных "деталей" для типов определенного вида, без привязки к конкретным предметным типам в разрезе некоторых общих операций). Однако, в любом случае возникает потребность иметь ссылку на "агрегат", следовательно, типы-"агрегаты" обречены быть только объектами в куче, создаваемыми через NEW с необходимостью получения указателя. Что влечёт соответствующие последствия (напр., организация коллекций объектов вынужденно через косвенный доступ и т.д.).

Тем не менее, моделирование требуемой предметки возможно, и такие означенные характеристики решения задач вполне могут быть удовлетворительными во многих случаях, но не абсолютно во всех.

Альтернативные принципы типизации в виде понятия пересечений и объединений типов в своей основе, особо то, не сложнее понятия наследования/расширения (изложения выше в теме, конечно же, напрашиваются причесаться и в целом адекватно быть сформулированными).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 01 Февраль, 2019 19:48 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
К вопросу ранее: "Что параметризовать: процедуры и типы или сразу модули". Нашлись идеи насчёт возможного простого варианта параметризации модуля:
https://forum.oberoncore.ru/viewtopic.php?f=30&t=5366&start=20

В целом, если параметризовать только модуль, с целью упрощения, то без гранулярности на уровне типов/операций теряются некоторые возможности. Напр, существует параметризация, фактически, задаваемая не извне, а возникающая изнутри типа посредствам операций. Пример на том же Rust -- "branding pattern":
https://pcwalton.github.io/2012/12/26/typestate-is-dead.html

, где тип для работы с файлом параметризуется "фантомными" структурами, тем самым делается попытка статически контролировать последовательность операций (в рамках поддержки статической "тотальности" типизации). В статье указана причина, почему из языка выкинули средства т.н. typestate, изначально предназначенные для решения таких задач. Теперь необходима эмуляция (если, конечно же, пользователю вообще нужна такая забота), неэффективная, поскольку объекты в императивном языке не могут изменять свой тип (из-за чего typestate и ликвидировали, во всяком случае до лучших времён), возникает потребность протаскивать состояние данных через разные (разных типов) переменные/параметры (в тривиальных случаях копирования или передачи аргументов и возврата результатов функций компилятор может оптимизировать).

В IT известны попытки решения проблематики т.н. typestate, прежде всего, в функциональщине с зависимыми типами, но со своими особенностями и ограничениями. В одной из вариаций Lustre имеется мощная поддержка протоколов типа, где допустимая последовательность операций может быть не только задана явно разработчиком, но и автоматически выведена по коду, в рамках общего вывода типов, типичного для ML-подобных (т.е. на тестовых программках протокол типа формируется автоматически (после проверок вплоть до полной верификации), и затем используется далее). Но Lustre не императивный универсальный язык.
Для императивного языка было решение у Microsoft -- когда-то у них был свой "безопасный" диалект С -- Vault (сайта уже нет, необходимо искать в инете следы), аналог Cyclone, который даже где-то там использовался при реализации драйверов, где-то для DirectX и пр. Там применялись "регионы" (в т.ч. для непосредственного управления памятью), и состояние типов контролировалось через метки региона (тип объектов не изменяется). Объект представляется как виртуальный автомат с определенными состояниями, над которым совершаются операции. Речь о виртуальных состояниях, эти состояния не обязательно связаны с реальным значением объекта ("физическое" значение переменной/параметра). Напр., какой-то дескриптор ресурса может не изменяться при операциях (его собственное значение не изменяется), некие изменения могут быть во внешней среде.
Стиль оформления протоколов был такой:
Вложение:
vertex.png
vertex.png [ 58.65 КБ | Просмотров: 6091 ]

Через tracked(...) задаётся "регион" и в сигнатурах операций указываются требования соответствия виртуальному состоянию и его возможное изменение. Компилятор контролирует следование операций с помеченным объектом, по тем же принципам (в некоторых компиляторах), когда выявляется доступ к ещё не инициализированной переменной или после потери валидности у переменной и т.п. Виртуальные состояния не заменяют "физические" состояния объектов, т.е. значения объектов могут быть разными, ошибочными и положительными и т.д., и операции должны учитывать такой факт, как обычно. В случаях, когда компилятор не может (статически) определить точное возможное состояние (из-за вариативности кода, т.е. наличие if-ов и т.п.), возникает потребность в "служебных" операциях (возможно и тривиальных, после оптимизации игнорируемых в runtime), принимающих объект в некоторых различных возможных состояниях и задающих результатное состояние.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 76 ]  На страницу Пред.  1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB