Oberon space
General Category => Общий раздел => Тема начата: ilovb от Апрель 05, 2012, 01:52:34 pm
-
Сразу признаюсь что интерес у меня праздный.
Не могу никак понять. Как можно сделать контейнер, позволяющий в качестве ключа хранить POINTER, чтобы при этом был быстрый поиск?
-
Как можно сделать контейнер, позволяющий в качестве ключа хранить POINTER, чтобы при этом был быстрый поиск?
Если сборщик мусора не перемещающий, то можно рассматривать POINTER как INTEGER. Вот и все дела.
-
Я правильно понимаю, что для этого нужно SYSTEM импортировать?
И кстати не менее интересно как быть если сборщик перемещающий? :)
Ну т.е. мне вообще интересно как в безопасных языках такие контейнеры делают? Где почитать можно?
-
Замечу, что на SYSTEM закладываться не стоит, ибо в некоторых реализациях его может не быть, или он может быть другим.
-
Вот я потому и спрашиваю ;)
-
Ну т.е. мне вообще интересно как в безопасных языках такие контейнеры делают? Где почитать можно?
Скорее вы найдете чтиво о том - насколько важно НЕ ДЕЛАТЬ этого (без крайней необходимости) ;D и я согласен с ними...низкоуровневые преобразования типов (или что ЕЩЕ ХУЖЕ неявные преобразования) - удел низкоуровневых небезопасных яп
-
Дык вот в том и вопрос. :) Ассоциативный контейнер довольно полезная штука. И нужен он чаще в безопасных языках, чем в сях например. А в безопасных языках с POINTERами трабл, т.к. их нельзя сравнивать...
Опять же в жабах такой контейнер есть на сколько я знаю. А как он работает то? ??? Не линейный поиск ведь там...
-
Так я же специально описал в топике про 10 миллионов строк КАК это делается (в примитивном варианте) - что непонятно?
-
Ваще не понял ;D
Вы о чем? Какая связь с той веткой?
-
Ваще не понял ;D
Вы о чем? Какая связь с той веткой?
:o Прямая
-
Там описано как безопасные поинтеры индексировать/хэшировать? ???
-
Там описано как безопасные поинтеры индексировать/хэшировать? ???
Там кэшируется ЗНАЧЕНИЕ а не указатель... (ключ а не адрес , по которому он хранится)
-
Сам указатель хранится в массиве....
-
Так в массиве то его тоже сначала найти нужно ;)
Понятно, что запихав указатель в массив, мы получим индекс, который будем хышыровать.
Но контейнеру то я указатель буду совать... Как он узнает индекс этого указателя в массиве?
p.s. Или я чего-то не понимаю...
-
Может мы о разном говорим?
Я говорю об ассоциативном контейнере:
ПСЕВДОКОД:
Пер:
Чувак: Указатель на запись: Имя: СТРОКА, пол: Пол;
Возраст: Ассоциативный контейнер;
Код:
Новый(Чувак);
Чувак.Имя = "Вася";
Чувак.пол = Пол.Мужской;
Возраст.Вставить(Чувак, 50);
Результат = Возраст.Найти(Чувак);
Конец;
-
Так в массиве то его тоже сначала найти нужно ;)
Понятно, что запихав указатель в массив, мы получим индекс, который будем хышыровать.
Но контейнеру то я указатель буду совать... Как он узнает индекс этого указателя в массиве?
p.s. Или я чего-то не понимаю...
Нет мы хешируем ЗНАЧЕНИЕ(ключ, в том топике строку (набор литер)) результат этой операции число-которое служит индексом ячейки в которой будет храниться адрес контейнера (содержащего сам ключ..)
-
Может мы о разном говорим?
Я говорю об ассоциативном контейнере:
ПСЕВДОКОД:
Пер:
Чувак: Указатель на запись: Имя: СТРОКА, пол: Пол;
Возраст: Ассоциативный контейнер;
Код:
Новый(Чувак);
Чувак.Имя = "Вася";
Чувак.пол = Пол.Мужской;
Возраст.Вставить(Чувак, 50);
Результат = Возраст.Найти(Чувак);
Конец;
ДА о разном -я говорю о ассоциативном контейнере (ключ (а поскольку он уникален, то и весь контейнер) ассоциируюется с индексом), вы не знаю...
-
Я не понимаю о чем вы говорите. У меня наверно пятничный тупняк ;D
Вот в моем примере как вы Чувака хэшировать будете?
-
Я не понимаю о чем вы говорите. У меня наверно пятничный тупняк ;D
Вот в моем примере как вы Чувака хэшировать будете?
У меня ЧУВАК - это ЗАПИСЬ- и это естественно - у вас это указатель (за это на любом собеседовании бан)...Я буду кэшировать Поле (значение которое хранится -напр. имя) ЗАПИСИ, а хранить в массиве - указатель на ЗАПИСЬ (т.е чувака в ВАШЕМ понимании).
-
Вот в моем примере как вы Чувака хэшировать будете?
А, так значит речь не о хэшировании указателя, а о хэшировании объекта на который он указывает. Это другое. Тогда базовый класс этого объекта должен иметь виртуальную функцию возвращающую хэшкод. А в конкретном наследнике эта виртуальная функция должна быть переопределена, поскольку как хэшировать Чувака знает лишь сам класс Чувака. Так же должна быть виртуальная функция для выяснения равенства двух объектов.
-
Я про базовый класс тоже думал. Получается что в контейнер можно помещать только объекты имеющие такой базовый класс. А с остальными пролет....
Хотя с множественным наследованием наверно можно.
-
Вот в моем примере как вы Чувака хэшировать будете?
А, так значит речь не о хэшировании указателя, а о хэшировании объекта на который он указывает. Это другое. Тогда базовый класс этого объекта должен иметь виртуальную функцию возвращающую хэшкод. А в конкретном наследнике эта виртуальная функция должна быть переопределена, поскольку как хэшировать Чувака знает лишь сам класс Чувака. Так же должна быть виртуальная функция для выяснения равенства двух объектов.
Вообще говоря , кэшируется последовательность байт (это всего лишь отображение одной последовательности байт на другую ( обычно фиксированного количества)... а там что хотите...хоть указатель, хоть ВЕСЬ обьект (все байты в которых закодированы ЗНАЧЕНИЯ всех полей), хоть значение ОДНОГО поля обьекта...
-
за это на любом собеседовании бан
Э?
-
Вообще говоря , кэшируется последовательность байт (это всего лишь отображение одной последовательности байт на другую ( обычно фиксированного количества)... а там что хотите...хоть указатель, хоть ВЕСЬ обьект (все байты в которых закодированы ЗНАЧЕНИЯ всех полей), хоть значение ОДНОГО поля обьекта...
Вы для каждого типа предлагаете свой контейнер писать?
-
за это на любом собеседовании бан
Э?
Да, извините - просто жутко такого рода вещи достали- от студентов... это не у Вас, а у меня "пятничный" синдром :(, определенно
-
бывает :)
Всех с тяпницей!
Напьюсь сёдня нафик. 8)
-
Вот в моем примере как вы Чувака хэшировать будете?
А, так значит речь не о хэшировании указателя, а о хэшировании объекта на который он указывает. Это другое. Тогда базовый класс этого объекта должен иметь виртуальную функцию возвращающую хэшкод. А в конкретном наследнике эта виртуальная функция должна быть переопределена, поскольку как хэшировать Чувака знает лишь сам класс Чувака. Так же должна быть виртуальная функция для выяснения равенства двух объектов.
Да. Именно поэтому в Java у класса Object (от которого наследуются все остальные) есть метод int hashCode(). Без этого никак.
-
Вообще говоря , кэшируется последовательность байт (это всего лишь отображение одной последовательности байт на другую ( обычно фиксированного количества)... а там что хотите...хоть указатель, хоть ВЕСЬ обьект (все байты в которых закодированы ЗНАЧЕНИЯ всех полей), хоть значение ОДНОГО поля обьекта...
Вы для каждого типа предлагаете свой контейнер писать?
Зависит от задачи (и от яп)- степень поддержки обобщенного программирования в различных ЯП(так же как и "штатные" средства) -различна, а что вас смущает? - Обероны далеко не лучший вариант (это вроде всем известно).
-
Да. Именно поэтому в Java у класса Object (от которого наследуются все остальные) есть метод int hashCode(). Без этого никак.
"Вот оно че, Михалыч!" ;D
Обероны в пролете короче :)
-
Т.е. чтобы эти плюшки кушать, оно в языке должно быть изначально прошито. (В жабе Object часть языка?)
-
Да. Именно поэтому в Java у класса Object (от которого наследуются все остальные) есть метод int hashCode(). Без этого никак.
"Вот оно че, Михалыч!" ;D
Обероны в пролете короче :)
Так по этому и речь ведем об области его эффективного использования - что бы в "дерьмо" не попасть, случайно...
это здесь - а у коровцев один ответ -лучше оберонов ничего нет...
-
Да. Именно поэтому в Java у класса Object (от которого наследуются все остальные) есть метод int hashCode(). Без этого никак.
"Вот оно че, Михалыч!" ;D
Обероны в пролете короче :)
В обероне придется вводить родительсный тип типа Hashable, у которого будет подобный "метод". Соответственно все желающие хэшироваться должны будут наследоваться оттуда. Но возникает проблема - в Обероне нет множественного наследования. Ни множественного наследования реализаций, ни интерфейсов. Поэтому если у типа есть еще какое-то свойство (Drawable например), то придется либо Hashable наследовать от Drawable, либо наоборот. И то и другое смотрится как-то искусственно.
-
Т.е. чтобы эти плюшки кушать, оно в языке должно быть изначально прошито. (В жабе Object часть языка?)
В жабе Object да, часть языка.
Это не обязательно должно быть прошито в языке, можно используя другие механизмы это реализовать. Гм. Ну, например в этот контейнер передавать не только объекты, но и функцию которая из них будет делать хэш. В принципе, тут и наследование не особо нужно.
-
Да. Это вариант. Хотя не особо удобно конечно.
-
Да. Именно поэтому в Java у класса Object (от которого наследуются все остальные) есть метод int hashCode().
Угу, а в C# она int System.Object.GetHashCode().
-
Это не обязательно должно быть прошито в языке, можно используя другие механизмы это реализовать. Гм. Ну, например в этот контейнер передавать не только объекты, но и функцию которая из них будет делать хэш. В принципе, тут и наследование не особо нужно.
Мало... нужно иметь в языке обобщенный указатель (для определения типа ячейки в ассоциативном массиве совместимого по присваиванию с произвольным типизированным указателем) - в КП есть AnyPtr - а в простых Оберонах вроде нет - может кто поправит?
-
Это не обязательно должно быть прошито в языке, можно используя другие механизмы это реализовать. Гм. Ну, например в этот контейнер передавать не только объекты, но и функцию которая из них будет делать хэш. В принципе, тут и наследование не особо нужно.
Мало... нужно иметь в языке обобщенный указатель (для определения типа ячейки в ассоциативном массиве совместимого по присваиванию с произвольным типизированным указателем) - в КП есть AnyPtr - а в простых Оберонах вроде нет - может кто поправит?
Нужно. Но это уже существенно меньшая проблема.
-
Нужно. Но это уже существенно меньшая проблема.
Почему если его нет (как и других специализированных средств - например , нетипизированного указателя) - остается только шаболон с использованием общего предка (а уж вшит он в ЯП или нет... вопрос конкретного ЯП) или я ошибаюсь?
-
Но возникает проблема - в Обероне нет множественного наследования. Ни множественного наследования реализаций, ни интерфейсов. Поэтому если у типа есть еще какое-то свойство (Drawable например), то придется либо Hashable наследовать от Drawable, либо наоборот. И то и другое смотрится как-то искусственно.
Множественное наследование всегда можно сделать вручную (как в C ;)
Object.QueryInterface() - и вперед.
-
Но возникает проблема - в Обероне нет множественного наследования. Ни множественного наследования реализаций, ни интерфейсов. Поэтому если у типа есть еще какое-то свойство (Drawable например), то придется либо Hashable наследовать от Drawable, либо наоборот. И то и другое смотрится как-то искусственно.
Множественное наследование всегда можно сделать вручную (как в C ;)
Object.QueryInterface() - и вперед.
Приведи на Обероне реализацию, плиз. Object.QueryInterface это ж вроде как ни разу не Си, это С++.
-
Далее.. функцию хэширования в примитивном случае нам передавать не нужно... достаточно передать указатель на валидный объект - и ЗНАЧЕНИЕ возвращаемое этой функцией(только для односторонне ассоциативного массива) - в этом случае наш контейнер будет отличаться от обычного массива указателя лишь действиями по разрешению коллизий...
-
Ну и наконец ... можно использовать "встроенную" хэш - функцию общего вида (например CRC32 кодирование, со всеми "прелестями" такой методы) - хэшировать ВЕСЬ обьект.
-
Ну и наконец ... можно использовать "встроенную" хэш - функцию общего вида (например CRC32 кодирование, со всеми "прелестями" такой методы) - хэшировать ВЕСЬ обьект.
Что бы хешировать весь объект тебе нужно иметь возможность получить оный объект в виде куска памяти/массива байтиков. А в обероне такой возможности нет.
-
Правда тогда нужно передавать помимо указателя размер- в оберонах это не прокатит (без использования систем), вроде бы.
-
:) да вы успели запостить раньше чем я :)
-
Множественное наследование всегда можно сделать вручную (как в C ;)
Object.QueryInterface() - и вперед.
Приведи на Обероне реализацию, плиз. Object.QueryInterface это ж вроде как ни разу не Си, это С++.
Все наследуется от базового Object, у которого есть перегружаемый QueryInterface. Допустим у наc есть объект Object -> Drawable и его надо положить в контейнер, который хочет Object -> Hashable:
1. Реализуем свой Object -> Hashable -> MyHashable, в котом есть ссылка на оригинальный Object -> Drawable
2. У MyHashable реализуем QueryInterface, который умеет возвращать оригинальный Object -> Drawable.
3. Кладем в контейнер.
4. Когда надо вытащить из контейнера и получить оригинальный Object -> Drawable: вытаскиваем Hashable, вызываем у него QueryInterface, кастим результат к Drawable.
Все просто :) Только закат солнца вручную ;)
P.S. В С++ оно не надо - там есть dynamic_cast, который замечательно работает с множественным наследованием.
-
Приведи на Обероне реализацию, плиз. Object.QueryInterface это ж вроде как ни разу не Си, это С++.
Тут еще интересно, что использовать в качестве аргумента QueryInterface. Ручками назначать каждому интерфейсу идентификатор - это вообще ужос-ужос, так что без очередного расширизма не обойтись ;)
-
Все наследуется от базового Object, у которого есть перегружаемый QueryInterface. Допустим у наc есть объект Object -> Drawable и его надо положить в контейнер, который хочет Object -> Hashable:
Наверно тяжелый день... не врубаюсь в смысл употребляемого слова - наследование (вроде в СИ его нет), разумеется эту ситуацию можно смоделировать низкоуровневыми
средствами( других нет :) ) - вы это имеете ввиду?
-
Ярослав Романченко, некоторое время назад, выкладывал пример с контейнерами в А2 (обероны) на oberonCore. А я его немного развил (http://aos.madzi.ru/?q=node/26)
-
Ярослав Романченко, некоторое время назад, выкладывал пример с контейнерами в А2 (обероны) на oberonCore. А я его немного развил (http://aos.madzi.ru/?q=node/26)
На сколько я помню, там был тихий, типонебезопасный, ужас.
-
Ярослав Романченко, некоторое время назад, выкладывал пример с контейнерами в А2 (обероны) на oberonCore. А я его немного развил (http://aos.madzi.ru/?q=node/26)
На сколько я помню, там был тихий, типонебезопасный, ужас.
А что означает "типонебезопасный"?
-
Не было там никакого ужаса. Там был кастиг типов, и чтобы от него избавится я предложил свой вариант. В котором уже совсем нет приведения типов.
-
Не было там никакого ужаса. Там был кастиг типов, и чтобы от него избавится я предложил свой вариант. В котором уже совсем нет приведения типов.
А вот это может быть ужасом - если используется внутри контейнера... при определенный обстоятельствах... сборщик мусора может взять и посчитать ссылки хранящиеся в контейнере инвалидными... иными словами обьекты выпадают из поля зрения GK -ужас если речь идет об этом.
-
Не было там никакого ужаса. Там был кастиг типов, и чтобы от него избавится я предложил свой вариант. В котором уже совсем нет приведения типов.
А ты пробовал собирать тот код который у тебя там выложен?
Мне откровенно не понятно каким образом соберется вот это:
PROCEDURE TestList*();
VAR
list : ArrayList; (* можно заменить на LinkedList *)
long : Longint;
BEGIN
NEW(list);
ASSERT(list # NIL);
NEW(long);
long^.value := 13;
list.Add(long);
long := NIL;
KernelLog.String("List size: ");
KernelLog.Int(list.Size(), 4);
KernelLog.Ln();
long := list.Get(0);
KernelLog.String("Element value: ");
KernelLog.Int(long^.value);
KernelLog.Ln();
END TestList;
Тип возвращаемого значения Get - ListItem, а Longint - это потомок ListItem'a (Longint* = POINTER TO RECORD(ListItem);). Следовательно необходим апкастинг.
Кроме того, в этот ArrayList я могу положить не только LongInt а все что угодно другое унаследованное от ListItem'a, следовательно при апкастинге при доставании вылетит исключение во время исполнения приложения. Это и есть - не типобезопасно.
-
а что в Активе нет is, as?
-
а что в Активе нет is, as?
И is и as это приведение типов (апкастинг в данном случае). Если в списке будет лежать что-то не то, будет ошибка в рантайме. Её конечно можно обработать, но от этого не легче. Нет типобезопасности.
-
я это к чему - ну ошибка - она же в конечном примере...а не в реализации библиотеки.
-
а что в Активе нет is, as?
И is и as это приведение типов (апкастинг в данном случае). Если в списке будет лежать что-то не то, будет ошибка в рантайме. Её конечно можно обработать, но от этого не легче. Нет типобезопасности.
Что означает не то? -не потомок пустой записи? а как он туда попадет - где дырка в интерфейсе?
-
Что означает не то? -не потомок пустой записи? а как он туда попадет - где дырка в интерфейсе?
Означает что был у меня список int'ов, а какой-то гад туда окошко положил. И то и другое потомок ListItem'a, но при доставании у меня ВНЕЗАПНО случится не то что я хочу.
Это собственно ровно то, из за чего в java были введены (с версии 1.5) дженерики. Они делают контейнеры типобезопасными (на производительность в жабе это в общем то не влияет).
-
Что означает не то? -не потомок пустой записи? а как он туда попадет - где дырка в интерфейсе?
Означает что был у меня список int'ов, а какой-то гад туда окошко положил. И то и другое потомок ListItem'a, но при доставании у меня ВНЕЗАПНО случится не то что я хочу.
Это собственно ровно то, из за чего в java были введены (с версии 1.5) дженерики. Они делают контейнеры типобезопасными (на производительность в жабе это в общем то не влияет).
Алексей.... я считаю , что это не проблема ДАННОЙ реализации контейнера- обобщенка работающая чисто на наследовании имеет такой изьян, хотя можно пропихнуть кастомную CheckType(oblPtr:PEmptyPtr):BOOLEAN и потребовать ее реализацию при создании экземпляра коллекции - чтобы вылетело при попытке запихнуть что-то не то.... но это из другой оперы...
-
Максимум, что можно сделать, это через метаинформацию типа выудить тип первого добавленного элемента и требовать ассертом, чтобы все остальные элементы ему соответствовали. Так как Вирт не дал нам дженериков :)
-
Максимум, что можно сделать, это через метаинформацию типа выудить тип первого добавленного элемента и требовать ассертом, чтобы все остальные элементы ему соответствовали. Так как Вирт не дал нам дженериков :)
Почему - требуйте с пользователя обязательную реализацию метода PROCEDURE CheckType (obj :ListItem):BOOLEAN;
BEGIN RETURN Obj is Longint END CheckType;
(при добавлении проверяйте этой функцией фактический тип данных).
-
или я не прав ;)
-
Все наследуется от базового Object, у которого есть перегружаемый QueryInterface. Допустим у наc есть объект Object -> Drawable и его надо положить в контейнер, который хочет Object -> Hashable:
Наверно тяжелый день... не врубаюсь в смысл употребляемого слова - наследование (вроде в СИ его нет), разумеется эту ситуацию можно смоделировать низкоуровневыми
средствами( других нет :) ) - вы это имеете ввиду?
Речь шла об обероне. Там наследование есть (немножественное). И о том как можно эмулировать множественное.
-
Это не моделирование множественного наследования - это использование промежуточного контейнера- обертки но теперь я не врубаюсь - причем здесь СИ?
-
Использование контейнера обёртки, и есть эмуляция множественного наследования.
Допустим, что у нас есть объекты
TYPE
Sortable = OBJECT ... END Sortable;
Serialable = OBJECT ... END Serialable;
Listenable = OBJECT ... END Listenable;
и есть базовый объект (MyObject), который хотелось бы унаследовать от данных. Прямого множественного наследования в оберонах нет, поэтому нужно эмулировать:
TYPE
ProxySortable = OBJECT(Sortable)
VAR
myObject : MyObject;
PROCEDURE AsMyObject() : MyObject;
...
END ProxySortable;
ProxySerializable = OBJECT(Serializable)
VAR
myObject : MyObject;
PROCEDURE AsMyObject() : MyObject;
...
END ProxySerializable;
ProxyListenable = OBJECT(Listenable)
VAR
myObject : MyObject;
PROCEDURE AsMyObject() : MyObject;
...
END ProxyListenable
MyComplexObject = OBJECT(MyObject)
VAR
sortable : ProxySortable;
serializable : ProxySerialiable;
listenable : ProxyListenable;
...
PROCEDURE AsSortable() : ProxySortable;
...
PROCEDURE AsSerializable() : ProxySerializable;
...
PROCEDURE AsListenable() : ProxyListanable;
....
END MyComplexObject;
Таким образом всё во всё преобразуется (наследуется), в прокси классах реализуется требуемое поведение.
Ну и главное потом не забыть разрушить циклические ссылки, для чего можно написать деструктор
PROCEDURE Done*();
BEGIN
proxySortable^.myObject := NIL;
proxySortable := NIL;
proxySerializable^.myObject := NIL;
proxySerializable := NIL;
proxyListenable^.myObject := NIL;
proxyListenable := NIL
END Done;
-
2Madzi Наследуется - это не преобразуется. Не вижу смысла в использовании термина "множественное наследование" в контексте топика и вашего примера(и заодно того о чем говопил Vlad, но в его случае дополнительно непонятно -= причем СИ) -только сбивает "с понталыку".
-
2Madzi Наследуется - это не преобразуется. Не вижу смысла в использовании термина "множественное наследование" в контексте топика и вашего примера(и заодно того о чем говопил Vlad, но в его случае дополнительно непонятно -= причем СИ) -только сбивает "с понталыку".
Си при том, что на нем сделан COM (откуда название QueryInterface я и взял), в котором есть множественное наследование интерфейсов. Причем ручной работы для того, чтобы это все работало, там столько же сколько и в классическом обероне ;)
-
2Madzi Наследуется - это не преобразуется. Не вижу смысла в использовании термина "множественное наследование" в контексте топика и вашего примера(и заодно того о чем говопил Vlad, но в его случае дополнительно непонятно -= причем СИ) -только сбивает "с понталыку".
Си при том, что на нем сделан COM (откуда название QueryInterface я и взял), в котором есть множественное наследование интерфейсов. Причем ручной работы для того, чтобы это все работало, там столько же сколько и в классическом обероне ;)
И что?... ;) предлагаете ради этой фигни лезть в реализацию COM...есть более приятные способы маяться дурью... мы обсуждаем хранилище -(говнохранилище) с заданной структурой способное хранить обьекты (какашки) различных типов (т.е. различных размеров, цвета, консистенции).. Можно построить либо говнохранилище допускающее хранение 1. самих какашек , либо 2. какашек в обертке - вы про какое хранилище говорите?
-
;D ;D ;D
-
предлагаете ради этой фигни лезть в реализацию COM...есть более приятные способы маяться дурью...
В реализацию COM никто лезть не предлагал. Базовая идея COM (множественное наследование) вполне понятна и не нова. Реализация этой идеи на языке без поддержки ООП (Си) тоже довольно проста и чего-то нового для оберона придумать не получится :) Использование этой идеи в языке без непосредственной поддержки - крайне неудобна (собственно поэтому все боятся COM ;) При этом программисты на VB - COM не боятся и могут даже не знать что это такое - потому что язык заточен под COM.
мы обсуждаем хранилище -(говнохранилище) с заданной структурой способное хранить обьекты (какашки) различных типов (т.е. различных размеров, цвета, консистенции).. Можно построить либо говнохранилище допускающее хранение 1. самих какашек , либо 2. какашек в обертке - вы про какое хранилище говорите?
Применительно к оберону и универсальному хранилищу речь может идти только об обертках. Как раз в силу отсутствия множественного наследования в языке. Для создания оберток множественное наследование не нужно. Просто если бы множественное наследование было - то обертки не понадобились бы.
-
В реализацию COM никто лезть не предлагал. Базовая идея COM (множественное наследование) вполне понятна и не нова. Реализация этой идеи на языке без поддержки ООП (Си) тоже довольно проста и чего-то нового для оберона придумать не получится :) Использование этой идеи в языке без непосредственной поддержки - крайне неудобна (собственно поэтому все боятся COM ;) При этом программисты на VB - COM не боятся и могут даже не знать что это такое - потому что язык заточен под COM.
А что еще остается делать ;) хочется конкретики, нормальный человек будет смотреть в описалово ЯП из которого следует -что "кошерных" способов построить желаемое
с "гулькин нос", а тут таки словесы заворачиваются вокруг идей , которые ничего не дают и ссылки к технологиям сделанным на низкоуровневом языке.. :) Правда меня самого прошибает на такие вещи...
Применительно к оберону и универсальному хранилищу речь может идти только об обертках. Как раз в силу отсутствия множественного наследования в языке. Для создания оберток множественное наследование не нужно. Просто если бы множественное наследование было - то обертки не понадобились бы.я
Да нет, "не в силу отсутствия множественного наследования в языке" - а в силу того, что определенные типы данных (INTEGER,REAL) -выпадают из ерархии (я говорю про КП , в случае остальных Оебронов приходится идти в любом случае на извращение (оборачивать все какашки, либо высерать их по определенной схеме (кроме высерающихся не по правилам) ) тут никакое множественное наследование не поможет.
Да, а насчет COM - бояться не правильное слово, повторяюсь -не фиг дурью маяться -для большую часть того что он дает, реализуют наитивные библиотеки и возможности ЯП, а разбираться не имея мотивации - just for fun не для всех (по такой же причине не популярен Хаскель), и пример Байсека эту точку зрения весьма хорошо иллюстрирует.
-
По этому Хаскилеры и называют свое евангелие Learn You a Haskell for Great Good! - не специфицируя "добро" которое может получить читатель... а если будут специфицировать, то никто это дело даже и не откроет... ;D
-
По этому Хаскилеры и называют свое евангелие Learn You a Haskell for Great Good! - не специфицируя "добро" которое может получить читатель... а если будут специфицировать, то никто это дело даже и не откроет... ;D
Это не евангелие :-) Книга не занимает около центрального положения среди всей литературы по хаскеллю.
-
По этому Хаскилеры и называют свое евангелие Learn You a Haskell for Great Good! - не специфицируя "добро" которое может получить читатель... а если будут специфицировать, то никто это дело даже и не откроет... ;D
Это не евангелие :-) Книга не занимает около центрального положения среди всей литературы по хаскеллю.
:)Это метафора используемая мной как обозначение "откровений", передающих сущность топика неофитам.
-
Кстати в 1С каждый объект имеет свой GUID. Думаю что все коллекции и контейнеры используют его для хеширования и индексации.
В принципе тоже вариант, если памяти не жалко :)
-
И какой вывод?
Как вы считаете, стоит ли дополнить Оберон (не важно какой), интерфейсами с множественным наследованием интерфейсов? Я думаю что это сделать не сильно сложно и особо оберону это не повредит, так как не противоречит его идеологии.
-
Пока я склоняюсь к мысли, что должен быть аналог жабавского Object.
К тому же вынужден признать, что это не проблема языка. Думаю, что при обероновской идеологии Object должен быть введен на уровне фреймворка. ;)
Множественное наследование привлекательно, но я полный профан в этом вопросе. Я видел мнения и за и против м.н., но общей картины у меня в голове нет :(
-
Пока я склоняюсь к мысли, что должен быть аналог жабавского Object.
К тому же вынужден признать, что это не проблема языка. Думаю, что при обероновской идеологии Object должен быть введен на уровне фреймворка. ;)
Как разные фреймворки в одном проекте будем скрещивать? Я с таким уже сталкивался пару раз.
Множественное наследование привлекательно, но я полный профан в этом вопросе. Я видел мнения и за и против м.н., но общей картины у меня в голове нет :(
Я ни разу не видел ничего против множественного наследования интерфейсов (не реализаций).
-
Вот да... в разных фреймворках проблема остается. Конечно должен быть и фреймворк какой-то базовый (наследование фреймворков ;D)
А по поводу м.н. я читал где-то, в пропагандистской литературе ;), что мол композиция позволяет без него обойтись.
Я м.н. не пользовался, и потому только в теории представляю как им пользоваться.
То что я читал об интерфейсах жабы мне нравится. :)
-
А по поводу м.н. я читал где-то, в пропагандистской литературе ;), что мол композиция позволяет без него обойтись.
Композиция обычно заменяет наследование реализации.
-
Кроме того, множественное наследование интерфейсов не решит проблему с созданием типобезопасных контейнеров. В Обероне ровно один способ реализации типобезопасных контейнеров - внешний препроцессор.
-
А в жабах оно как?
-
А в жабах оно как?
На жабах - дженерики.
-
Кроме того, множественное наследование интерфейсов не решит проблему с созданием типобезопасных контейнеров. В Обероне ровно один способ реализации типобезопасных контейнеров - внешний препроцессор.
а в каких случаях нельзя этого сделать?
-
То есть хотелось бы пример типа= для хранения данных которого нельзя построить безопасный контейнер и почему.
-
То есть хотелось бы пример типа= для хранения данных которого нельзя построить безопасный контейнер и почему.
Любой пользовательский контейнер. Ну попробуй реализовать банальный типобезопасный связный список. Чтобы все элементы в нем были, как и положено, одного типа.
-
Как вы считаете, стоит ли дополнить Оберон (не важно какой), интерфейсами с множественным наследованием интерфейсов? Я думаю что это сделать не сильно сложно и особо оберону это не повредит, так как не противоречит его идеологии.
Множественное наследование ставит крест на "быстрой проверке типа", которая в свою очередь является залогом эффективности "message bus". Кроме того, проблему с "типобезопасными" контейнерами это не решит, только улучшит использование традиционных универсальных контейнеров.
-
Кстати в 1С каждый объект имеет свой GUID. Думаю что все коллекции и контейнеры используют его для хеширования и индексации.
В принципе тоже вариант, если памяти не жалко :)
У меня есть подозрение, что тамошний GUID имеет корреляцию с адресом объекта (если, конечно, там не перемещающий GC).
-
Кстати в 1С каждый объект имеет свой GUID. Думаю что все коллекции и контейнеры используют его для хеширования и индексации.
В принципе тоже вариант, если памяти не жалко :)
У меня есть подозрение, что тамошний GUID имеет корреляцию с адресом объекта (если, конечно, там не перемещающий GC).
Адреса объектов же могут совпадать в некоторых случаях. Так что GUID там скорее всего просто отдельным полем.
-
Адреса объектов же могут совпадать в некоторых случаях. Так что GUID там скорее всего просто отдельным полем.
Это из серии "sin в военное время может достигать 3" ;) Если адреса совпадают, то это один объект :) Это у тебя тяжелое сишное детство проявляется: "раньше по этому адресу мог лежать другой объект и есть поинтер, который думает, что там еще тот другой объект" :)
-
Поправьте меня, если я ошибаюсь, но QT тоже вроде бы использует внешний препроцессор - и ничего. Для легковесного синтаксиса Оберона подобный написать не проблема.
-
Адреса объектов же могут совпадать в некоторых случаях. Так что GUID там скорее всего просто отдельным полем.
Это из серии "sin в военное время может достигать 3" ;) Если адреса совпадают, то это один объект :) Это у тебя тяжелое сишное детство проявляется: "раньше по этому адресу мог лежать другой объект и есть поинтер, который думает, что там еще тот другой объект" :)
Ничего подобного. Про такое я не думал :-) Все много проще:
#include <iostream>
struct A {
char b;
char c;
};
int main()
{
A a;
a.b = 'c';
std::cout
<< (std::size_t)&a << " "
<< (std::size_t)&a.b << std::endl;
return 0;
}
-
Ничего подобного. Про такое я не думал :-) Все много проще:
Ну да, оно самое, тяжелое сишное детство ;) Назови хоть один managed/safe/гермотипизированный язык где можно такое вытворять ;)
P.S. Да, давненько я не работал с сишно
-
Ой, глючит форум... На самом деле пост был такой:
Ничего подобного. Про такое я не думал :-) Все много проще:
Ну да, оно самое, тяжелое сишное детство ;) Назови хоть один managed/safe/гермотипизированный язык где можно такое вытворять ;)
P.S. Это ж на самом деле "эмуляция наследования с помощью композиции", ООП по-сишному. Т.е., структуру A можно рассматривать как "наследника" char. И с этой точки зрения - это действительно один и тот же объект ;)
-
Ничего подобного. Про такое я не думал :-) Все много проще:
Ну да, оно самое, тяжелое сишное детство ;) Назови хоть один managed/safe/гермотипизированный язык где можно такое вытворять ;)
P.S. Да, давненько я не работал с сишно
В обероне/кп будет в точности то же самое.
-
В обероне/кп будет в точности то же самое.
Нет, там не будет "адреса" (поинтера).
-
В обероне/кп будет в точности то же самое.
Нет, там не будет "адреса" (поинтера).
SYSTEM :-)
-
Нет, там не будет "адреса" (поинтера).
SYSTEM :-)
Речь шла о "managed/safe/гермотипизированный" ;)
-
Нет, там не будет "адреса" (поинтера).
SYSTEM :-)
Речь шла о "managed/safe/гермотипизированный" ;)
Речь шла про GUID и адрес объекта. Внаружу safe обычно адрес объекта действительно не выставляет, но внутри он все равно есть. В некоторых случаях унутре адреса разных объектов/переменных могут быть одними и теми же, поэтому генерировать GUID чисто по адресу не стоит.
-
Речь шла про GUID и адрес объекта. Внаружу safe обычно адрес объекта действительно не выставляет, но внутри он все равно есть. В некоторых случаях унутре адреса разных объектов/переменных могут быть одними и теми же, поэтому генерировать GUID чисто по адресу не стоит.
1. Я бы предположил, что для тех сущностей, у которых есть GUID и которые "выставляются" в safe - адреса действительно разные.
2. Я говорил о корреляции, а не "чисто по адресу".
3. Генерация "полноценных" GUID в количествах соизмеримых с количеством "всех" объектов - кажется довольно дорогой операцией. Даже если не заказывать эти GUID у Microsoft по почте (как положено для получения самых правильных genuine GUID'ов) ;)
4. Очень может быть, что я не прав :)
-
То есть хотелось бы пример типа= для хранения данных которого нельзя построить безопасный контейнер и почему.
Любой пользовательский контейнер. Ну попробуй реализовать банальный типобезопасный связный список. Чтобы все элементы в нем были, как и положено, одного типа.
Угу - попробую, заинтересовали однако :D.
-
Кстати в 1С каждый объект имеет свой GUID. Думаю что все коллекции и контейнеры используют его для хеширования и индексации.
В принципе тоже вариант, если памяти не жалко :)
У меня есть подозрение, что тамошний GUID имеет корреляцию с адресом объекта (если, конечно, там не перемещающий GC).
Да там GUID - это просто суррогатный первичный ключ в таблице. Причем не в каждой.
GC - на основе счетчика ссылок.
-
Это не просто суррогатный ключ. Гуид - глобальный, т.е. гарантирует уникальность объекта не только в конкретной таблице. Кроме того он содержит информацию о типе.
-
Хотел ответить каждому, но накопилось много ответов, так что буду отвечать всем :)
1. "Message Bus" не панацея, есть множество способов как можно не потерять производительность (например, введя поле id).
2. Интерфейсов, как правило, много не реализуют в одном объекте (мне максимум встетилось 1 раз 7 интерфейсов). Проверка 1 или 7 последовательных значений не сильно усложнит проверку типа, и не сильно её затормозит.
3. Препроцессоры в обероне смысла не имеют! Поясняю:
Одними из ключевых принципов Оберона (как концепции, а не как языка) является единство исходного кода и реализации плюс одноразовость компиляции (нет необходимости в перекомпиляции исходников при каждой сборке). Что мы получаем в случае предпроцессора: Сгенерёный символьный файл и бинарный модуль будут отличатся от исходного файла, плюс (внимание, любители ifdef) возможно получение различного бинарного кода (символьного файла) при перекомпиляции (если будут другие условия). Вирт стремился к максимальной переносимости кода между системами и максимальной единообразности кода в различных системах, а препроцессоры способствуют получению разного кода в одной и той же системе (при чуть изменившихся условиях).
Уж лучше тогда подумать, как реализовать в обероне дженерики. Если оно вообще нужно.
С интерфейсами - всё проще. Интерфейс - это контракт, такой же как и запись, только на имена процедур у конкретного объекта. т.е., что конкретный объект будет обладать данными процедурами.
Например:
Figure* = OBJECT
VAR
x, y : REAL;
color : LONGINT;
PROCEDURE &New*(x, y : REAL; color : LONGINT);
BEGIN
SELF.x := x;
SELF.y := y;
SELF.color := color;
END New;
END Figure;
Drawable* = INTERFACE
PROCEDURE Draw*(canvas : Raster.Raster);
END Drawable;
Point* = OBJECT(Figure, Drawable)
PROCEDURE Draw*(canvas : Raster.Raster);
BEGIN
canvas.PutPixel(x, y, color);
END Draw;
END Point;
GeomList* = ARRAY OF Drawable;
Т.е. принципиально, всегда в любой системе, у модуля будет один и тот же код, только реализуемая логика может получится значительно проще, чем без интерфейсов. Для интерфейсных методов, можно предусмотреть реакции по умолчанию. Т.е. если процедура не реализована в объекте, то она либо ничего не возвращает (пустая процедура), либо возвращает 0/0.0/NIL.
-
Это не просто суррогатный ключ. Гуид - глобальный, т.е. гарантирует уникальность объекта не только в конкретной таблице. Кроме того он содержит информацию о типе.
GUID - по определению глобальный (Globally Unique Identifier).
Информацию о типе он не содержит.
-
Дело в том что в 1С гуид составной. По сути два гуида. Один из них определяет тип
-
Вот так оно выглядит при сериализации:
(http://imglink.ru/thumbnails/10-04-12/177db6863b8f82d3e2605770793a356c.jpg) (http://imglink.ru/show-image.php?id=a8202d6558e1a5d3772ae8c883e2004b)