LINUX.ORG.RU

Существуют ли иные модели ООП?

 , ,


1

3

На сегодняшний день известно 2 модели ООП. Назовем их условно, «сильная» и «слабая».

Первая — смолтоковская модель, основанная на, воистину, величайших идеях Алана Кея, в первую очередь — позднее связывание и концентрация на сообщениях.

Вторая — основанная на лексических замыканиях.

К сожалению, вторая модель получила наибольшее распространение в современных языках программирования. Первая нашла свое воплощение лишь в очень малом количестве ЯП, из мейнстримных я знаю только JS и Ruby. Видимо, основная причина в трудностях эффективной реализации мощной модели, хотя, пример JS заставляет усомниться в этом. Другой причиной, может быть то, что средний программист не может понять сильную модель, тогда как слабую понимают почти все.

А вопрос такой: есть ли какая-нибудь альтернативная модель, некий третий путь. Тут следует пояснить, наверное, что я не провожу различия между смолтоковской классовой(smalltalk, ruby) и прототипной(js, self, io) моделями, условно считаем, что это то же самое, также я не провожу различия между замыканиями и java-like-классами, в данном случае (т.е. модель scheme в контексте примеров модели вычислений с окружениями из SICP === java-style etc), нутыпонел — я обобщил. Может быть что-то еще, принципиально отличающееся от этих двух, есть такое?



Последнее исправление: oop (всего исправлений: 1)
Ответ на: комментарий от anonymous

если эти теперешние $100M на джойстик вложить тогда

«Тогда» и «теперь» это несколько разные деньги. Да и не факт, что «тогда» они у них были. И главное - им-то это зачем?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Какое-то упоротое сравнение. Если мы с тобой возьмёмся одновременно писать разные либы используя GObject, то «базовые типы», конечно будут одинаковые и совместимые (как собственно и в С++)

Я имел в виду, что для объектной системы поддержки классов в языке недостаточно. Необходим стандарт на базовые типы, семантику, методологию созданий новых классов. Для C++ таковыми можно считать STL и Qt (хотя Qt не совсем C++, там собственный язык, но бинарно совместимый с C++).

но GObject как раз несколько громоздкий по сравнению с «встроенными» решениями.

С макросами не так всё страшно. Кроме того есть Vala.

monk ★★★★★
()
Ответ на: комментарий от monk

Я имел в виду, что для объектной системы поддержки классов в языке недостаточно.

Я всё-таки не совсем согласен. Да, в С++ много не хватает, вот только большинство из этого ортогонально «обьектной системе». Во первых, все перечисленные фреймворки, в первую очередь, для ГУИ задумывались. Во вторых, совместимость многим из них просто не нужна была.

С «базовыми типами» у С++ всё нормально, проблема в отсутствии АБИ. Ну и интроспекции не хватает, но тут опять же, проблема в том, что в комитете стандартизации долгое время фигнёй страдали, отсюда и растёт множество разнообразных «костыльных» решений. Впрочем, втаскивать в стандарт либу/фреймворк для ГУИ, вряд ли, вообще будут.

Кроме того есть Vala.

Что собственно и доказывает, что «встроенное» решение удобнее, если в языке нет развитых средств для метапрограммирования. Да и при наличии таких средств, иметь стандарт удобно.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

С «базовыми типами» у С++ всё нормально

Да, какое «нормально», если обычная строка в MFC, OWL, VTK, Qt, ... была разная (в Qt вроде до сих пор, но это фактически отдельный язык — ему можно)?

проблема в отсутствии АБИ

Внутри одного компилятора/линкера всё ОК. А смешивать разные и на Си не очень рекомендуется (errno, например, ломается).

monk ★★★★★
()
Ответ на: комментарий от monk

если обычная строка

Так и знал, что к строкам прицепишься. Ещё хоть один пример назовёшь? Qt, кстати, долгое время дублировал алгоритмы, а контейнеры до сих пор дублирует. Тем не менее, они отлично совместимы с стл в обе стороны.

А разность ростёт из несколько других причин.

Внутри одного компилятора/линкера всё ОК.

Ну если бы оно ещё и внутри одного компилятора не работало...

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Ещё хоть один пример назовёшь?

Массивы, списки, ассоциативные массивы (в смысле std::map, std::unordered_map)

Qt, кстати, долгое время дублировал алгоритмы, а контейнеры до сих пор дублирует.

Я про это и говорю.

Тем не менее, они отлично совместимы с стл в обе стороны.

Да ну. QString text = "Test"; cout << text; уже работает?

А когда одна библиотека возвращает QVector<QString> , другая для обработки хочет vector<string>, а третья для вывода хочет vtkStringArray, то приходится одни и те же данные держать в трёх местах и дважды конвертировать (причём не через memcpy, а с учётом UTF-8).

А разность ростёт из несколько других причин.

NIH синдром, вроде...

monk ★★★★★
()
Ответ на: комментарий от monk

Или в самом языке? Тогда «а зачем?».

или гитхаб страничка

родовые функции, мультиметоды, методы на элементарные типы, вот это вот всё. макросами на plain C.

anonymous
()
Ответ на: комментарий от monk

Я про это и говорю.

Ну так причина былa нe в том, что «чего-то не хватает».

Да ну.

Я про контейнеры и алгоритмы. Строки - это всё-таки немного не то. Алгоритмы работают с итераторами, соответственно Qt-шные контейнеры отлично обрабатываются аглгоритмами из стл. И наоборот. В этом моменте, в плане «задания стандартного интерефейса» стл вполне отлично справляется.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от monk

для объектной системы поддержки классов в языке недостаточно. Необходим стандарт на базовые типы, семантику, методологию созданий новых классов. Для C++ таковыми можно считать STL и Qt (хотя Qt не совсем C++, там собственный язык, но бинарно совместимый с C++).

первая — библиотека, второй — фрейморк. первое — прозрачно относительно языка, второе — вводит свой DSL сигналов и слотов, и кодогенератор moc.

первое — composable, второе вводит свой недоязычок. из-за отсутствия composability приходится городить свой QString, например — фреймворки кабанеют изо дня.

собственно, поэтому фреймворки и сосут, в отличие от библиотек — они не composable в смысле семантики. особенно если базовый язык неудачен для расширяемых DSL.

методологию созданий новых классов.

эка ты конструктор обозвал. внушаить!

но GObject как раз несколько громоздкий по сравнению с «встроенными» решениями.

а по-моему, встроенный VMT C++ более громоздкий — стоит собрать helloworld со -static, как тут же откуда ни возьмись 600k какой-то лабуды.

этот оверхед что, так уж необъодим для объектной системы?

тот же D, кстати в скромные 200k укладывается.

anonymous
()
Ответ на: комментарий от DarkEld3r

Что собственно и доказывает, что «встроенное» решение удобнее, если в языке нет развитых средств для метапрограммирования. Да и при наличии таких средств, иметь стандарт удобно.

если в языке есть нормальное CFTE программирование, то «встроенное» не нужно, ибо любое реализуется библиотечно. ну разве что «официальный стандарт» иметь удобно, да.

вот например, на том же D есть QtE, в котором в райнтайм реализована объектная модель С++: грузится Qt .dll/.so, врапперы, написанные вручную создают объекты на С++, вызывают методы на С++. почти как на managed C++, C++ + .NET в одном общем рантайме, только на D и лоадер в рантайме.

сдаётся, что если дописать манглер CTFE функциями, то можно сгенерировать врапперы при компиляции. или плагин написать к clang, который при компиляции эти CTFE обёртки генерирует.

anonymous
()
Ответ на: комментарий от monk

Да, какое «нормально», если обычная строка в MFC, OWL, VTK, Qt, ... была разная

и «таблица маршрутизации методов» макросами — это так прикольно, ага. костыли же.

anonymous
()

Модель очень простая. Все есть процессы и они общаются между собой сообщениями как правило ассинхронно

anonymous
()
Ответ на: комментарий от DarkEld3r

причина былa нe в том, что «чего-то не хватает»

Да ну? Почитай официальную отмазку, почему в Qt не используется std:string. «Наш QString быстрее и круче».

контейнеры и алгоритмы

С учётом того, что алгоритмы де-факто просто макросы, то было бы странно, если бы они не работали. Но проблема использования в одной программ 2-3 типов контейнеров для одних данных остаётся. И даёт overhead сравнимый с использованием FFI в каком-нибудь лиспе. Даже хуже: FFI я в макрос могу завернуть и он будет выглядеть как родной тип, а контейнеры приходится явно конвертировать.

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от anonymous

ага, а fork() — это наследование, а mmap() — полиморфизм ;-)))

ну или как там это в агентах будет выглядеть.

anonymous
()
Ответ на: комментарий от anonymous

Не fork но spawn. Реализации процессов бывают разные ;)

anonymous
()
Ответ на: комментарий от anonymous

