OberonCore https://forum.oberoncore.ru/ |
|
Mini Component Pascal https://forum.oberoncore.ru/viewtopic.php?f=29&t=494 |
Страница 1 из 3 |
Автор: | Trurl [ Пятница, 01 Июнь, 2007 14:46 ] |
Заголовок сообщения: | Mini Component Pascal |
Как вам сабж? http://plas.fit.qut.edu.au/generics/mcp |
Автор: | Wlad [ Пятница, 01 Июнь, 2007 14:55 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Они шо, наши темы в КД и здесь читали? :о))) |
Автор: | Wlad [ Пятница, 01 Июнь, 2007 15:10 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Код: MODULE GListMod;
TYPE GList<X:PIDisplayable> = EXTENSIBLE RECORD (ANYREC + IDisplayable) head: X; tail: PGList<X>; END; PGList<X:PIDisplayable> = POINTER TO GList<X:PIDisplayable>; (* ... *) VAR list: PGList<PInteger>; helper: PHelper; head: PInteger; (* ... *) BEGIN (* ... *) list.head := helper.NewPInteger(5); list.Insert(helper.NewPInteger(10)); (* ... *) head := list.Head(); util.WriteInt(head.val); END ListMod. Оно-то красиво, да вот узнать бы, какова у них в системе времени исполнения идеология местонахождения параметризованных классов? Они так же множат одинаковые инстанции по разным модулям, или таки оптимизируют этот процесс и только по-одному на систему хранят? Если да - каков механизм "учёта, контроля и слежения"? |
Автор: | Trurl [ Пятница, 01 Июнь, 2007 15:34 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): Они так же множат одинаковые инстанции по разным модулям, или таки оптимизируют этот процесс и только по-одному на систему хранят?
Так же - это как C++? Вряд-ли. Почти никто таким путем не идёт. |
Автор: | Wlad [ Пятница, 01 Июнь, 2007 15:43 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Смотрите: есть объявление прототипа. И мы объявили, что именно этот модуль гарантирует предоставление функционаьности для всех вариантов настройки данного прототипа. По правилам наши алгоритмы, используемые в генериках настолько обобщены (сам принцип подхода!), что нам не важно внутреннее содержание типов-аргументов параметризации. Так, что получается, что мы просто объявляем подобие "настраиваемой фабоики", генерирующей "законченные" типы. И, естественно, что хранить она будет их у себя, в модуле, где генерик объявлен. Хотя, с другой стороны, ведь система не знает какие типы будут аргументами генериков, как же она будет память распределять для элементов? Как они обошли требование иметь исходники в момент компиляции, что бы "составить мнение" о арактеристиках классов-аргументов параметров? Но дублирования кода всегда будут! И В памяти ( в десятках модулей ) будет, например, десятки инстанций HackedArray<INTEGER>... Получается, что - наоборот, инстанцирование (в случае требования сохраннения обероновского подхода к раздельной компиляции) лучше проводить в тех модулях, где объявляются типы-аргументы? Или, иначе в памяти каждый раз будет перкомпилированный модуль с генериками??? |
Автор: | Алексей Елин [ Среда, 06 Июнь, 2007 11:20 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): Так, что получается, что мы просто объявляем подобие "настраиваемой фабоики", генерирующей "законченные" типы. И, естественно, что хранить она будет их...
Вовсе не обязательно. Есть альтернативный подход к реализации generics на основе "итрефейсов". Не даром "IMCPG is an extension of IMCPI". Упрощенно суть в том, что для типов используемых в generics (генериках) создаются интерфейсы с набором операций - методов. Вызовы именно этих методов ОДНОКРАТНО компилирются в модуле где реализован генерик. При работе с "инстанцированным" типом происходит скрытое получение интерфейсов конкретных "клиентских" экземпляров, с проверкой типов на эпате компиляции использующего генерик модуля (т.е. исходный текст генерика не требуется). Если при этом интерфейсы "фиксированы" (т.е. набор используемях в генерике операций заранее оговорен) - они могут быть заранее созданы по одному для каждого типа. Таким образом все компилируется ОДНОКРАТНО для каждого типа (а не для пары <генерик - тип>). По этому принципу реализовано несколько эмуляций "STL" для Delphi, естественно на основе интерфейсов. |
Автор: | Wlad [ Среда, 06 Июнь, 2007 11:34 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Алексей Елин писал(а): Есть альтернативный подход к реализации generics
Но, тогда это - не генерики, или "не совсем генерики"... Смотрите, получается, что все типы, которые возможно будут служить в качестве аргументов при параметризации генерик-классов, должны заранее быть некоего "типа" (с набором интерфейсных функций), позволяющего использовать его внутри обобщённых функций генерика... К тому же, если мы говорим о генерик-коллекциях, применительно к модели оберонов - мне не совсем понятно, как вы будете (при таком подходе) хранить в коллекциях экземпляры, а не ссылки? Смысл-то как раз в том, что инстанцируется (доопределяется) генерик-коллекция на этапе компиляции потому, что становится известным размер типа-аргумента и "начинается пляска от печки", а как в случае оберонов? - модуль-то с "заготовкой" генерик-коллекции уже в объектном коде... Пока мне не всё здесь ясно... Может это просто именно мне не ясно? Надо обговаривать... |
Автор: | Алексей Елин [ Среда, 06 Июнь, 2007 11:49 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): Смотрите, получается, что все типы, которые возможно будут служить в качестве аргументов при параметризации генерик-классов, должны заранее быть некоего "типа" (с набором интерфейсных функций), позволяющего использовать его внутри обобщённых функций генерика... Это и есть интерфейсы. Суть интерфейса - возможность рассматривать ЛЮБОЙ тип как объект ДРУГОГО (интерфейсного) типа с ДРУГИМ "набором интерфейсных функций". Wlad писал(а): как вы будете (при таком подходе) хранить в коллекциях экземпляры, а не ссылки?
Есть несколько подходов. Самый простой - физически создавать именно ссылки, а для пользователья представлять их как экземпляры (что то вроде _box-ing в .Net). Но можно менять и физический размер инстанцированного типа, что намного сложнее и требует поддержки со стороны среды выполнения. Есть и комбинированные подходы. |
Автор: | Wlad [ Среда, 06 Июнь, 2007 12:17 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Алексей Елин писал(а): Это и есть интерфейсы. Суть интерфейса - возможность рассматривать ЛЮБОЙ тип как объект ДРУГОГО (интерфейсного) типа с ДРУГИМ "набором интерфейсных функций". Это понятно. Но я говорил о том, что в случае "истинных генериков" (максимально обобщённых), у нас нет первичности производства генериков или типов аргументов для них. То есть ни типы-"аргументы" "не знают", будут ли они использоваться аргументами параметризации генериков, ни уж, тем более, генерики не знают про все типы, которыми они будут параметризироваться(конретизироваться)... Алексей Елин писал(а): Есть несколько подходов. Самый простой - физически создавать именно ссылки, а для пользователья представлять их как экземпляры (что то вроде _box-ing в .Net). ОЧЕНЬ не эффективно в смысле быстродействия... Алексей Елин писал(а): Но можно менять и физический размер инстанцированного типа, что намного сложнее и требует поддержки со стороны среды выполнения. МЕНЯТЬ? Скорее всего, вы имели в виду «производить, скорее всего новые варианты инстанцирования»? Возникают вопросы - «где»? На стороне модуля-обявителя генерика или в модуле, где генерик параметризуется? Если второй вариант – как избежать дублирования инстанцирования одинаковыми типами, что бы не было неэффективности по памяти? И ещё одна проблема. Типобезопасность. Я понимаю, как она решается в случае Си++ - там время компиляции. А вот в уже скомпилированном модуле это проверять? Даже по предлагаемому вами варианту? Придумывать «увязку с компилятором» для проверок? Алексей Елин писал(а): Есть и комбинированные подходы.
Какие? |
Автор: | Алексей Елин [ Среда, 06 Июнь, 2007 12:53 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): "истинных генериков" (максимально обобщённых), у нас нет первичности производства генериков или типов аргументов для них. В случае использования интерфейсов первичность есть. Ограничивается лишь набор операций с экземплярами типов-аргументов. И все. Любой экземпляр любого типа (в т.ч. и "инстанцированного") может быть представлен как некоторый "стандартный" интерфейс и может использоваться в качестве типа-аргумента. Большая "истинность" может быть достигнута лишь в смысле макроподстановок, когда инстанцирование происходит в контексте конкретного исходного текста, с учетом полиморфизма операций языка и контекстно зависимых вызовов неполиморфных функций для типов-аргументов. Wlad писал(а): Алексей Елин писал(а): Есть несколько подходов. Самый простой - физически создавать именно ссылки, а для пользователья представлять их как экземпляры (что то вроде _box-ing в .Net). ОЧЕНЬ не эффективно в смысле быстродействия... Менее эффективно чем макроподстановки, но все же не так провально, а в некоторых случаях вообще без потерь. Wlad писал(а): Алексей Елин писал(а): Но можно менять и физический размер инстанцированного типа, что намного сложнее и требует поддержки со стороны среды выполнения. МЕНЯТЬ? Скорее всего, вы имели в виду «производить, скорее всего новые варианты инстанцирования»? Нет. Я имел в виду менять физический размер экземпляра. А так называемое "инстанцирование" происходит лишь однажды (при компиляции генерика и в модуле генерика), но особым образом, с учетом "динамической природы" экземпляров типов-аргументов. В исползовании "динамических" полей и состоит поддержка со стороны среды выполнения. Wlad писал(а): И ещё одна проблема. Типобезопасность. Я понимаю, как она решается в случае Си++ - там время компиляции. А вот в уже скомпилированном модуле это проверять? Даже по предлагаемому вами варианту? Придумывать «увязку с компилятором» для проверок? Если делать "в лоб" - то все просто (добавить код динамической проверки типов и всё), но в реальности проверку делают статически на этапе компиляции. Если подумать - никакой проблемы типобезопасности нет. Грубо говоря - что положили, то и взяли. Если экземпляр связан с типом-аргументом, то компилятор разрешает работать экземпляру только с соответствующим типом-параметром. Wlad писал(а): Алексей Елин писал(а): Есть и комбинированные подходы. Какие? Например тот-же боксинг, но выделение памяти происходит одновременно (в том же блоке) с выделением памяти экземпляру генерика (как статически, так и динамически). |
Автор: | Wlad [ Среда, 06 Июнь, 2007 14:09 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Алексей Елин писал(а): В случае использования интерфейсов первичность есть. Какая? Взять коллекции – ни они не знают, что в них помещаться будет, в смысле типов, ни сами элементы не знают, что их туда помещать будут. Коллекция, единственно, должна владеть размером, если хранит не ссылки, а сами элементы... Алексей Елин писал(а): Менее эффективно чем макроподстановки, но все же не так провально, а в некоторых случаях вообще без потерь. В смысле провально? Катастрофично? Или с задержками? Ну так, а чем померить, когда «медленно», а когда – нет? А в случае ссылок, в , как ни крутите, дополнительную косвенность по обращению вводите. Для нескольких элементов это, может быть, и не так заметно, а когда графику или «мелкопорциальные» потоки данных обрабатываете – уже начинаете искать спасения... Алексей Елин писал(а): Нет. Я имел в виду менять физический размер экземпляра. А так называемое "инстанцирование" происходит лишь однажды (при компиляции генерика и в модуле генерика), но особым образом, с учетом "динамической природы" экземпляров типов-аргументов. В исползовании "динамических" полей и состоит поддержка со стороны среды выполнения.
Опять не понимаю. Гипотетический пример. Код: MODULE A; OBJECT FixedLengthArray<ItemType, CONST N:INTEGER> items: ARRAY N OF ItemType; ... END FixedLengthArray; И у меня есть два объявления: Код: MODULE B; VAR ArrayOfInt: FixedLengthArray<INTEGER,25>; ArrayOfFloat: FixedLengthArray<REAL,100>; Если мы храним не ссылки, то объясните мне, как у меня один и тот же экземпляр коллекции в одном и том же месте памяти может обрабатывать объект с разным объёмом занимаемой памяти? Другое дело, что я понимаю, что (НАПРИМЕР), в модуле A я строю нормально vtbl (или просто ссылки на процедуры, если методы – невиртуальные), НО! В A «некоторые» методы или процедуры (назовём их «вспомогательными»), необходимые для непосредственной обработки обращения к элементам НЕ ОПРЕДЕЛЕНЫ. При объявлении же конкретных массивов, объявляются (в данном случае – анонимные) типы, в которых эти процедуры уже определены. Здесь уже вопросов нет. Мы и гибкость получили, и проверки во время компиляции по типам. Кстати, начинают проясняться мои непонятки (вот пока сам не начнёшь рассуждать... :о) ) с «где инстанцировать»? Наверное я не очень понятно объяснил. Я имел в виду «построение» «инфраструктуры поддержки типа». То есть «тэговой структуры» для инстанцированного от генерика типа. В принципе, больших потерь от дублирующих объявлений, навроде Код: MODULE M1;
VAR ArrayOfInt: FixedLengthArray<INTEGER,25>; ... MODULE M2; VAR ArrayOfInt: FixedLengthArray<INTEGER,25>; ... ... не привнесёт, я думаю. В крайнем случае, остаётся на кого-нибудь упражнение в программировании, для создания «реестра инстанцированных типов», в котором бы были ссылки на описания типы («тэговые структуры»), которые уже были инстанцированы. Там же можно и хранить инфу для компилятора и загрузчика... Но, тогда надо скорректировать идеологии изменения счётчиков клиентов модулей... |
Автор: | Иван Горячев [ Среда, 06 Июнь, 2007 15:14 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): Если мы храним не ссылки, то объясните мне, как у меня один и тот же экземпляр коллекции в одном и том же месте памяти может обрабатывать объект с разным объёмом занимаемой памяти?
В принципе во "вспомогательные" процедуры можно скрыто передавать размер элемента. |
Автор: | Алексей Елин [ Среда, 06 Июнь, 2007 15:26 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): В смысле провально? Катастрофично? Или с задержками? Ну так, а чем померить, когда «медленно», а когда – нет? А в случае ссылок, в , как ни крутите, дополнительную косвенность по обращению вводите. В том смысле, что с "задержками" и именно с разыменованием указателя (как в случае с боксингом). Если данные ссылочные - задержек нет. Если структуры - дополнительное, скрытое от программиста разыменование. Wlad писал(а): Гипотетический пример. Код: MODULE B; VAR ArrayOfInt: FixedLengthArray<INTEGER,25>; ArrayOfFloat: FixedLengthArray<REAL,100>; Если мы храним не ссылки, то объясните мне, как у меня один и тот же экземпляр коллекции в одном и том же месте памяти может обрабатывать объект с разным объёмом занимаемой памяти? А так что тут у вас ДВА ЭКЗЕМПЛЯРА естественно в РАЗНЫХ областях памяти, но одного генерик типа FixedLengthArray. Один называется ArrayOfInt а другой ArrayOfFloat. Для одного выдляется X+25*4 байт, а на другой X+100*8 байт. А обрабатывать, например, также как динамические и открытые массивы. Wlad писал(а): Я имел в виду «построение» «инфраструктуры поддержки типа». То есть «тэговой структуры» для инстанцированного от генерика типа. Вот и я про то же - В ЭКЗЕМПЛЯРЕ генерик типа. Wlad писал(а): В крайнем случае, остаётся на кого-нибудь упражнение в программировании, для создания «реестра инстанцированных типов», Не нужно никакого реестра - сам экземпляр и есть запись об инстанцировании. Wlad писал(а): Но, тогда надо скорректировать идеологии изменения счётчиков клиентов модулей...
И не только это. Так просто ЭТО к ББ, например, не прикрутить. |
Автор: | Wlad [ Среда, 06 Июнь, 2007 15:27 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Ivor писал(а): В принципе во "вспомогательные" процедуры можно скрыто передавать размер элемента. Зачем? В виртуальные методы вы только указатель на объект передаёте... Ivor писал(а): Можно ничего не хранить. Тэг типа у всех экземпляров одного дженерика одинаковый, но в дополнительном поле указывать тэги всех его параметров.
Тэг типа у обектов-экземпляров конкретизированных генериков НЕ МОЖЕТ БЫТЬ ОДИНАКОВЫМ. 1)FixedArray<ItemType,CONST N:INTEGER> - это один тип 2)FixedArray<INTEGER,15> - другой 3)FixedArray<INTEGER,16> - третий 4)FixedArray<REAL,16> - третий Это – РАЗНЫЕ ТИПЫ. Более того, как такового, типа FixedArray<ItemType,CONST N:INTEGER> в системе для программиста НЕ СУЩЕСТВУЕТ НИ ПОД КАКИМ ВИДОМ! Он - «недоделанный» ( с «недоделанными» «вспомогательными» процедурами обращения к элементам ). А вот 2) – 4) - «готовые к употреблению», со всеми «заполнеными» полями ссылок на «вспомогательные» процедуры. Кстати – да, «незаполненные» ссылки в некоей таблице ( той же vtbl ) как раз могут быть заполнены в «конкретизированных» «потомках». С «конкретизацией» константы в объявлении типа надо подумать. Может это просто - возвращение числа-размера из некоего вспомогательного кода при размещении экземпляра коллекции? (и становится не важно, КУДА это возвращается: то ли в код динамического размещения в куче, то ли выделения места на стеке для статических объектов... :о) ) «Теплее, однако-сь!» Всем – спасибо за участие в обсуждении! |
Автор: | Иван Горячев [ Среда, 06 Июнь, 2007 15:46 ] |
Заголовок сообщения: | |
Wlad, про одинаковый тэг это я глупость сморозил. Тут же убрал, ан успели заметить По поводу дублей и реестра. Вообще ведь согласно правилам языка Код: MODULE M1;
VAR ArrayOfInt1: FixedLengthArray<INTEGER,25>; ArrayOfInt2: FixedLengthArray<INTEGER,25>; ... имеют разные типы, и описания этих типов должны храниться отдельно. Так что реестр просто не нужен. |
Автор: | Trurl [ Среда, 06 Июнь, 2007 16:00 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): ОЧЕНЬ не эффективно в смысле быстродействия...
Всякие там хаскели и окамлы обходятся. |
Автор: | Trurl [ Среда, 06 Июнь, 2007 16:07 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Wlad писал(а): Зачем? В виртуальные методы вы только указатель на объект передаёте...
В C++ только указатель, а в Обероне ещё и дескриптор типа. |
Автор: | Wlad [ Среда, 06 Июнь, 2007 16:36 ] |
Заголовок сообщения: | |
Ivor писал(а): По поводу дублей и реестра. Вообще ведь согласно правилам языка
Код: MODULE M1; VAR ArrayOfInt1: FixedLengthArray<INTEGER,25>; ArrayOfInt2: FixedLengthArray<INTEGER,25>; ... имеют разные типы, и описания этих типов должны храниться отдельно. Так что реестр просто не нужен. Хочу привлечь ваше внимание к одному тонкому моменту! Да это - РАЗНЫЕ типы в плане совместимости по типам согласно правил КП. Но! это - ОДИНАКОВЫЕ инстанции-параметризированные типы генерика в смысле РЕАЛИЗАЦИИ (генерика)! Нет смысла "разбрасываться" памятью на дублирование одних и тех же "всопомогательных" структур! |
Автор: | Wlad [ Среда, 06 Июнь, 2007 16:40 ] |
Заголовок сообщения: | Re: Mini Component Pascal |
Trurl писал(а): Wlad писал(а): Зачем? В виртуальные методы вы только указатель на объект передаёте... В C++ только указатель, а в Обероне ещё и дескриптор типа. Кажецо я что-то упустил или запамятовал? Разве в метод (виртуальный) первым невидимым параметром не достаточно передать указатель на экземпляр объекта? Насколько я знаю, тэг извлекается именно из места, рядом с расположением структуры виртуальной таблицы данного класса... Я не прав, что-то поменялось или я что-то напутал? Или тег - это и есть указатель на область памяти с vtbl + ещё мишура чуть ниже прямо перед vtbl. |
Автор: | Алексей Елин [ Среда, 06 Июнь, 2007 17:18 ] |
Заголовок сообщения: | |
Wlad писал(а): Код: MODULE M1; VAR ArrayOfInt1: FixedLengthArray<INTEGER,25>; ArrayOfInt2: FixedLengthArray<INTEGER,25>; ... Хочу привлечь ваше внимание к одному тонкому моменту! Да это - РАЗНЫЕ типы в плане совместимости по типам согласно правил КП. Но! это - ОДИНАКОВЫЕ инстанции-параметризированные типы генерика в смысле РЕАЛИЗАЦИИ (генерика)! Действительно, это так. Это ОДИНАКОВЫЕ типы - FixedLengthArray. Если точнее, то в объекте хранится ссылка на десриптор одного и того же типа FixedLengthArray. Но и в более раннем примере: Код: MODULE M1;
VAR ArrayOfInt1: FixedLengthArray<INTEGER,25>; ArrayOfInt2: FixedLengthArray<FLOAT,100>; ... типы тоже могут быть одинаковыми - генерик тип FixedLengthArray. Нет никакой причины запрещать для нескольких экземпляров генерик типа, даже с разными параметрами, ссылаться на один и тот же тип (дескриптор типа). |
Страница 1 из 3 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |