LINUX.ORG.RU

[ЖЖ] *морфизм, Haskell & Lisp

 


3

1

Вот все праздники разбирался с Template Haskell, квазицитированием, SYB и ghc7, не забывая такие важные вещи как распитие спиртных напитков и игру в FreeCiv :)

И вот какая идея мне пришла в голову... Катаморфизм ведь — штука всеобъемлющая, и если лисперы могут называть свои S-выражения алгебраическими типами данных, то почему же мы не можем называть алгебраические типы данных S-выражениями?

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

Единственное, «но» в подходе лисп-систем к компиляции, там компилятор «внутри», а не «с боку» как в более традиционных подходах. А так, работы ведутся, та же Java, та же Scala позволяет вмешиваться в работу компилятора. А в GHC есть Template Haskell, который идеологически близок к лисповским макросам, с той только разницей, что они стоят по разные стороны относительно катаморфизма: лисп как списки, хаскель как алгебраические типы с соответствующей типизацией.

В ООП языках все еще интереснее, там для реализации лисповского подхода нужно две вещи: а) классы должны быть объектами первого класса; б) должен быть способ узнавать конкретный тип объекта в рантайме. В Яве есть и первое (на худой конец в рамках JVM), и второе. В С++ есть RTTI, а вот с первым дела обстоят вроде бы не очень, хотя Александреску в своей книге показывал, вроде бы, как можно генерить иерархию классов с помощью шаблонов. Про Scala, вообще молчу, там алгебраические типы «из коробки» имеются.

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

★★★★★
Ответ на: комментарий от archimag

> В реальной практике разработки на динамических языках таких ситуаций я не встречал

Как пример, приведу Федоровскую Anaconda, хоть она и на Python написана. В 10-ом или 11-ом релизе Федоры эта самая анаконда при попытке выкачать обновления при установке из отключенных интернетов валилась с ошибкой о каком-то отсутствующем методе (не помню уже наизусть, давно дело было). Если не требовать закачки обновлений при установке — всё ровно-гладко. А в статическом языке этот косяк выявился бы уже при компиляции, и в релиз не пошёл.

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

> У тебя просто висит несколько условий, которые при тестовом

запуске false


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

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

И, кстати, повышенная любовь к исключениям (exception) в компилируемых языках со статической типизацией (да хоть те же плюсы взять) меня тоже сильно расстраивает. Конпелятор не хочет мне сказать при конпеляции, что вот та и эта функции могут кинуть такое и эдакое исключения. Я собираю проект без оборачивания функций в try-catch, а потом выясняется, что при определённой фазе луны эти исключения таки бросаются, и программа, вместе со своей типизацией, вылетает. Очень здорово. Спасибо.

Заранее предупреждая упрёки о недопрочтении документации к функциям и классам по поводу их возможных исключений — хорошо, если оная документация есть. А при наследовании да агрегации приходится просматривать всё дерево наследуемых классов, и используемых тоже, чтобы убедиться в их безопасности по отношению к исключениям. А это — 3,14здец, и не лечится.

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

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

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

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

И как ты планируешь обойти все узлы состояний системы, если их там over 9000, и на некоторых происходит затык? А если система типов достаточно мощная, чтобы эти условия описать, то конпелятор тебе об этом скажет ещё до того, как код уйдёт в эксплуатацию.

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