man Fragile Base Class problem

Это относится вообще к ООП такому как в джаве/С++, а не конкретно проблема плюсов.

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

если в языке есть нормальное CFTE программирование, то «встроенное» не нужно, ибо любое реализуется библиотечно.

Я несколько криво выразился. Решение в стандартной библиотеке тоже вполне подходит. Речь о том, что не стоит предлагать каждому изобретать решение самостоятельно. Вон в ракете всё реализовано средствами языка, но тем не менее, иметь реализации в «стандарте» удобно.

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

сигналы/слоты, например.

Плохой пример. Тут нет зоопарка реализаций. Имеющаяся в Qt реализация зависит от общей инфраструктуры. Да, есть реализация в бусте, но это немного не то. Да и не нужны они так уж часто. В общем, в отличии от строк, тут проблемы не наблюдается.

DarkEld3r ★★★★★
()
Ответ на: комментарий от monk

«Наш QString быстрее и круче».

Быстрее - спорно, а насчёт круче - так и есть. Но может хватит уже строки мусолить?

С учётом того, что алгоритмы де-факто просто макросы

Чего это они макросы? Просто они удачно используют такую абстракцию как итераторы.

Но проблема использования в одной программ 2-3 типов контейнеров для одних данных остаётся.

Не встречал таких проблем. Просто надо выбрать чем пользоваться и тогда конвертации будут только в редких местах. Да и вообще не везде нужна мешанина фреймворков.

Но вообще мы начали спорить о пользе «стандартного решения». Вот и представь - если бы в С++ вообще не было бы строк и контейнеров. Тогда сейчас было бы не несколько вариантов, причём совместымых с стл, как правило. А в разы больше.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Быстрее - спорно, а насчёт круче - так и есть

Они так пишут:

http://www.qtcentre.org/threads/15700-Qstring-vs-string

Чего это они макросы?

Того, что не функции и не классы. Код генерируется при компиляции, поэтому тип не важен. Главное, чтобы имена методов совпадали.

Не встречал таких проблем. Просто надо выбрать чем пользоваться и тогда конвертации будут только в редких местах.

Вот и получается, что люди пишут на Qt, VTK, boost, ... и должны использовать не лучшие решения, а использующие тот же фреймворк (например, qt-mat вместо armadillo, так как GUI на Qt).

Но вообще мы начали спорить о пользе «стандартного решения». Вот и представь - если бы в С++ вообще не было бы строк и контейнеров. Тогда сейчас было бы не несколько вариантов, причём совместымых с стл, как правило. А в разы больше.

Все существующие варианты появились как раз когда «в С++ вообще не было бы строк и контейнеров».

monk ★★★★★
()
Ответ на: комментарий от monk

Они так пишут:

Не они, а какой-то непонятный тип. Возможно, Qt девелопер, но это не официальная позиция. Вообще, я с Qt достаточно работал и представляю что там и как. Да и вообще преимущества и недостатки Qt-шных строк многократно обсуждались на разных ресурсах, зачем повторяться.

Того, что не функции и не классы

Ну если так придираться, то они и не макросы, а шаблоны.

поэтому тип не важен. Главное, чтобы имена методов совпадали.

Нет, недостаточно. Есть разные категории итераторов, пусть в отсутствии концептов внятной ошибки и не будет.

и должны использовать не лучшие решения, а использующие тот же фреймворк

Нет.

Все существующие варианты появились как раз когда «в С++ вообще не было бы строк и контейнеров».

Нет.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

не лучшие решения, а использующие тот же фреймворк
Нет.

Ты же сам пишешь «просто надо выбрать чем пользоваться и тогда конвертации будут только в редких местах». Если мне нужна визуализация в 3D, то лучший фреймворк — VTK, если мне нужно умножение матриц, то armadillo, если GUI, то Qt. В них всех разные все типы (кроме сишных).

существующие варианты появились
Нет

Ну смотрим. STL появилась в стандарте в 1998. Qt появилась 20 мая 1995, MFC и OWL в 1992, VTK в 1993

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)

oop, чего ты тут своими теориями мозг выносишь?

Сходи на форум oberoncore.ru, вправишь себе мозг.

anonymous
()
Ответ на: комментарий от monk

Ты же сам пишешь «просто надо выбрать чем пользоваться

Ну и часто тебе нужно одновременно «визуализация в 3D, умножение матриц и GUI»?

И я всё равно не вижу противоречий. Используй то, что лучше подходит. Если вдруг окажется, что кое-где придётся конвертировать, то не беда.

