Pull to refresh

Comments 49

Кто-то же должен подвести черту :)

Парадигмы в программировании понадобились, чтобы упоавлять сложностью, чтобы упростить восприятие кода в частности. Разработчику надо быть хоть немного архитектором, чтобы осознанно выбирать тот или иной подход в реализации решения. Там где объекты уместны, там применение ООП снижает нагрузку и повышает эффективность ппрограммиста. А в статье очередное нытьё!

Разработчику надо быть хоть немного архитектором, чтобы осознанно выбирать тот или иной подход в реализации решения. Там где объекты уместны, там применение ООП снижает нагрузку и повышает эффективность программиста.

Точно!

Поэтому считаю, что: «объекты и классы – дар Божий». Они очень хорошо позволяют структурировать код, выносить модули в автономные классы. А там, где слегка накосячил в первой версии программы, как у меня:

Структура первой версии обучающей программы «L'école»
Структура первой версии обучающей программы «L'école»

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

Люто плюсую, статья явно написана без ИИ!

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

Пример, конечно, неудачный. Метод можно поместить куда угодно если он не трогает потроха класса и у нас вообще нет наследования. Что явно вырожденный случай. Если наследование есть, и оно предполагает разную реализацию печати для разных принтеров или для разных документов - то расположение метода очевидно.

Ну а разные процессы - это объекты обёрнутые в JSON-ы, вроде бы так.

Во-первых. "Есть несколько разных реализаций этого вызова.... Это ещё зовут полиморфизмом"

Вроде бы это зовут абстракцией?

Во-вторых, насколько я знаю, "a table" значит "какой-то инстанс", или "некий инстанс". Класс это просто table, без артикля.

Безусловно , ООП это не свойство языка, свидетельством чего являются первые версии Windows: ООП в чистом виде, и при этом на ANSI C.

На моих первых работах я в основном писал свой код, с нуля или почти с нуля. Я очень любил ООП и С++: все можно было сделать проще и понятнее. Потом так получилось, что я в основном читал чужой код и чинил там баги или делал небольшие добавки. И тут я ООП разлюбил. Когда длинная цепочка наследования, происходит что-то непонятное, и поди знай, откуда это выплывает, с какого уровня... Когда в суперклассе есть то, что мне нужно, а я не могу это использовать, потому что метод не protected, a private...

Как то раз в коде было написано что-то типа "х := у + 1". Результат: у был 0, х стал -1. Сначала я решил, что у меня сломался процессор :-) Оказалось, нет: кто-то перегрузил операторы "-" и "+", и в определённых условиях они срабатывали наоборот.

Это проблема реализации ООП в ++. Собственно, поэтому в Java и большинстве последующих языков перегрузку операторов отменили.

Это проблема, именно, наследования

Насчёт "какой-то инстанс" Вы правы, но это и есть введение класса, по сути. Мы не знаем конкретных свойств этого инстанса (значений полей и даже конкретного класса). Ну, то есть, даже не знаем, кухонный это тейбл, или верстак.

Вообще-то в Линуксе издревле основным понятием был процесс, а не объект. А по поводу парадигм и программирования существуют и другие мнения. Например здесь: http://softcraft.ru/

Слова "издревле" и "линукс" несовместимы. Издревле существует Bell Labs Unix. Основных понятий в нём два. Процесс и файл.

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

отдельно интересно мыслить из категории ооп без наследования классов, как в расте или хаскеле; а то и вовсе некую вырожденную категорию где есть строго только синглтоны ну или каждую структуру можно "инстанцировать" лишь единожды

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

есть трейт "деревянный стул" — по сути, объединение трейтов "стул" и "деревянный объект" + какие-то свои отдельные свойства.

и есть некий объект "The деревянный стул сделанный на фабрике в Швейцарии в 1998 году пекарем Николой Теслой во время запекания сапогов, украденных у соседки Зины, пока она …, масса которого составляет 10кг, состоит в данный момент из x.xE+27 атомов, …" — каждый такой объект уникален и каждый удовлетворяет каждый лишь строго своему набору трейтов.

каждый трейт это просто объединение других трейтов (ну или какой-то атомарный трейт по типу как условный трейт "объект со скоростью 1 м/с"), а каждый объект это некая уникальная сущность