[code] (defun foo (x) (when (not (eq? 45677856423785623785678 x)) (defun yoba () `yoba)))

(foo (read)) (yoba) [/code] А теперь скажи, как мне это запустить, чтобы оно упало?

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

> И как ты планируешь обойти все узлы состояний системы, если их там over 9000, и на некоторых происходит затык?

А никак. Если есть евал - то это даже теоретически невозможно.

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

> И что? В статическом языке это валилось бы с чем-нибудь более страшным, ибо код с отключенным интернетом никто не тестировал.

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

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

Для этого придуманы юниттесты

100% покрытия всё равно не случится, да и эти тесты надо уметь писать, и правильно интерпретировать результаты их выполнения.

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

> А кто тебе сказал, что код в статических языках не тестируется?

Вы с кем разговариваете? Я ничего подобного не говорил. Научитесь читать.

в статическом проверять уже не нужно, оно гарантированно

работает правильно.



Очень смешно.

пытаются покрыть миллиардами тестов свой код


Вы что, серьёзно не в курсе для чего пишут тесты? Хватить тролить то уже.

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

> (eval (read))

Ну, REPL, ну и что? Само наличие eval, по твоему, даст прохождение по всем условиям и значениям входных переменных само собой?

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

> Очень смешно.

Что смешного? За тем статическая типизация и нужна - чтобы можно было _доказать_ корректность программы.

Вы что, серьёзно не в курсе для чего пишут тесты? Хватить тролить то уже.

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

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

> Ну, REPL, ну и что? Само наличие eval, по твоему, даст прохождение по всем условиям и значениям входных переменных само собой?

Не понял, о чем ты? Какое прохождение?

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

> Не понял, о чем ты? Какое прохождение?

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

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

и к чему ты это говоришь?

К тому, что сам по себе REPL не обеспечит тебе прогон всех условий, и, следовательно, не обеспечит 100% гарантии выполнения твоего (достаточно объёмного) кода у клиента.

Или мы вообще о чём говорим-то???

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

> статическая типизация и нужна - чтобы можно было _доказать_

корректность программы.


Ну и как, что-нибудь уже доказали?

В динамических ЯП тесты пишутся для того, чтобы доказать, что нигде

не вызывается несуществующая функция



Вы просто некомпетентны, угу. И ваши домыслы про доказательство только тому подтверждение.

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

> Я таки понял, что статически компилируемые языки гарантируют на 100%?

Таки не 100%, но поболе, чем языки с динамической типизацией, да ещё и интерпретируемые. Точное соотношение, разумеется, не скажу, ибо.

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

Ну и как, что-нибудь уже доказали?

Простейший пример из этих ваших JavaScript:

2 + «3» == 5 , но «2» + 3 == «23» . А в языках со статической типизацией «программист», наваявший это, получил бы по рукам от конпелятора. А не от пользователя.

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

Конечно РЕПЛ никак не автоматизирует прогон условий. Он всего лишь значительно облегчает тестирование различных участков кода, особенно тех, в поведении которых ты не уверен. Если тебе западло тестировать, то толку от РЕПЛа один фиг ноль; драть и убивать.

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

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

> мифических вызовах несуществующих функций

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

или сегфолтов


А это здесь при чём?

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

>А по существу возражения будут?

ССЗБ, сам каку написал - сам и расхлебывай. Думаешь, я не смогу тебе на всем таком статически типизированном С++ накатать пример с приведением типов и идиотским переопределением стандартных операторов, «демонстрирующий» дерьмовость плюсов?

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

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

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

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

А это здесь при чём?

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

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

> Думаешь, я не смогу тебе на всем таком статически типизированном С++ накатать пример с приведением типов и идиотским переопределением стандартных операторов, «демонстрирующий» дерьмовость плюсов?

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

Повторяю, эти ошибки - капля в море.Чем кривее руки разработчика и чем меньше он уделяет внимания проверке написанного им кода, тем больше капля.


Угу, а теперь сравни количество «программистов», которые знают рабочий язык достаточно плохо, чтобы писать подобные «шедевры», и серьёзных профи. По результатам сравнения выяснится, что капель этих накапало уже чуть ли не больше изначального моря.

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

>Так в этом случае ты сам будешь яму рыть, а в приведённом примере яма заботливо вырыта недостаточно строгой типизацией JavaScript-а.

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

И я не говорил, есичо, что система типизации плюсов — верх совершенства.

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

Угу, а теперь сравни количество «программистов», которые знают рабочий язык достаточно плохо, чтобы писать подобные «шедевры», и серьёзных профи. По результатам сравнения выяснится, что капель этих накапало уже чуть ли не больше изначального моря.

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

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

> Жабоскрипт заботливо предоставляет тебе спорную, но удобную штуку

И достаточно неочевидную, чтобы в неё вляпаться от души.

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


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

Ты же не предлагаешь сделать язык для кретинов и заставить пользоваться им всех?


Они уже есть. Называются — естественные языки. И именно из-за кучи неочевидностей, умолчаний и прочей радости естественные языки так трудно формализуются для машинной обработки. А когда я включаю режим GrammarNazi в реальной жизни, на меня сердятся, отстаивая своё «право» использовать язык с жуткими ошибками.

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

> а с «программистам» пусть работодатели разбираются

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

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

> Ну и как, что-нибудь уже доказали?

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

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

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

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

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

>И достаточно неочевидную, чтобы в неё вляпаться от души.

Вот так, дорогой мой засраный дружок, однажды маленький мальчик пионерского возраста, отличник в школе, примерный сын родителей, гулял по улице. И вот неожиданно, малыш, он увидел на тратуаре огромную кучу говна! «Наступлю или не наступлю?» думал мальчик, и действительно не наступил, а просто ёбнулся в неё мордой, подскользнувшись на чьей то кожуре от банана! А мораль здесь в сказке такова: Не надо мусорить!

(c) КП. Вот и ты, смотришь на типизацию, тогда как к проблемам приводит не она.

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

Ну что там предупреждать? Напреобразовывал ты типы (статически) (а в плюсах еще и неявно, что опять же палка о двух концах), и как системе типизации узнать, что ты хотел получить А, а не Б? Взялся за гуж, не говори, что не дюж.

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

Проблемы индейцев шерифа не... Ну ты понял.

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

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

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

> Вот и ты, смотришь на типизацию, тогда как к проблемам приводит не она.

Смотрю я на отсутствие типизации, и говорю, что без неё проблем будет больше, чем с ней. Сколько раз ещё это повторить надо?

и как системе типизации узнать, что ты хотел получить А, а не Б?


Если я А пытаюсь использовать как Б — вот это систему типизации должно сильно расстроить.

Проблемы индейцев шерифа не... Ну ты понял.


А потом шерифы плачут, что вот, де, %PROGRAMNAME% загубило, сцуко такое, мой месячный отчёт, который сдавать надо уже вчера (ну, или болванку с онеме каким-нить), рухнув посреди работы, и шерифу теперь предстоят крупные, или не очень, денежные траты.

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

> Напреобразовывал ты типы (статически) (а в плюсах еще и неявно

Нормальная статическая типизация бывает только строгой. Так тчо никаких преобразований типА, тем более неявных.

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

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

А кто говорил про _любые_ ошибки? Но, например, агда.

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

>Смотрю я на отсутствие типизации, и говорю, что без неё проблем будет больше, чем с ней. Сколько раз ещё это повторить надо?

Возможности шире - проблем больше. Не нравится - не ешь.

Если я А пытаюсь использовать как Б — вот это систему типизации должно сильно расстроить.

Если у А и Б похожие интерфейсы, это проворит не только система типизации, но и ты. Скомпилируешь и даже запустишь.

А потом шерифы плачут

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

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

>Так в этом случае ты сам будешь яму рыть, а в приведённом примере яма заботливо вырыта недостаточно строгой типизацией JavaScript-а. И я не говорил, есичо, что система типизации плюсов — верх совершенства.

Не сам. В случае С++ ты уже начинаешь в яме, а можешь только рыть другие.

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

> Смотрю я на отсутствие типизации, и говорю, что без неё проблем

будет больше, чем с ней.


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

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

> Возможности шире - проблем больше

Какие проблемы?

Если у А и Б похожие интерфейсы, это проворит не только система типизации, но и ты. Скомпилируешь и даже запустишь.


У целочисленных типов и у строк есть оператор '+'. В примере про JavaScript я показал, что неочевидные преобразования типов проводятся аж бегом. И в большой программе придётся посидеть не один час, пока случится увидеть, а где же это так конпелятор «помог», подумал за меня? В то время как статическая типизация явно спросит «а какого хрена ты творишь-то?».

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

> Своему опыту я доверяю больше, чем вашим домыслам

Каким таким «моим домыслам»? Список «домыслов» в студию.

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