Да и я не очень понял какая альтернатива? Умножать матрицы средствами Qt?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Ну и часто тебе нужно одновременно «визуализация в 3D, умножение матриц и GUI»

Для аналитической геометрии вполне актуальная задача.

Если вдруг окажется, что кое-где придётся конвертировать, то не беда.

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

Да и я не очень понял какая альтернатива? Умножать матрицы средствами Qt?

Использовать неоптимальное (с худшей производительностью и возможностями, зато на типах данных Qt) решение для умножения матриц и 3D.

Я пытаюсь донести мысль, что из за дублирования базовых базовых типов данных в фреймворках получилось несколько независиых доменов C++, каждый из которых приходится рассматривать почти как независимый «язык», так как конвертация между ними сравнима по стоимости с использованием из другого языка.

monk ★★★★★
()
Ответ на: комментарий от monk

Я пытаюсь донести мысль, что из за дублирования базовых базовых типов данных в фреймворках получилось несколько независиых доменов C++

Только вот забавно, что мы начали с полезности «стандартных» решений. И похоже оба с этим согласны. О чём тогда спорим?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

О чём тогда спорим?

О том, что важнее: наличие стандартного базового дерева классов (GObject) или поддержка классов в синтаксисе языка (C++). Разумеется, что лучше и то и другое (C++ с 98 года), но если выбирать, то что?

P.S. Отсутствие поддержки в синтаксисе даёт больше гибкости. Множественную диспетчеризацию к Си можно прикрутить на уровне макросов (причём можно не брать OOC, а расширить GObject), а в C++ только через переписывание компилятора или полную смену синтаксиса.

monk ★★★★★
()
Ответ на: комментарий от monk

Множественную диспетчеризацию к Си можно прикрутить на уровне макросов

К С++ точно так же можно. В смене синтаксиса нет ничего ужасного, если уж нам это нужно. Тем более, что она не «полная» - язык-то остаётся старым, просто вместо «встроенного» ООП будут макросы.

Но есть и другие способа. Хотя подозреваю, что ты в курсе.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Но есть и другие способа.

4.1 Changes to Compiler & Linker

Я это и имел в виду. Рекомендуемый путь расширения объектной модели в C++ — менять компилятор.

К С++ точно так же можно.

С учётом того, что C++ = надмножество C, то это очевидно. Правда в этом случае мы теряем преимущество встроенного синтаксиса и начинаем писать на «C с шаблонами».

monk ★★★★★
()
Ответ на: комментарий от monk

К С++ точно так же можно.

Если я меняю потроха GObject, то у меня всё равно в коде остаётся gtk_box_pack_start (box, child, expand, fill, padding) только вызываться будет метод не в зависимости от типа box, а в зависимости от типов box и child.

А если я пытаюсь изобразить что-то на макросах в С++, то все вызовы box->pack_start(child, expand, fill, padding) придётся вручную менять на примерно то, что в GObject.

monk ★★★★★
()
Ответ на: комментарий от monk

Рекомендуемый путь расширения объектной модели в C++ — менять компилятор.

Тут речь немного у другом. Нет смысла в отрыве от практики рассуждать, соответственно рассматривается вариант реального добавления функциональности в язык. Естественно (в рамках С++), это невозможно без изменний в компиляторе.

Аналогично есть реализация концептов и модулей, но они пока остаются «тестовыми».

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от monk

Если я меняю потроха GObject

Это всё хорошо, но GObject не входит в стандарт С. И не все его используют. То есть аналогия с «встороенными» в С++ средствами неполная.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Это всё хорошо, но GObject не входит в стандарт С. И не все его используют.

GObject — наиболее используемая ООП модель в Си. Или знаешь более популярную?

Тут скорее претензия к разработчикам C++, что не утвердили вместе с языком API на базовые классы. Правильный подход можно увидеть у Java или Python — и там фрагментации кодовой базы почти нет (почти, потому что выходят новые версии языка).

Даже немножко не так. В Си (или, например, в Object Pascal) можно работать не оглядываясь на ООП. То есть, даже если я разрабатываю ООП библиотеку, то массивы, строки, ввод-вывод я всё равно беру из стандартной библиотеки.

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

monk ★★★★★
()
Ответ на: комментарий от monk

Тут скорее претензия к разработчикам C++, что не утвердили вместе с языком API на базовые классы.

Питон и джава создавались после и могли учесть ошибки. В С++ ведь тоже это сделали, но позже.

DarkEld3r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.