хотя возможно, для такой модели ближе не oop, а ecs. тогда, сервисы — это те самые трейты, а компоненты… не уверен. возможно, сервисы — тоже компоненты, просто динамические? а объекты это как раз entity.

впрочем, из конкретно примера со стулом, можно ещё и привести непонятки, навроде парадокса корабля тесея… ну или что если взять половину атомов стула и использовать для создания одного стула, а половину для создания другого… будет ли хоть один из новых стульев считаться оригинальным объектом? как будто тогда уж стоит говорить и о уникальности во времени, ну или иммутабельности, что, как мне кажется, точно лишь запутывает…

Можно практически всё, но зачем? Наследование - способ структуризации и представлений о предметной области, и связанных с ним применимых к ней алгоритмов. Представить себе мир, где объекты компонуются из необъятного моря трейтов легко, но они же не будут ортогональны. Придётся сделать трейт "украдены у Зины" и трейт "украдены у Люси", вместо трейта "украдены у кого-то" и его конкретизации.

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

Это, конечно, немного взрывало мозг, но логика была безупречна. (Она делалась для Маркета) - на каждом уровне иерархии появлялись поля, актуальные для данного обобщения. И, кстати, множественное наследование работало и позволяло из "принтеры" и "сканеры" родить "МФУ".

Придётся сделать трейт "украдены у Зины" и трейт "украдены у Люси", вместо трейта "украдены у кого-то" и его конкретизации.

Это почему еще? Завтипы прекрасно эту конкретную проблему решают.

Вообще говоря, полиморфизм и инкапсуляция — как-то внезапно оказались узурпированы ОО-евангелистами, хотя и появились раньше, и существовали во всех мало-мальски используемых языках. Файл открыл в блокирующем режиме — и вот она инкапсуляция. void** — и вот он полиморфизм (или с теми же файлами — soft link на файл).

Наследование же, которое остаётся действительной, настоящей прерогативой ОО — навряд ли сильно облегчает жизнь и уж точно не помогает описывать мир. (Пример с артиклями очень красивый и яркий, но это пока не наследование, это пара интерфейс→реализация, от которых и в ФП не продохнуть, и на которых везде реализован тот же полиморфизм.)

Не, ну серьезно, мебель→стол — это прям полезно: «Что нужно? — Стол. Куда ехать? — В мебельный!». А что насчет наследования от стола? Почему его нельзя реализовать свойствами вместо методов? Связанными объектами? Внедренными зависимостями, на крайняк?

Так что текст выше — очень изящный и внятный, я получил настоящее удовольствие от казуистических трюков. Но тезис «ОО очень хорошо ложится на окружающий мир» — не подтвержден буквально ничем. Меж тем, Аланкаевская модель с сообщениями — вот она действительно блистательно описывает мир, ибо объекты гораздо менее важны, в сравнении с обменом информацией. ОБ этом очень много говорил Армстронг, и его реализация «окружающего мира» — гораздо убедительнее Гослинговой.

Но тезис «ОО очень хорошо ложится на окружающий мир» — не подтвержден буквально ничем. Меж тем, Аланкаевская модель с сообщениями — вот она действительно блистательно описывает мир, ибо объекты гораздо менее важны, в сравнении с обменом информацией. ОБ этом очень много говорил Армстронг, и его реализация «окружающего мира» — гораздо убедительнее Гослинговой.

За это вам наша искренняя сердечная благодарность!

Настоящий ("аланкеевский") ООП не просто хорошо, а изумительно хорошо описывает буквально всё. При этом всего-то и нужны объекты и сообщения.

Универсальность * Простота = МОЩЬ

И не нужны никакие краденые и переиначенные инкапсуляции, полиморфизмы, которые только усложняют и путают. И даже наследования с абстракциями совсем не обязательны. Это всё прекрасно выводится из объектов и сообщений.

Современный "ООП" на столько исковеркал саму идею, что все эти споры остроконечников с тупоконечниками уже просто смешны — про то, что яйцо вариили, чтобы его просто съесть, никто даже не вспоминает. …Нет, уже даже и не знает, похоже.

не нужны никакие […] инкапсуляции, полиморфизмы, которые только усложняют и путают

Вместе с водой ребенка-то не надо выплескивать :)

