Pull to refresh

Comments 64

Извините, в чём смысл вашей статьи?
UFO just landed and posted this here
Скажите это SQL из 1974 и реляционной алгебре, куда движутся распределённые хранилища, бывшие NoSQL, а сейчас NewSQL (Spanner, Cockroach DB). Или посмотрите на эволюцию Java, где добавили сахар для замыканий, анонимных функций, Stream API (оптимизация функтора). Тут аналогия с поколениями при сборке мусора: если до сих пор что-то помнят из 1971, то большие шансы, что ещё долго будут помнить. А свежий мусор из nursery забудется в следующем году.
В сети есть уйма холиваров, ООП vs ФП, языки со статической типизацией против динамической, зачем нужны компиляторы, которые мешают разрабатывать своими ошибками, когда можно покрыть юнит тестами, какой язык лучше. Если в них разобраться, то окажется что в одном варианте нужно делать ручками, а в другом за вас работу может сделать компьютер. Но, конечно, придётся потратить время, чтобы разобраться. Здесь указано, в какую сторону время тратить: в фундаментальные понятия, а не в популярные в нынешнем сезоне.
да, хорошая идея для статьи, копипаста различных цитат.
Приведите, пожалуйста, пруф-ссылку на копипасту :)
Это скорее, awesome list.

Полезность материала, конечно, сомнительна на первый взгляд. Однако, я не видел более ясного и доступного неформального описания функторов и монад )
Цель материала была в том, чтобы человек, который раньше не встречал, что такое зависимые типы или обходил стороной слово «монада», начав с того, что ему знакомо, дочитал до конца, на этот раз понял, что штука-то в хозяйстве это полезная, и, может быть, глубже погрузился в тему, щёлкнув по ссылке.
Если текст показался очевидным, то это вообще замечательно!

… кому-нибудь будет интересен список ошибок в этих "определениях", или и так всем все понятно?

Мне интересен. Ваши комментарии — это как мастер-класс по занудству в лучшем смысле этого слова.
Вы правильно взяли «определения» в кавычки. Но ошибки, пожалуйста приведите. Как Маугли, воспитанный Википедией, я могу и ошибаться и рад бы был от вас чему-нибудь научиться.
Тип — это то, над чем компьютер умеет рассуждать. Рассуждать в смысле привычной человеческой или формальной логики, то есть по правилам строить некоторые заключения из исходных посылок.

Даже не придираясь к утверждению "компьютер умеет рассуждать", здесь опущено важное: компьютер "умеет рассуждать" над данными. То, что вы здесь называете типом — всего лишь метаинформация о "хранилище" (будь то переменная или колонка в БД или впишите что угодно еще), в первую очередь — ограничивающая допустимый набор его значений.


Хорошая новость в том, что компьютер делает это автоматически.

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


Сильные системы типов могут за вас делать больше работы, чем слабые.

Здесь забыт важный пункт: сильные системы типов могут требовать от вас больше работы, чем слабые. Кстати, эй, а что же такое "сильная" и "слабая" система типов?


Класс в ООП — это одна из систем типов

Класс — это не система типов. Класс — это (в некоторых ОО-языках) один из видов типов (простите); иными словами (в некоторых ОО-языках) всякий класс — это тип, но не всякий тип — это класс.


Аналоги: запись, кортеж, тип-произведение.

Нет. Если мы говорим о более-менее устоявшихся определениях, то запись, кортеж и типы-произведения — это не классы, и фундаментальное отличие состоит в том, что обычно класс предполагает поведение, а кортеж — нет.


Наследование в ООП смешивает как минимум 4 идеи

Ну вы бы хоть сказали, какое из определений наследования вы используете (и зачем вы это делаете).


Наследование интерфейса (Ad hoc полиморфизм) перегружает метод, то есть позволяет по одному имени получить разную реализацию для каждого типа

Тут случилась каша. Интерфейсы не наследуются, а реализуются. И это не ad-hoc-полиморфизм, потому что тот подразумевает разные функции с одним и тем же именем для разных типов, а интерфейсы (опять-таки, если мы про ООП говорим) подразумевают разные типы с общим внешним поведением.


Объединение типов аналогично

