стандартная библиотека языка должна быть настолько мощной и согласованной, чтобы не пришлось ее переделывать.
Если бы мы жили в идеальном мире — нам хватило бы грубо говоря двух-трёх языков на все случаи жизни. Но основная проблема в том, что PHP ухитрился обогнать конкурентов на рынке и обогнал он их не благодаря качеству. Поэтому имеем то, что имеем.
Проблема конфликта имён — возможно переоценена, я за почти десять лет работы с PHP с подобным конфликтом не сталкивался. Теперь же у нас есть пространства имён, которые призваны решить проблему и вопрос уже не стоит и выеденного яйца.
Практика показывает, что «дикое количество» сводится к «паре десятков». Да и их я себе заменил больше из эстетических соображений, чем по практической надобности. PHP далёк от идеала функциональных языков, очень далёк ))
Говоря про языки я имел в виду наверно немного другое (если я Вас правильно понял).
Но с практической точки зрения наверно самым интересным было бы действительно взять все популярные языки из разных парадигм, взять некоторый набор задач и рассмотреть доступные способы решения, их плюсы и минусы, возможность трансформации кода следом за модификацией постановки задачи и т.п. — это наверно уже масштаб целой книги… или создания специализированной вики.
Вынесенное в публичное обсуждение это позволит высказаться всем и привести в пример лучшие практики каждого языка. Что значительно приблизит нас к объективной точке зрения, а заодно, возможно, кому-то и облегчит миграцию.
Ну и, как выше уже была попытка привести в пример эллипс с lockedAspectRatio — наличие такого свойства у эллипса уже даже без наследования приведёт к разному поведению кода
fig.stretchX(2).stretchY(2);
для разных состояний поля lockedAspectRatio, независимо от того, равны оси или не равны.
В общем, после некоторой медитации над этой задачей прихожу к выводу, что здесь проблема именно в попытке разделить сущность круга и сущность эллипса на две различные, в то время как это недопустимо, следуя из use cases модели. Подмножества состояний объекта не проецируются прямо на подмножества моделей поведения объекта. Решать задачу «в лоб» — будет ошибкой.
Кстати, возвращаясь к парадоксу эллипс/круг, ромб/квадрат и т.п. — возможно ошибка кроется ещё и в том, что круг в действительности не является другой, а тем более наследующей, сущностью, а лишь частным случаем состояния изначальной. В итоге может получиться архитектура, где объект со свойствами фигуры — один, но у него есть диспетчер поведения, который может выбрать разные реализации под конкретные случаи и уже у классов поведения будут разные методы модификации экземпляра фигуры, но не у самой фигуры, а экземпляры классов поведения будут неразрывно связаны с породившим их экземпляром фигуры. То есть будет mutable Фигура и immutable морфинг_фигуры.
То есть вопрос здесь не в ООП, а лишь в том, что в любой парадигме можно выбрать неудачный способ решения задачи. Кроме того, сама постановка «парадокса» не уточняет такой важный параметр, который ожидается от поведения системы в целом — наследники должны переопределять правила поведения или не должны. Под что система проектируется, таков и путь решения задачи и возможно это моё утверждение действительно ставит под вопрос абсолютную безусловность пункта L.
Именно так — интерфейс летит ко всем чертям вместе со всем зависимым кодом, поскольку зависимый код ожидает от класса, что с name он работать умеет и будет.
И без объектов будет такая же досада — если функция ожидает, что в структуре просто обязано быть поле name, а его оттуда убирают — все функции, работающие с этой структурой уже не будут работоспособны.
Другое дело, если объект представляет из себя список или хранилище «ключ-значение» без ожидаемого набора ключей и элементов — удаление одного из них ни для кого не окажется сюрпризом, опять же независимо от парадигмы.
Именно так. Причём «сферическое» ООП как парадигма ещё дальше от этого вопроса, чем ООП реализованное в конкретных языках. И одна и та же задача в разных языках будет оптимально решена разными способами.
То, что язык не позволяет работать напрямую с указателями, ещё не значит, что их нет ;)
Если в реализации используется указатель, это совершенно не значит, что реализуемое — является указателем. Да и откуда Вы знаете, что там именно указатель используется, а не индекс в таблице сущностей?
Полиморфизм полиморфизму рознь. Такого полиморфизма, как в Java, в JavaScript нет.
Полиморфи́зм (от греч. πολὺ- — много, и μορφή — форма) в языках программирования — возможность объектов с одинаковой спецификацией иметь различную реализацию.
Ну а то, что в разных языках есть разная реализация этого свойства не говорит о том, что это два разных полиморфизма. Да, в JavaScript нельзя строго затребовать наличие интерфейса средствами языка, также как нельзя объявить для этого сам интерфейс, но реализовать такую функциональность — можно. Поэтому в JavaScript полиморфизм может повторить реализованный в Java — если задаться такой целью, но может и отличаться и реализовать другое видение этой концепции.
А в чём по Вашему разница в полиморфизмах? Чем один столь существенно отличается от другого, что Вы предлагаете говорить о разных сущностях и случайном совпадении названий?
Если класс уже ушел в продакшн, то уже ничего не поменяешь
Как это не поменяешь? Да сразу после выхода в продакшн изменения учащаются, по сравнению со стадией разработки. Стабильным остаётся только интерфейс, но реализация — пилится и точится под весьма динамичные требования, пока не будет достигнут приемлемый статус и не будут выловлены все баги и бутылочные горлышки на реальных задачах.
Более того, в классе родителе прямая запись в поле могла ничего не портить, зато в наследнике — логика меняется. При наличии сеттера это не вопрос, при прямом доступе к полю — проблема неразрешима.
Если портит — берём и исправляем реализацию сеттера. При наличии прямого доступа к полю это было бы невозможно. Так что геттер/сеттер — правильнее и не эквивалентен прямому доступу.
наличие геттеров и сеттеров для поля равносильно открытию поля
На основании чего Вы утверждаете о равносильности?
В этой версии — значение передаётся напрямую, в следующей версии — функциональность шире. В наследниках появляется ещё какая-нибудь функциональность, которая не нужна была в родителе.
Но система в целом продолжает работать так, будто ничего не изменилось и ничто не рушится. Поэтому — не равносильно.
Если бы мы жили в идеальном мире — нам хватило бы грубо говоря двух-трёх языков на все случаи жизни. Но основная проблема в том, что PHP ухитрился обогнать конкурентов на рынке и обогнал он их не благодаря качеству. Поэтому имеем то, что имеем.
Проблема конфликта имён — возможно переоценена, я за почти десять лет работы с PHP с подобным конфликтом не сталкивался. Теперь же у нас есть пространства имён, которые призваны решить проблему и вопрос уже не стоит и выеденного яйца.
В идеале он должен быть документирован phpDoc'ом.
Можно было бы посодействовать его документации.
Кстати, в php функции не передаются просто так, их в любом случае придётся завернуть в лямбду или передать по имени.
Но с практической точки зрения наверно самым интересным было бы действительно взять все популярные языки из разных парадигм, взять некоторый набор задач и рассмотреть доступные способы решения, их плюсы и минусы, возможность трансформации кода следом за модификацией постановки задачи и т.п. — это наверно уже масштаб целой книги… или создания специализированной вики.
Вынесенное в публичное обсуждение это позволит высказаться всем и привести в пример лучшие практики каждого языка. Что значительно приблизит нас к объективной точке зрения, а заодно, возможно, кому-то и облегчит миграцию.
для разных состояний поля lockedAspectRatio, независимо от того, равны оси или не равны.
В общем, после некоторой медитации над этой задачей прихожу к выводу, что здесь проблема именно в попытке разделить сущность круга и сущность эллипса на две различные, в то время как это недопустимо, следуя из use cases модели. Подмножества состояний объекта не проецируются прямо на подмножества моделей поведения объекта. Решать задачу «в лоб» — будет ошибкой.
То есть вопрос здесь не в ООП, а лишь в том, что в любой парадигме можно выбрать неудачный способ решения задачи. Кроме того, сама постановка «парадокса» не уточняет такой важный параметр, который ожидается от поведения системы в целом — наследники должны переопределять правила поведения или не должны. Под что система проектируется, таков и путь решения задачи и возможно это моё утверждение действительно ставит под вопрос абсолютную безусловность пункта L.
И без объектов будет такая же досада — если функция ожидает, что в структуре просто обязано быть поле name, а его оттуда убирают — все функции, работающие с этой структурой уже не будут работоспособны.
Другое дело, если объект представляет из себя список или хранилище «ключ-значение» без ожидаемого набора ключей и элементов — удаление одного из них ни для кого не окажется сюрпризом, опять же независимо от парадигмы.
Если в реализации используется указатель, это совершенно не значит, что реализуемое — является указателем. Да и откуда Вы знаете, что там именно указатель используется, а не индекс в таблице сущностей?
Полиморфизм полиморфизму рознь. Такого полиморфизма, как в Java, в JavaScript нет.
Полиморфи́зм (от греч. πολὺ- — много, и μορφή — форма) в языках программирования — возможность объектов с одинаковой спецификацией иметь различную реализацию.
Ну а то, что в разных языках есть разная реализация этого свойства не говорит о том, что это два разных полиморфизма. Да, в JavaScript нельзя строго затребовать наличие интерфейса средствами языка, также как нельзя объявить для этого сам интерфейс, но реализовать такую функциональность — можно. Поэтому в JavaScript полиморфизм может повторить реализованный в Java — если задаться такой целью, но может и отличаться и реализовать другое видение этой концепции.
А в чём по Вашему разница в полиморфизмах? Чем один столь существенно отличается от другого, что Вы предлагаете говорить о разных сущностях и случайном совпадении названий?
Как это не поменяешь? Да сразу после выхода в продакшн изменения учащаются, по сравнению со стадией разработки. Стабильным остаётся только интерфейс, но реализация — пилится и точится под весьма динамичные требования, пока не будет достигнут приемлемый статус и не будут выловлены все баги и бутылочные горлышки на реальных задачах.
На основании чего Вы утверждаете о равносильности?
В этой версии — значение передаётся напрямую, в следующей версии — функциональность шире. В наследниках появляется ещё какая-нибудь функциональность, которая не нужна была в родителе.
Но система в целом продолжает работать так, будто ничего не изменилось и ничто не рушится. Поэтому — не равносильно.