Без полиморфизма (который, как я выше отметил, не является прерогативой OOП ни в какой мере) — мы бы замучались реализовывать банальные Eq, Ord и Show. Без инкапсуляции (которая с успехом заменяется полной иммутабельностью, и является, по сути, костылем вокруг изменяемых откуда попало данных) — фактически невозможно рассуждать о коде. Это все крайне полезные штуки, на одних сообщениях далеко не уедешь, кроме аксиоматики — нужен и минимальный понятийный аппарат.

Кто знает, если бы инфоцыганщина Мартина не выстрелила в неокрепшие умы джейсоноукладчиков, — и ООП был бы не так уж изуродован популистским бредом. Так-то и на джаве можно написать вполне себе рабочие штуки (правда, все, кто делал что-то стоящее, а не бухучет, — рано, или поздно, переходили на Скалу: Hadoop, Spark, Akka).

"Минимальный понятийный аппарат" — это вы про полиморфизм и инкапсуляцию? А я почему-то думал, понятийный аппарат должен быть хотя бы более однозначным и более простым, чем то, для описания чего он используется.

Как странно получается… Про сообщения и объекты вы в курсе. Про то, что на их основе сделаны Smalltalk/Self, Erlang (с оговорками, но всё же) и акторы — видимо, тоже? Про то, что "инкапсуляция" с "полиморфизмом" в отношении ООП появились позже, наверное, как минимум, догадываетесь. Но для описания очевидных следствий из "аксиоматики" всё равно почему-то считаете необходимым введение "понятийного аппарата" на основе переусложнённого и искажённого "полиморфизма" и шизофреничной "инкапсуляции". А чем они лучше простейших и интуитивно понятных, наверное, любому школьнику "поведения" и "состояния"? В последних по вашему мнению чего-то не хватает? Чего?

А я почему-то думал, понятийный аппарат должен быть хотя бы более однозначным и более простым, чем то, для описания чего он используется.

Дайте угадаю, вы никогда не сталкивались с понятийными аппаратами современной математики (всякие там аффинные геометрии, теории групп, и т. п.).

А чем они лучше простейших и интуитивно понятных, наверное, любому школьнику «поведения» и «состояния»?

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

В последних [«поведение» и «состояние» — @amcured] по вашему мнению чего-то не хватает? Чего?

Прилагательных и наречий :) Поведение — это глагол. Состояние — существительное. И пока мы с вами — не Бродский, — нам не обойтись одними глаголами. «Красный» — это не поведение и не состояние.

Дайте угадаю, вы никогда не сталкивались с понятийными аппаратами современной математики (всякие там аффинные геометрии, теории групп, и т. п.).

Не угадали.

Все эти понятийные аппараты именно упорядочивают и упрощают — то есть убирают избыточную сложность, а не добавляют её. Они появились по необходимости — без них просто не удавалось получить желаемое (формализованные доказательства).

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

Я же про это и спросил! Только не про аксиоматику Пеано, а про аксиоматику ООП.

Какое утверждение провозглашает "теорема" под названием "полиморфизм" в ООП? Что она даёт, чего не даёт на порядки более простая пара утверждений: "одно и то же сообщение может быть по-разному обработана разными объектами" и "один и тот же объект может по-разному обработать одно и то же сообщение в разные моменты времени"? Зачем мне может понадобится для определения (sic!) понятия ООП начинать ссылаться на "способность функции обрабатывать данные различных типов", строя искусственные изоморфизмы из пространства объектов и сообщений в пространство функций, данных и типов? А затем перечислять все виды и подвиды полиморфизма, добавляя ещё больше бессмысленной избыточности?

(В классическом определении ООП через объекты и сообщения, дополненного вариантом реализации через поведение и состояние не хватает…) Прилагательных и наречий :) Поведение — это глагол. Состояние — существительное. И пока мы с вами — не Бродский, — нам не обойтись одними глаголами. «Красный» — это не поведение и не состояние.

"Красный" — это именно состояние, которое влияет на поведение.

И как же полиморфизм с инкапсуляцией позволяют добавить прилагательные и наречия?

И ещё интересно, как же, по вашему мнению, без них древние смогли создать, например, Smalltalk, который до сих пор по выразительным/функциональным возможностям и простоте минимум на порядок превосходит все ополиморфленные и обинкапсулированные якобы ООП-шные современные языки? ;)

