> Но как на хаскеле existentials помогают эмулировать подтипы?
data IShow = forall a. (Show a) => IShow a
тогда любой инстанс IShow ведет себя так же, как в ООП ведет себя класс, реализующий интерфейс IShow. Отличие только в наличии обертки, но на самом деле чисто с формальной точки зрения запись data IShow = forall a. (Show a) => a тоже валидна, просто в хаскеле так нельзя (вроде бы нельзя, по крайней мере, без каких-то хитрых расширений).
> Речь идёт о том, есть ли у вас возможность не мыслить в терминах кучки DOM элементов и скриптов, или такой возможности нет.
Ну так она и есть. У вас же нету ни дома, ни скриптов. Как вы можете мыслить тем, чего нет?
> но при наличии развитой библиотеки компонент
Мы зачем-то все в одну кучу мешаете. Задача ангуляра — абстрагироваться от манипуляций с домом, html и прочим. Он это делает. А библиотеку компонентов предоставлять — задача библиотек компонентов.
> и не должен волноваться, какой конечный HTML/JS/CSS сгенерится в результате.
> Я никак не могу взять в толк, каким образом мне помогла бы IDE и каким образом я могу обойтись без отладчика в браузере, если проблема специфична для браузера.
А я никак не могу понять, чем вам поможет отладчик. Именно в том случае, если проблема специфична для браузера.
> Я видел программы на C#, в которых все методы были статические и находились в классе Program
Но ведь _класс_, да еще и статический — это со всей очевидностью ООП-шная конструкция. Как и методы. Ровно в той же степени, как интерфейсы или абстрактные классы. Разве из этого не следует сразу сделать вывод, что это код в ООП-стиле? И не-ООП код, получается, на c# вообще не написать?
Мне кажется, что в рамках подобной логики абсолютно любой код на языке, поддерживающем ООП, будет считаться написанным в ООП-стиле. По крайней мере, мне не удалось сейчас придумать какой-то контр-пример.
> Интерфейс как элемент языка очень похож на абстрактный класс без полей.
Давайте по порядку. Есть интерфейсы, интерфейсы — это контракты (абстрактные классы, конечно же, тоже). Идея накладывать контракты на программные сущности — не является чем-то специфичным для ООП. Это моя точка зрения. Можете свою полностью сформулировать, потому что мне совершенно непонятно, к чему вы ведете.
> Применительно к интерфейсам в C#, при реализации интерфейса в некотором смысле наследуются все методы-расширения, определенные для этого интерфейса. Например, любой класс, реализующий IEnumerable, автоматически получает методы-расширения Where, Select, SelectMany, Join и прочие.
И? Это вы к чему? Как это меняет тот факт, что интерфейс — это контракт?
> Если вы так не считаете — то я не понимаю какой тезис вы пытаетесь отстоять в этом споре.
Мой тезис — интерфейсы не имеют никакого отношения к ООП. Они вообще не привязаны к какой-либо парадигме и существуют хоть в ООП, хоть в ФП, хоть в процедурном программировании (интерфейс модуля, например).
> Кроме того, тут используется паттерн из мира ООП («итератор»)
Это как вы определили, что там используется итератор? Из кода это никак не следует.
> С того, что тут задействуются два кита ООП — наследование и полиморфизм
Интерфейсы не наследуются, а реализуются. И если интерфейс в стиле тайпклассов хаскеля, не предполагает полиморфизма подтипов (по крайней мере вне костылей из existential types)? Будет уже не ООП?
> Вот пример из документации: docs.angularjs.org/guide/templates, в котором чёрным по белому говорится про HTML разметку, расширенную (augmented) директивами Angular.
Тут возникла терминологическая путаница, возможно, я сам виноват, что не уточнил. Когда в 2017 упоминают ангуляр, то обычно имеется ввиду второй (четвертый, пятый, ну и так далее) ангуляр, который совсем другой фреймворк.
> Вот в таком случае абстракция как раз и будет, но не в случае с web приложениями.
Так она и есть, что значит «будет»? И почему не в случае с веб-приложениями?
> web приложения в современном виде не являются образчиком вменяемого подхода к разработке приложений в общем смысле
Пока что лучшего подхода для разработки УИ не придумали, хотя делалось много разных попыток. За неимением гербовой — приходится писать на простой.
> Не использовать отладчик в браузере или не использовать отладчик вообще?
Никто не говорит о неиспользовании в принципе, это уже будет какое-то религиозное убеждение. Речь о том, что реальная потребность в его использовании возникает крайней редко.
> Исходники чего, браузеров?
Так вы про отладку чего, самого браузера, в опкодах? Я-то думал вы про js, уточняйте тогда хоть.
> Особенно интересно про снижение количества синтаксического мусора и и семантической нагрузки в коде, при повышении плотности.
Если токен не несет никакой полезной ф-и (таковыми, например, часто являются скобки) — его можно убрать, плотность повысится, мусора станет меньше.
Если есть конструкция, которая инкапсулирует в себе несущественные детали поведения — кода становится меньше, плотность возрастает, а семантическая нагрузка падает. Пример: замена классического цикла for на map. В данном случае из кода пропадает информация о о счетчике, и о логике построения коллекции. По-этому collection.map(x => ...) вместо for — это хорошее, годное упрощение.
Проблема состоит во взаимодействии двух вещей:
1. В случае ООП мы работаем со стейтом, вместо того, чтобы прокидывать аргументы явно
2. Проверяемые исключения не являются first class citizen
В итоге на практике сильно ограничивается возможность композиции методов с проверяемыми исключениями. В случае монад мы можем писать как угодно методы без исключений, а потом на самом верху лифтануть в функтор по нужному аргументу. При этом весь внутренний код о наличии дополнительной обработки сверху не в курсе. В случае с исключениями они по стеку протекают от внутреннего метода до внешних — везде «заражая» сигнатуры, которые при изменениях постоянно надо поправлять или перебрасывать исключения. В итоге на практике вместо того, чтобы инструментом пользоваться, его стремятся сломать и обойти, потмоу что чересчур много геморроя. Если бы ООП код писался в ФП стиле, с явной передачей, то этой проблемы бы не было, т.к. логику можно было бы точно так же выделить, а потом пробрасывать аргументы сверху.
Да нет, не использовать отладчик — вполне обычная практика.
> В случае клиентов Sencha это как раз я и ещё несколько таких же болезных.
Ну у вас же есть исходники? Зачем тогда отладчик? Обычно, почти всегда гораздо быстрее просмотреть код, чтобы найти ошибку, чем дебажить. Другое дело, если код откровенно плох.
Любой инстанс Show, конечно же.
data IShow = forall a. (Show a) => IShow a
тогда любой инстанс IShow ведет себя так же, как в ООП ведет себя класс, реализующий интерфейс IShow. Отличие только в наличии обертки, но на самом деле чисто с формальной точки зрения запись data IShow = forall a. (Show a) => a тоже валидна, просто в хаскеле так нельзя (вроде бы нельзя, по крайней мере, без каких-то хитрых расширений).
Ну так она и есть. У вас же нету ни дома, ни скриптов. Как вы можете мыслить тем, чего нет?
> но при наличии развитой библиотеки компонент
Мы зачем-то все в одну кучу мешаете. Задача ангуляра — абстрагироваться от манипуляций с домом, html и прочим. Он это делает. А библиотеку компонентов предоставлять — задача библиотек компонентов.
> и не должен волноваться, какой конечный HTML/JS/CSS сгенерится в результате.
Так он и не волнуется :)
А я никак не могу понять, чем вам поможет отладчик. Именно в том случае, если проблема специфична для браузера.
Но ведь _класс_, да еще и статический — это со всей очевидностью ООП-шная конструкция. Как и методы. Ровно в той же степени, как интерфейсы или абстрактные классы. Разве из этого не следует сразу сделать вывод, что это код в ООП-стиле? И не-ООП код, получается, на c# вообще не написать?
Костыли — в качестве эмуляции подтипирования. Потому что подтипирование в хаскеле считается ненужным.
> Что вы называете подтипами?
Не совсем понимаю вопроса. То же, что и все? Есть системы типов с подтипированием (например, lambda<:), у них есть семантика.
Давайте по порядку. Есть интерфейсы, интерфейсы — это контракты (абстрактные классы, конечно же, тоже). Идея накладывать контракты на программные сущности — не является чем-то специфичным для ООП. Это моя точка зрения. Можете свою полностью сформулировать, потому что мне совершенно непонятно, к чему вы ведете.
И? Это вы к чему? Как это меняет тот факт, что интерфейс — это контракт?
> Если вы так не считаете — то я не понимаю какой тезис вы пытаетесь отстоять в этом споре.
Мой тезис — интерфейсы не имеют никакого отношения к ООП. Они вообще не привязаны к какой-либо парадигме и существуют хоть в ООП, хоть в ФП, хоть в процедурном программировании (интерфейс модуля, например).
В хаскеле нету классов
То есть если я поменяю IEnumerable на List, код чудесным образом перестанет быть ООП?
> Это всего лишь особенность конкретного языка.
Это особенность интерфейсов. Интерфейсы нельзя наследовать, потому что интерфейс — это контракт. Что значит «наследовать контракт»?
> Мы все еще говорим о C# и Java или обсуждаем какой-то неопределенный язык программирования?
Какая разница, на каком? У вас что, _один и тот же_ код то функциональный, то ООП в зависимости от того, какой язык?
Это как вы определили, что там используется итератор? Из кода это никак не следует.
> С того, что тут задействуются два кита ООП — наследование и полиморфизм
Интерфейсы не наследуются, а реализуются. И если интерфейс в стиле тайпклассов хаскеля, не предполагает полиморфизма подтипов (по крайней мере вне костылей из existential types)? Будет уже не ООП?
Тут возникла терминологическая путаница, возможно, я сам виноват, что не уточнил. Когда в 2017 упоминают ангуляр, то обычно имеется ввиду второй (четвертый, пятый, ну и так далее) ангуляр, который совсем другой фреймворк.
> Вот в таком случае абстракция как раз и будет, но не в случае с web приложениями.
Так она и есть, что значит «будет»? И почему не в случае с веб-приложениями?
> web приложения в современном виде не являются образчиком вменяемого подхода к разработке приложений в общем смысле
Пока что лучшего подхода для разработки УИ не придумали, хотя делалось много разных попыток. За неимением гербовой — приходится писать на простой.
Никто не говорит о неиспользовании в принципе, это уже будет какое-то религиозное убеждение. Речь о том, что реальная потребность в его использовании возникает крайней редко.
> Исходники чего, браузеров?
Так вы про отладку чего, самого браузера, в опкодах? Я-то думал вы про js, уточняйте тогда хоть.
Если токен не несет никакой полезной ф-и (таковыми, например, часто являются скобки) — его можно убрать, плотность повысится, мусора станет меньше.
Если есть конструкция, которая инкапсулирует в себе несущественные детали поведения — кода становится меньше, плотность возрастает, а семантическая нагрузка падает. Пример: замена классического цикла for на map. В данном случае из кода пропадает информация о о счетчике, и о логике построения коллекции. По-этому collection.map(x => ...) вместо for — это хорошее, годное упрощение.
1. В случае ООП мы работаем со стейтом, вместо того, чтобы прокидывать аргументы явно
2. Проверяемые исключения не являются first class citizen
В итоге на практике сильно ограничивается возможность композиции методов с проверяемыми исключениями. В случае монад мы можем писать как угодно методы без исключений, а потом на самом верху лифтануть в функтор по нужному аргументу. При этом весь внутренний код о наличии дополнительной обработки сверху не в курсе. В случае с исключениями они по стеку протекают от внутреннего метода до внешних — везде «заражая» сигнатуры, которые при изменениях постоянно надо поправлять или перебрасывать исключения. В итоге на практике вместо того, чтобы инструментом пользоваться, его стремятся сломать и обойти, потмоу что чересчур много геморроя. Если бы ООП код писался в ФП стиле, с явной передачей, то этой проблемы бы не было, т.к. логику можно было бы точно так же выделить, а потом пробрасывать аргументы сверху.
Да нет, не использовать отладчик — вполне обычная практика.
> В случае клиентов Sencha это как раз я и ещё несколько таких же болезных.
Ну у вас же есть исходники? Зачем тогда отладчик? Обычно, почти всегда гораздо быстрее просмотреть код, чтобы найти ошибку, чем дебажить. Другое дело, если код откровенно плох.