А тут я просто не понял, что вы хотели сказать, хотя я знаю, что такое типы-суммы. А представьте себе человека, который первый раз видит этот справочник и наследование вообще?


Pattern Matching деконструирует алгебраический тип-сумму или тип-произведение, то есть это обратная конструктору операция.

Я как-то привык считать, что деконструирует деконструктор (C#), паттерн (F# и Haskell) и так далее. А паттерн-матчингом называется case expression, который на вход получает выражение, а дальше, используя разные варианты его деконструкции (или просто сравнения), выдает следующее выражение (или операцию).


Объект в ООП — замыкание, где свободные переменные являются полями, желательно приватными.

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


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

Спасибо, это даже не определения.


Типаж, интерфейс — тип-произведение, состоящее, в основном, из функций.

Ну во-первых, интерфейсы в ООП (таком, знаете, мейнстримном) совершенно не обязательно состоят из функций; собственно, там и функций-то нет. Во-вторых, я не уверен, что термин "тип-произведение" вообще можно применить к функциям: смотрите, у меня есть два интерфейса, Summable: float -> float и Multipliable: float -> float. У них функции одинакового типа (float -> float), и множество значений одинаковое. Но интерфейсы все равно разные, и их единственная операция имеет разную семантику. Куда семантика-то потерялась?


Шаблон проектирования — неформальное реализация идеи вне языка программирования, поскольку данный язык не поддерживает необходимый уровень абстракции. В другом, более высокоуровневом языке, шаблон возможно реализовать средствами языка.

Из этого тезиса можно сделать вывод, что уровни абстракции — это такая лестница, по которой можно идти вверх. Однако же нет, абстракции могут быть не иерархическими, а просто различными, и два языка одной степени "высокоуровневости" могут иметь разный набор абстракций (тем самым требуя разных паттернов).


Visitor — шаблон проектирования, реализующий Pattern Matching.

… за тем маленьким исключением, что для Visitor строение объекта не обязано быть публичным, а для Pattern Matching — обязано.


Dependency Injection — шаблон проектирования, реализующий функцию высшего порядка, которая принимает зависимости и выдаёт продукт.

… давайте начнем с простого, и выясним, что же такое "продукт"?


Dependency Injection [...] изоморфен шаблону Builder с поправкой на то, что зависимости, обычно, являются функциями.

Во-первых, вы еще не ввели понятие изоморфизма. Во-вторых, DI изоморфен Builder только по реализации, но не по семантике, а это очень важное различие. Впрочем, у вас везде изоморфизм про это забывает.


MVC [...] чистая функция и абстрактный автомат для обработки внешних событий.

Не оригинальный MVC. Оригинальный MVC весь построен на побочных эффектах. Ну и да, это определение не позволяет понять, зачем же это нужно.


Программирование — инженерная наука о композиция кода.

Программирование — не наука (см. определение: "область человеческой деятельности, направленная на выработку и систематизацию объективных знаний о действительности"). Ну и непонятно, в каком значении вы тут употребляете слово "композиция".


Изоморфизм — превращение или замена чего-либо во что-то другое и обратно, то есть суть изоморфных вещей одна.

… и сейчас мы упремся в значение слова "суть". Смотрите:


Рефакторинг — изоморфизм, выполняемый людьми.

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


(собственно, рефакторинг не изоморфен, потому что рефакторинг предполагает неухудшение характеристик)


Оптимизация — изоморфизм, выполняемый компьютером.

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


(Чистая) функция — превращение одного в другое всегда одинаково

Забыли про побочные эффекты.


Функтор превращает один тип в другой (функция на типах), да так, что можно оптимизировать композицию чистых функций.

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


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

Какая связь между монадой Maybe и побочными эффектами? Или монадой "список"? (кстати, у вас список только что был функтором)

Даже не придираясь к утверждению "компьютер умеет рассуждать", здесь опущено важное: компьютер "умеет рассуждать" над данными. То, что вы здесь называете типом — всего лишь метаинформация о "хранилище" (будь то переменная или колонка в БД или впишите что угодно еще), в первую очередь — ограничивающая допустимый набор его значений.

Я имел в виду, "рассуждать" как применять правила вывода в теории доказательств, теории типов и изоморфизме Карри Ховарда. Да, в достаточно мощной теории с типами можно обращаться как с данными: складывать, умножать, матчить, объявлять функции и подставлять в неё аргументы. Грубо говоря, тип — это данные, обрабатываемые в compile time, но граница с runtime может быть размыта. А значения типа ограничены теми, которые можно построить, произвольно комбинируя конструкторы типа.

Я имел в виду, "рассуждать" как применять правила вывода в теории доказательств, теории типов и изоморфизме Карри Ховарда.

Для этого подойдет любой "тип" из любого языка программирования? Или эти типы должны соответствовать определенным критериям?


Грубо говоря, тип — это данные, обрабатываемые в compile time

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

Для этого подойдет любой "тип" из любого языка программирования? Или эти типы должны соответствовать определенным критериям?

Любой тип. Разница в том, что вы можете из него вывести. Например, тип, который определяет, что в нём может лежать всё, что угодно, даёт вам ноль статической информации в compile time и можно назвать его динамическим.


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

Можно не пользоваться статической информацией пораньше в compile time и оставить ошибки до run time. Интерпретируемый или нет — не важно. Можно воспользоваться статическим анализатором кода, который обработает типы в compile time, но сгенерирует не код, а отчёт об ошибках или документацию.

Интерпретируемый или нет — не важно.

Важно. У чистого интерпретируемого языка нет compile time. Да, это вопрос терминологии.


Формально, интересующее вас отличие называется — насколько я помню — именно что статическим анализом, и к компиляции отношения не имеет.

«Интерпретируемость» и «компилируемость» — это в общем случае не свойство языка, а вопрос реализации.

Согласен. Я, говоря "язык", подразумевал сочетание языка и тулсета.

У чистого интерпретируемого языка нет compile time.

Не бывает чистого интерпретируемого языка: сегодня нет компилятора, завтра напишут.


Да, это вопрос терминологии.

Отлично, что мы поняли друг друга! Не устаю повторять, меня интересуют идеи, а не алиасы на идеи (терминология). Есть тучи и тьма конфликтующей терминологии, а ясных идей довольно ограниченное количество и они настолько просты, что их сложно выразить.


Формально, интересующее вас отличие называется — насколько я помню — именно что статическим анализом, и к компиляции отношения не имеет.

Всё, что делает компилятор — это статически анализирует код, сначала лексически, потом синтаксически и семантически, потом изоморфно преобразует семантику в оптимизациях. Но статически анализировать код может, например, форматтер.
Статически vs динамически = рано vs поздно = compile vs run = у разработчика vs на продакшене = в моей ветке vs в мастере. Идея есть, а слова, которое выражает все разом нет.


P.S. Ещё раз спасибо, что указываете места, где я криво и непонятно выражаюсь.

Не устаю повторять, меня интересуют идеи, а не алиасы на идеи (терминология). Есть тучи и тьма конфликтующей терминологии, а ясных идей довольно ограниченное количество и они настолько просты, что их сложно выразить.

Вот именно потому, что людей не интересует терминология, чистой терминологии и не случается.

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

Если типы слабые, то нужно писать больше юнит тестов, и это будет делать не компьютер автоматически, а вручную программист.

… а если типы "сильные", то нужно писать больше типов, и это будет делать не компьютер автоматически, а вручную программист.

  1. Автоматический вывод типов позволяет их не писать.


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

Object = Int + String + Num + ...

Автоматический вывод типов позволяет их не писать.

Для начала их (типы) надо определять. Без этого никакого вывода не будет.

Тип определяется самим упоминанием литерала "Hello, World!": String, и дальше эта информация выводится вверх по синтаксическому дереву.


import Html exposing (text)

main =
  text "Hello, World!"

text здесь — это функция, превращающая строку в HTML


Поиграться можно тут.

Типы String и HTML всё равно же определены где-то?

Конкретно, эти типы определены в стандартной библиотеке.


А здесь 20 строке пример объявления пользовательского типа Msg. И компилятор по телу функции выведет её тип view: Int -> Html Msg, где встречается пользовательский тип.

Тип определяется самим упоминанием литерала "Hello, World!": String,

Значит, где-то кто-то определил тип string


text здесь — это функция, превращающая строку в HTML

Значит, кто-то где-то определил тип html.


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

Конечно, кто-то определил String и Html. И пользовательские типы под бизнес задачи нет проблем определить. Но излишне их потом указывать при каждом объявлении переменной этого типа. Компилятор по правой части равенства выведет тип переменной(ых) автоматически.

И пользовательские типы под бизнес задачи нет проблем определить.

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

Основной код в функциях: в моём пруфе 1 строка объявления пользовательских данных из 30. Комментариев и пустых строк обычно больше. Это типичный код. И эта строка сэкономила ещё 30+ строк на тестах.

Здесь забыт важный пункт: сильные системы типов могут требовать от вас больше работы, чем слабые. Кстати, эй, а что же такое "сильная" и "слабая" система типов?

В сколько-нибудь реальных проектах, написание кода составляет мизерную долю от общего времени разработки и ошибки на этом этапе имеют стоимость нескольких ударов по клавиатуре. Дебаг, тестирование и сопровождение — вот где работа зарыта. И я с удовольствием поменяю сокращение их вдвое на вдвое более сложное кодирование. Сравните на "силу" и "слабость" системы типов Elm и JavaScript.

В сколько-нибудь реальных проектах, написание кода составляет мизерную долю от общего времени разработки

Пожалуйста, источник утверждения в студию.


И я с удовольствием поменяю сокращение их вдвое на вдвое более сложное кодирование.

Вы — возможно. А менеджмент, которому важно время выхода на рынок?


Сравните на "силу" и "слабость" системы типов Elm и JavaScript.

Я еще раз спрашиваю, что такое "сильная" и "слабая" системы типов?

Пожалуйста, источник утверждения в студию.

Любой курс по технологиям разработки ПО, первый попавшийся в гугл.


Вы — возможно. А менеджмент, которому важно время выхода на рынок?

Я рассматриваю именно экономию итогового проекта времени, коэффициенты берите свои:
Кодирование 0.2 времени
Посткодирование 0.8 времени
Итого 0.2*2 + 0.8/2 = 0.8 время сэкономлено


Но доказать экономию времени для менеджента не такая проблема, как обосновать риски при поиске разработчиков, что упомянуто в начале поста. Тут порочный круг: нет внедрений — нет доказательства, нет доказательства — не будет внедрений. Но это вопрос времени, внедрения появляются и лет через 20 всё будет ок.


Я еще раз спрашиваю, что такое "сильная" и "слабая" системы типов?

тут

Любой курс по технологиям разработки ПО, первый попавшийся в гугл.

Там нет такой цитаты (ну или я ее не нашел).


Я рассматриваю именно экономию итогового проекта времени, коэффициенты берите свои:

Вот именно, что свои. В ситуации быстрого выхода на рынок будет 70/30, дальше понятно, что будет?


Но доказать экономию времени для менеджента не такая проблема

Да ну? Я вот точно знаю, что это далеко не маленькая проблема, потому что реальных цифр для конкретного проекта нет.


тут

Дадада, именно: "Эти термины не являются однозначно трактуемыми, и чаще всего используются для указания на достоинства и недостатки конкретного языка".

Там нет такой цитаты (ну или я ее не нашел).

Вторая круговая диаграмма "Программные изделия с большой длительностью эксплуатации".


Вот именно, что свои. В ситуации быстрого выхода на рынок будет 70/30, дальше понятно, что будет?

Открою секрет, для вашего проекта и формула будет другой. Считать в любом случае вам. Но лучше знать о большем числе вариантов.


Да ну? Я вот точно знаю, что это далеко не маленькая проблема, потому что реальных цифр для конкретного проекта нет.

Я говорил, что риски — ещё большая проблема. Проблем много. Другой инструмент даёт другой баланс. Ещё раз, считать и принимать решение все равно вам.


Дадада, именно: "Эти термины не являются однозначно трактуемыми, и чаще всего используются для указания на достоинства и недостатки конкретного языка".

Неоднозначность в этих определениях не влияет на ошибки в продакшн, в отличие от NullPointerException, поэтому меня не сильно беспокоит. Зато это размытое определение направляет меня выбрать инструмент, который уменьшит ошибки на продакшн.

Класс — это не система типов. Класс — это (в некоторых ОО-языках) один из видов типов (простите); иными словами (в некоторых ОО-языках) всякий класс — это тип, но не всякий тип — это класс.

Вы сами используете обтекаемые формулировки "в некоторых ОО-языках" потому, что "ООП — набор идей без единого центрального стержня" и сложно сформулировать утверждение для всех ООП языков. Сравните ваше определение "Класс — один из видов типов" и моё "Класс — одна из систем типов". В чём разница? Они изоморфны. Я согласен с вами, что в ООП есть другие подсистемы типов, например элементарные типы и они не классы.

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

Нет, потому что реализации в разных языках отличаются.


Сравните ваше определение "Класс — один из видов типов" и моё "Класс — одна из систем типов". В чём разница?

В том, что система — это не вид.


Они изоморфны.

Нет. Система не изоморфна виду.


Я согласен с вами, что в ООП есть другие подсистемы типов, например элементарные типы и они не классы.

ООП вообще бывает без классов. А еще можно сделать классы без ООП.

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

Конечно, потому что "ООП — популярный бренд, исторически сложившийся, но не уникальный набор идей без единого центрального стержня." И жестоко просить дать другое общее определение ООП.


В том, что система — это не вид.

Чего нельзя сделать в "Классе, как одном из видов типов", что можно в "Классе, как одной из систем типов" или наоборот?

И жестоко просить дать другое общее определение ООП.

Поэтому не надо пытаться дать общее определение ООП (если вы не можете этого сделать).


Чего нельзя сделать в "Классе, как одном из видов типов", что можно в "Классе, как одной из систем типов" или наоборот?

А я не понимаю, что такое "класс как система типов", это просто бессмысленное выражение. Класс — это частный случай типа; система типов — не частный случай типа.

Поэтому не надо пытаться дать общее определение ООП (если вы не можете этого сделать).

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

Аналоги: запись, кортеж, тип-произведение.
Нет. Если мы говорим о более-менее устоявшихся определениях, то запись, кортеж и типы-произведения — это не классы, и фундаментальное отличие состоит в том, что обычно класс предполагает поведение, а кортеж — нет.

Я не говорю об определениях, а об аналоге, чем класс можно заменить. Наименьший общий знаменатель в классах — это данные, например, в Data классе нет поведения. Поведение можно упаковать отдельно в функцию и первый аргумент назвать this. Данные и функции можно упаковать в модуль. Разбиение класса на более мелкие сущности (данные и функции) имеет преимущества. Например, когда в функции (типа Java equals) нужен "второй this" приходится вводить интерфейс Comparable, когда это просто функция a->a->Bool. Или меньшая связность кода: функции над одними данными можно поместить в разные модули, а не в классы, связанные наследованием. Или не нужно думать, как раскладывать функции по классам, когда есть несколько подходящих.

об аналоге, чем класс можно заменить

Класс в общем случае нельзя заменить кортежем.


(а если продолжать эту цепочку дальше, то кортеж можно заменить просто набором переменных)


Наименьший общий знаменатель в классах — это данные

Нет же. Можно иметь класс без данных (или без публичных данных).


Разбиение класса на более мелкие сущности (данные и функции) имеет преимущества.

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

Класс в общем случае нельзя заменить кортежем.

Кортеж + функции, принимающие этот кортеж. Пруф хотя бы одного примера из общего случая.


Нет же. Можно иметь класс без данных (или без публичных данных).

Публичных / не публичных, к этому вопросу не относится, это вопрос к модульной системе.
У класса без данных (без состояния) все функции можно сделать статическими, и, вообще, расформировать класс, оставив только эти функции. Это проблема языка, что он обязывает оборачивать такие функции внутрь класса.


(а если продолжать эту цепочку дальше, то кортеж можно заменить просто набором переменных)

Да. Компилятор идёт ещё дальше и заменяет на просто ссылки в памяти.


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

Как будет угодно, мне не важно, что такое класс, а важно, что им можно сделать. И equals(Object) — это косяк ООП, когда нужен equals(Self).

Кортеж + функции, принимающие этот кортеж.

Ну так "плюс" же. Одним кортежем обойтись не удалось.


(и это мы еще в тонкие вопросы инкапсуляции не вдавались)


Компилятор идёт ещё дальше и заменяет на просто ссылки в памяти.

Но это же не значит, что просто переменные — это аналог кортежа?


У класса без данных (без состояния) все функции можно сделать статическими, и, вообще, расформировать класс, оставив только эти функции.

А вы не знаете, есть у него состояние, или нет. Вы знаете только то, что у него есть такие-то методы, которые то-то делают.


Как будет угодно, мне не важно, что такое класс, а важно, что им можно сделать.

А зря. Потому что вы опять забываете про семантику.


И equals(Object) — это косяк ООП

Я что-то не помню, чтобы ООП в целом требовало какого-то equals(Object), и не понимаю, где здесь косяк.

Ну так "плюс" же. Одним кортежем обойтись не удалось.

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


(и это мы еще в тонкие вопросы инкапсуляции не вдавались)

Инкапсуляция, модульная система реализуется на замыканиях, за примером обратитесь к JavaScript.


Но это же не значит, что просто переменные — это аналог кортежа?

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


А вы не знаете, есть у него состояние, или нет. Вы знаете только то, что у него есть такие-то методы, которые то-то делают.

Слово "заменить" означает, например, что я разрабатываю этот класс или провожу рефакторинг и обязан знать внутренности.


Я что-то не помню, чтобы ООП в целом требовало какого-то equals(Object), и не понимаю, где здесь косяк.

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

Наследование в ООП смешивает как минимум 4 идеи
Ну вы бы хоть сказали, какое из определений наследования вы используете (и зачем вы это делаете).

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

Никакое определение конкретно и все определения в сумме

Это называется "я взял свое понимание наследования, и описал его". Ну что ж, ваше понимание неверно.

Озвучте верное.

"In object-oriented programming, inheritance is when an object or class is based on another object (prototypal inheritance) or class (class-based inheritance), using the same implementation."


Это если википедии верить. Там дальше, кстати, как раз написано, что не надо путать с сабтайпингом (который is a).

"… class-based inheritance… is when… class is based on another… class, using the same implementation"


Больше похоже на тавтологию. А что такое "based, using the same implementation". Делегирование тоже подходит: мы использует ту же реализацию.


Я скептически отношусь к определениям на человеческом языке и считаю, что нет смысла их оттачивать до бесконечности, как нет смысла стремиться к 100% покрытию кода тестами: всегда останутся непокрытые ветки и зыбкие аксиомы. Стремиться к 100% корректности имеет смысл только в формальных языках, Coq какой-нибудь.


P.S. Лимит времени на обсуждение у меня вышел. Ещё раз спасибо.

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

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


Но ладно бы, это ваше дело, но ведь люди, которые придут читать этот справочник, попадут в ту же ловушку.

Вы не сводите к простому определению, вы ищете замену в рамках понятной вам элементной базы.

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


это приводит к потере оригинальной семантики

В этом и проблема — нет никакой универсальной оригинальной семантики.


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

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

Отличаются как раз реализации, а не идеи.


То ли дело стандартный научный базис: все термины однозначны.

… я же говорил, что программирование — не наука?


Определение — и есть разложение в элементную базу.

Без потери семантики.


В этом и проблема — нет никакой универсальной оригинальной семантики.

Ее в том числе и потому, что людям плевать на термины. Когда вы подменяете термин своим его пониманием, вы тоже не вводите универсальную тематику, вы просто выбрасываете понятие.

Во-первых, спасибо большое, что так обстоятельно ответили. Я ожидал от поста именно такой дискуссии и вы единственный откликнувшийся.

Во-вторых, вы совершенно правы с точки зрения популярного восприятия через призму ООП. Но для меня этого мало. Меня интересует связь ООП и ФП, не то, что из них лучше, а что между ними общего. Это разные подходы, не конвертируемые один в один, поэтому кратких и точных определений без длинного списка исключительных случаем дать не могу. Точные определения есть в интернетах, не вижу смысла их копипастить. Об этом дано предупреждение ещё в начале поста, что он «очень краткий, и поэтому неполный и не претендующий на точность». Возможно, стоит заменить слово «определение», на «понятие» или даже «восприятие».

В-третьих, в следующих отдельных комментариях отвечу вам, приведу ссылки и разъясню, что я имею в виду.
Меня интересует связь ООП и ФП, не то, что из них лучше, а что между ними общего.

… и для этого вы пытаетесь объяснить понятия из ООП с помощью терминологии из ФП. Но это так не работает. Это не "общее", это "как сделать одно через другое" — забыв про интент и семантику.

Общая суть — это и есть "одно через другое" и наоборот, см. изоморфизм. Меня интересует именно интент, даже прагматика. Ну а семантика, да, пришлось пожертвовать во имя краткости на 3 порядка, о чем написал в предупреждении "не претендующий на точность".

Общая суть — это и есть "одно через другое" и наоборот, см. изоморфизм.

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


Ну а семантика, да, пришлось пожертвовать во имя краткости

Так семантика — это то, чем в программировании жертвовать нельзя.

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

Извините, что сильно порезал вашу цитату, чтобы показать, что это тавтология.


Результат — есть суть того, к чему я стремлюсь по определению "программирование — инженерная наука о композиция кода". Ключевое слово инженерная, то есть нужен практический результат. Если результата можно достичь несколькими способами, то я выберу самый дешёвый и прагматичный.


Так семантика — это то, чем в программировании жертвовать нельзя.

Я пожертвовал семантикой ООП потому, что, во-первых, в ней нет "единого центрального стержня"; во-вторых, пожертвовал в обмен на семантику ФП; в-третьих, прагматика выше мастью, чем семантика по определению программирования.

Результат — есть суть того, к чему я стремлюсь по определению "программирование — инженерная наука о композиция кода". Ключевое слово инженерная, то есть нужен практический результат. Если результата можно достичь несколькими способами, то я выберу самый дешёвый и прагматичный.

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


Я пожертвовал семантикой ООП потому, что, во-первых, в ней нет "единого центрального стержня"; во-вторых, пожертвовал в обмен на семантику ФП;

Вот это "в обмен" и демонстрирует, что они не одинаковы. Значит, вы не нашли общую суть, а заменили одну другой.

> программирование — не наука

В том числе [наука](https://ru.wikibooks.org/wiki/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5), но не только.

По моим оценкам, сопровождение продукта, когда компилятор 100% верифицировал отсутствие класса ошибок, например NullPointerException, будет дешевле, чем когда программист частично покрыл его тестами. Но тут каждый выбирает сам и получает финансовую обратную связь.

> Вот это «в обмен» и демонстрирует, что они не одинаковы. Значит, вы не нашли общую суть, а заменили одну другой.

Формальное определение одинаковости, операторы неформальны:

(a = b) ~ (a <= b) & (b <= a)
В том числе наука

Нет. Вы определение науки видели? Если что-то "сочетает в себе элементы [...] науки", оно наукой еще не становится.


По моим оценкам, сопровождение продукта, когда компилятор 100% верифицировал отсутствие класса ошибок, например NullPointerException, будет дешевле, чем когда программист частично покрыл его тестами.

Вот только этот пример не имеет никакого отношения к семантике. Я говорю только о том, что игнорируя семантику, вы не можете обсуждать сопровождаемость продукта людьми.


(само утверждение при этом не буду ни подтверждать, ни опровергать, недостаточно информации)


Формальное определение одинаковости, операторы неформальны:

Мне это ничего не говорит.

Нет. Вы определение науки видели? Если что-то "сочетает в себе элементы [...] науки", оно наукой еще не становится.

Эх! Согласен с вами и моё намерение процент содержания этой науки увеличить.


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

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


Мне это ничего не говорит.

Например, равенство множеств

Согласен с вами и моё намерение процент содержания этой науки увеличить.

Зачем? Есть CS, есть SE, зачем их смешивать-то?


Я игнорирую семантику ООП в этом посте

… при этом давая определения терминам из ООП. Не надо так.


В основном, потому что её как таковой нет в достаточно строгом смысле

Она есть. Множественность определений не отменяет семантики.

Sign up to leave a comment.

Articles

Change theme settings