Есть гипотеза, что я понял, наконец, что вас так выводит из себя. Я использую термин «полиморфизм» в качестве синонима для «одно и то же сообщение может быть по-разному обработано разными объектами и один и тот же объект может по-разному обработать одно и то же сообщение в разные моменты времени» (это значительно сокращает количество фрикций в фалангах моих пальцев при наборе, например) — а вы почему-то под «полиморфизмом» понимаете «паттерн из ООП». Надо было мне сразу использовать термин «genericity», которым Алан Кай оперировал, чтобы дистанциироваться от ООП. Или «behaviour», который использовал Армстронг. Сути это, впрочем, не меняет.

«Красный» — это именно состояние, которое влияет на поведение.

Допустим, хотя я бы посмотрел на переход в другое состояние объекта «электромагнитная волна с длиной 700нм».

как же, по вашему мнению, без них древние смогли создать, например, Smalltalk

Да окститесь, в смолтолке полиморфизм был с первого дня.

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

Трейтами, например. Еще раз: я оперирую сущностями, а не ООП-шными паттернами.

Есть гипотеза, что я понял, наконец, что вас так выводит из себя.

Меня ничто не выводит из себя. Я всегда в себе, что бы со мной ни происходило ;) И уж точно повальное извращение ООП не может вывести из себя — я всё ещё продолжаю удивляться, как можно, но уже почти не верю, что это всё можно изменить :)

Я использую термин «полиморфизм» в качестве синонима для /…/

Я всё больше склоняюсь к тому, что использование одних и тех же слов для обозначения разные вещей — одна из основных проблем человечества :D

Попробуйте открыть статью "Полиморфизм (информатика)" в Википедии, и должно стать понятно, что и почему я понимаю под термином "полиморфизм".

И я бы тоже с удовольствием сокращал количество фрикций в фалангах своих пальцев, ограничившись словом "сообщение", но почему-то это всякий раз приходится объясняться…

Сути это, впрочем, не меняет.

Ну, вот как?! Как использование слов не по их исходному значению может не менять сути?

Как можно просто брать и использовать термин "полиморфизм", у которого есть вполне определённый (хотя и очень сложный) смысл, преданный этому термину ещё до появления термина "ООП", для краткой передачи смысла сообщений? Да ещё и учитывая, что с помощью этого термина переврали, извратили и буквально поставили с ног на голову всю концепцию? :)

Как можно говорить, что Кэй "дистанцировался" от ООП, используя «genericity», если Кэй с помощью этого термина пытался объяснить смысл ООП, (безрезультатно) демонстрируя, что "полиморфизм" (несмотря на всю сложность) не в состоянии дать те же возможности, что и концепция ООП и сообщений?

Не понимаю как, но вот вижу, что можно: именно так и превратили ООП в того уродца, о котором нынче ломают копья "тупоконечники" с "остроконечниками". И нет, это не выводит меня из себя. Скорее, уже забавляет ;)

Да окститесь, в смолтолке полиморфизм был с первого дня.

Вы про какой полиморфизм? Тот, который сейчас используют для "объяснения" что такое "ООП" — но который при про функции, а не про сообщения? Или всё же про ваш личный, который вы каким-то образом привязываете к связке объект-сообщение?

И про первый день какого именно Smalltalk-а речь? Про Smalltalk-80? Или про Smalltalk-76? Или, может быть, про Smalltalk-72? Было бы интересно услышать, как вы к нему привяжете полиморфизм… Или вообще про концепцию 71-го года — это было бы даже интереснее.

…Хотя, вы же, наверное, привяжете полиморфно — наделив термин "полиморфизм" ещё какой-нибудь интерпретацией? :)

> как же полиморфизм с инкапсуляцией позволяют добавить прилагательные и наречия?

Трейтами, например. Еще раз: я оперирую сущностями, а не ООП-шными паттернами.

По всей видимости, под "прилагательными" и "наречиями" вы тоже имеете ввиду что-то другое — не то, что в учебниках по русскому языку? Можно считать этот вопрос риторическим :)

Вот я тоже почитал и подумал - Вас именно эти слова, что ли, бесят? Ну - полиморфизм - это общепринятое сокращение для "одно и то же сообщение может быть по-разному обработана разными объектами" - почему это так раздражает-то?

Потому что Вас раздражает само слово ООП?

Потому что это не так?

Вот смотрите. Формально Вы совершенно правы - если всё вокруг народное immutable - инкапсуляцию можно отменить, верно?

Во-первых, неверно. Инкапсуляция, в том числе, скрывает трюки реализации, которые действительно знать нельзя. Мне один из сотрудников Микрософта рассказывал, что программисты просекли, что при старте процесса в Windows в каком-то регистре всегда лежит что-то полезное - какой-то дескриптор. И начали им пользоваться. А это значение там лежит случайно - валяется потому что последнее вычисление его использовало. Код скорректировали - и оно пропало. И Вы не представляете, на сколько денег влетел Микрософт, чтобы СИМУЛИРОВАТЬ это поведение для программ, которые от него сдуру зависят.

Отсюда некоторый максимализм, который иногда звучит в ООП - извне реализации даже классы желательно не использовать, только интерфейсы.

И вторая часть - ну, положим, мы такие заиньки, что трюки реализации ну никак не светятся. Не верится, но положим. Вот только есть беда - как обсуждаешь ФП формально, так в нём присваивания нет. А как реализация и конкретный код - так и сразу есть. И сразу - "это только критики ФП требуют от него идеального соответствия канонам, а мы, носители тайного знания, уже давно считаем, что присваивать можно". Это почти буквальная цитата из дискуссии.

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

при старте процесса в Windows в каком-то регистре всегда лежит что-то полезное

Вы не очень удачный пример выбрали, это как раз на 102% проблема изменяемых откуда попало данных. Но я верю, что можно придумать и более аккуратную иллюстрацию.

извне реализации даже классы желательно не использовать, только интерфейсы

Для реализации это верно в любой парадигме, ООП тут ни при чем. См. dependency injection.

ФП формально, так в нём присваивания нет. А как реализация и конкретный код — так и сразу есть.

Вот тут без примера уже никак. Я написал тонну кода и на ООП (причем и на энтерпрайзном, типа джавы, и на экстремальном, типа руби), и на ФП (эрланг, эликсир). Формально в ФП про присваивание никаких специальных сур нет, есть коаны. В эрланге, например, присваивания нет вовсе, есть паттерн-матчинг (и X = 1 — это именно что матчинг, можно с тем же успехом написать {ok, X} = call_function(), и даже 1 = X и компилятор останется доволен). И так далее.

Я как раз работаю над в принципе функциональным, полностью иммутабельным языком https://cure-lang.org — и там присваивание пока есть, потому что полная деструктуризация в правильном матче — это сложно, и оставлено на потом. Короче, есть присваивание, или нет, — второстепенный факт.

можно бы в рай заменить инкапсуляцию иммутабельностью

Можно, почему нет-то? Вы пока никаких аргументов не привели. Цитата из странной дискуссии в зачет не идет.

С точки зрения процесса этот регистр immutable - это внешние константные для него данные (менять их в ядре ОС он не может, видит копию), и проблема ИМЕННО в том, что процесс увидел чужой стейт. Который должен был быть недоступен. Увы, иммутабельность не заменяет инкапсуляции - не всё то, что нельзя изменить можно видеть и использовать.

Смотрите. Конкретизация до значений - это я немножко жёстко заявил, но дело в том, что наполнение поля значением тоже порождение дочернего класса, с некоторой точки зрения. Но можно не лезть в эти детали. Собственно, если трейты наследуются - то это ООП с множественным наследованием, а если не наследуются - это кабздец без реюза кода.

если [трейты] не наследуются — это кабздец без реюза кода

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

Если вам надо, чтобы экземпляр подкласса ходил, как животное, выглядел, как животное, но при этом квакал — ну сделайте функцию sound полиморфной, делов-то. И вместо duck.sound зовите Noise.sound(duck).

У меня складывается ощущение, что вы под ФП понимаете какую-то радикальную религию, в которой запрещены блекджек и девочки по вызову.

Вы, кажется, не уловили сути статьи. Она в том, что есть вещи естественные для человека, а есть неестественные. И вот duck.sound - естественная. Потому что утка крякает. А не шум издать утка. Не мыслят люди так. ФП тут не при чем, оба примера вполне императивны. Мало того, если Вы когда-нибудь ныряли в чужой код, то должны различать "посмотреть все методы утки" и "посмотреть все функции на свете, которые принимают что-то типа утки". Первое легко, второе нереально.

А мне кажется, это вы не очень уловили, что написали.

есть вещи естественные для человека, а есть неестественные

Абсолютно.

Потому что утка крякает. А не шум издать утка. Не мыслят люди так.

Да ну? Что там за шум? — Это утка в камышах. «Утка крякает» — это примитивизм, который покрывает только простейшие императивные жизненные ситуации. Чуть более сложные — уже нет.

должны различать «посмотреть все методы утки» и «посмотреть все функции на свете, которые принимают что-то типа утки»

Второе — тривиально (даже grep с удовольствием покажет все имплементации). Первое — в ООП практически невозможно. Потому что вот тот джун унаследовал от утки утконоса (ну ему так показалось, что они похожи), и у вас теперь тут инстанс утконоса, на котором определен метод «не эволюционировать», а метод «крякать» бросает экспепшн. Но по коду, в котором вы понятия не имеете, какой монстр скрывается за каждой переменной, это увидеть совершенно нельзя.

Вы приводите очень хороший аргумент: «есть вещи естественные для человека, а есть неестественные». Но ошибаетесь в том, что естественно мыслить в категориях объектов и методов. Естественно мыслить в категориях сущностей и сообщений (причем, асинхронных). Я не могу заставить вас понять эту прописную истину эксплицитным вызовом метода понять на истансе dz. Я могу только отправить сообщение (комментарий) и надеяться, что вы его получите, а потом обработаете, а потом — если захотите — еще и уведомите меня об этом.

Вот так на самом деле устроен окружающий мир. И такая модель на самом деле для человека естественна, потому что она моделирует именно его, а не безумные рабовладельческие фантазии наподобие утка.крякать. Ну подите заставьте утку крякать, если уж на то пошло. Поэтому там всегда _наблюдаемое_, то есть — шум, издаваемый уткой (если нужен полиморфизм).

В другом комментарии уже и так всё объяснили но всё же, объясню и от себя

Придётся сделать трейт "украдены у Зины" и трейт "украдены у Люси", вместо трейта "украдены у кого-то" и его конкретизации.

trait Stolen {
  const from : &str;
}

// или так, игнорируя, что константным параметром могут быть только инты, предполагая что объект может быть украден по нескольку раз
trait Stolen<const from : &str> {}

в идеале, если будут зависимые типы, позволяющие сделать константы не такими уж и константами — что хорошо ляжет на изменчивость при использовании разных объектов. Потом может появиться что-то такое :)

И, кстати, множественное наследование работало и позволяло из "принтеры" и "сканеры" родить "МФУ".

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

// вместо
abstract class Parent {
  int a;
}

class Child : Parent {
  ...
}

//делать как-то так
interface Parent {
  protected int a {get; set;}
}

sealed class Child : Parent {
  // бонусом ещё и видно на месте, 
  // так что не придётся лезть в базовые классы за определением
  protected int a {get; set;}
  ...
}

но наверное, в бд это может быть какой-то отдельный случай, где было удобно сделать именно так, я не сталкивался с таким, наверное.

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

Можно, вообще, отдельно обсуждать наследование интерфейса и реализации, и второе часто делается именно композицией.

Тут проблема вот в чём. Если бы ортогональность унаследованных интерфейсов была гарантирована и гарантировала бы ортогональность реализаций, то мир был бы прекрасен. В реальности сам факт того, что нам надо совместить два интерфейса означает, что реализация будет не "сложить вместе две реализации", а как-то их связать.

можно ли пример того о чём речь?

дерево классов

- драйвер

-- сетевой драйвер

--- драйвер TCP

--- драйвер UDP

дерево классов

- драйвер

-- драйвер бытовой техники

--- драйвер пылесосов

--- драйвер кофеварок

двойной наследник - драйвер кофеварок по UDP

Если бы к "фиговым" трём пунктам добавить ещё и самый неправильный про то, что "ООП — это инкапсуляция, наследование, полиморфизм", могло бы получиться что-то дельное. А так, к сожалению, получился очередной наброс в спор глухих со слепыми о балете.

Предполагается, что уж определения с первой страницы букваря читатель знает. :) Читателю, который этого не знает и сам вопрос, наверное, не очень интересен...

Кто-то кого-то не понимает — либо я вас, либо вы меня. Давайте выясним:

Буду краток - все три пункта выше - фи-игня. 

Вот и четвёртый (я бы его на первое место поставил) пункт про инкапсуляцию, наследование, полиморфизм — не меньшая фи-игня. Да?

Э. Стоп. Это общепринятое определение. Его можно тоже снести, но тогда надо свое предложить. Я такой задачи перед собой не ставил.

Всё уже давно предложено. С самого начала. И благополучно забыто.

В целом, позиция ясна.

Вы не путаете "забыто" и "умерло"? Динозавры не забыты, но исчезли - не конкурентоспособны. Так и с ООП - оспорено множество раз, но живёт, а конкуренты - если они вообще без ООП - умирают. И я объяснил, почему - потому что ООП соответствует базису мышления человека. И да (и про это я там тоже написал) - реальное ООП неидеально и местами коряво. А теперь посмотрите на русский и английский язык - неидеальны и местами корявы. Посмотрите на понятийный аппарат среднего homo sapiens. На этот мир, вообще.

:)

Вы не путаете "забыто" и "умерло"?

Нет. Но что вы понимаете под "умерло" — я понять не смог. Я-то всего лишь говорил о том, что исходная идея ООП существенно отличалась от "общепринятой" сейчас. И нет, она не умерла — просто забыта. И это печально, потому что она обладает гораздо большими выразительным возможностями, но при этом ещё и проще.

ООП соответствует базису мышления человека.

С этим утверждением я, в общем-то, согласен. Правда, не совсем уверен, что правильно понимаю, что вы имеете ввиду под "базисом мышления"…  Но зато теперь уже практически полностью уверен, что "ООП" у вас и у меня — очень разные. Так что:

  • Тот ООП, который (как я понимаю) имел ввиду Алан Кэй, придумывая этот термин, — да, похоже, является "базисом" человеческого мировосприятия.

  • Тот ООП, который про полиморфизм-инкапсляцию-наследование, — нет, таким базисом не является, и не может являться: слишком сложно и слишком узко для "базиса". И это "ООП" обречено постоянно "бодаться" с ФП и прочими в попытке обосновать и защитить себя, вместо того, чтобы стать эмерджентным синтезом.

Ну - значит, ждём новый ЯП...

Зачем? Зачем создавать что-то новое, пока нет понимания уже существующего?

…Даже, правильнее сказать, "существующИХ". Потому что после Smalltalk-а были и Self, и Strongtalk, и Newspeak… и даже Erlang с Elixir-ом. В общем были, были попытки развития разной степени успешности (разумеется, здесь я не имею ввиду популярность) — именно на основе понимания идеи ООП.

Но большинству милее деградация через всякие С++, Java и прочие химеры. Неадекватность заложенных в основу подобных ЯП принципов, "идеям ООП" (которые они тщатся "воплотить") компенсируется извращением и вырождением этих самых идей. Зато Algol-истый синтаксис — он же такой знакомый и "простой" (точнее, привычный) в реализации. Не зря же в ВУЗах основы теории компиляторов преподают. …Или уже не преподают?

А ещё можно очень успешно критиковать то, что не понимаешь. Особенно, если не хочешь понимать. Это ведь очень удобно делать, когда вокруг столько уродливо-кривых воплощений. Железная же "логика": идея —> извращение идеи —> воплощение извращённой идеи —> провал => вывод: идея была неправильной. Столько простора для "творчества"!

Так что ждать новых ЯП не приходится. А если они появятся, вряд ли это будет шагом вперёд для ООП.

Зато можно ожидать повторения раундов борьбы инкапсуляции с иммутабельностью и наследования с полиморфизмом. Это — всегда пожалуйста, это — сколько угодно! :D

Что-то в этом есть. Чем не классы?

module type ACC = sig
    type t
    val add: string -> t -> t
end

module NoAcc = struct
  type t = unit
  let add _ () = ()
end

module type DEPS_ENV = sig
    module Acc: ACC
    val deps: unit -> JSON.value
    val name: JSON.value
    val yes: bool
end

module Deps = struct
    module A = Set.Make(String)  (* implements ACC *)

    (* A bit of an artificial example *)
    module Inherit = struct
        include A

        let add k x = prerr_endline "Inherited" ; A.add k x
        ;; 
    end
Sign up to leave a comment.

Articles