![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Сейчас я опишу одну из главных причин по которым я недолюблюваю Ъ ф.п, и люблю CL.
Понимаете, рассуждая о развитии IT-индустрии, можно провести аналогию с классической промышленностью.
В истории классической промышленности были периоды когда всё делали единично и ручками. Я мог бы сравнить такие периоды с ранним развитием IT. Со временами расцвета UNIX или DOS. С языками вроде Си.
Потом были периоды рабовладельческого строя и раннего капитализма, когда любую задачу закидывали необходимым количеством человеков. Я бы сказал, что сейчас в IT-индустрии как раз такой подобный период, со всеми этими Java и PHP.
Но в итоге, во всех развитых странах промышленность пришла к автоматизации. И производит продукты лучше, быстрее и качественнее, чем когда-либо.
И IT-индустрию ждет когда-нибудь то же самое, то есть массовая автоматизация, программы которые пишут программы(понимаете, к чему я клоню, да?), и это неминуемо.
Я смотрю на языки функционального программирования, вроде хаскеля, как на, ну не знаю, алмазные лопаты. Выглядят красиво, конечно, прочностью обладают неслабой, но что они могут сделать против таких детищ автоматизированной промышленности, как отбойные молотки и экскаваторы?
Я не вижу, как ф.п. может помочь с если уж не уменьшением, то хотя бы со сдерживанием растущей сложности софта. Я вижу ф.п. как модный фетиш, и ничего более, и поэтому время от времени на него наезжаю, т.к. бессмысленные фетиши меня раздражают, т.к. бессмысленные фетиши это может быть круто в дизайне шмоток, например, но не в инженерии.
Кстати, скоро напишу на хабр статью о макросах и метапрограммировании в лиспе, как только продумаю её.
Понимаете, рассуждая о развитии IT-индустрии, можно провести аналогию с классической промышленностью.
В истории классической промышленности были периоды когда всё делали единично и ручками. Я мог бы сравнить такие периоды с ранним развитием IT. Со временами расцвета UNIX или DOS. С языками вроде Си.
Потом были периоды рабовладельческого строя и раннего капитализма, когда любую задачу закидывали необходимым количеством человеков. Я бы сказал, что сейчас в IT-индустрии как раз такой подобный период, со всеми этими Java и PHP.
Но в итоге, во всех развитых странах промышленность пришла к автоматизации. И производит продукты лучше, быстрее и качественнее, чем когда-либо.
И IT-индустрию ждет когда-нибудь то же самое, то есть массовая автоматизация, программы которые пишут программы(понимаете, к чему я клоню, да?), и это неминуемо.
Я смотрю на языки функционального программирования, вроде хаскеля, как на, ну не знаю, алмазные лопаты. Выглядят красиво, конечно, прочностью обладают неслабой, но что они могут сделать против таких детищ автоматизированной промышленности, как отбойные молотки и экскаваторы?
Я не вижу, как ф.п. может помочь с если уж не уменьшением, то хотя бы со сдерживанием растущей сложности софта. Я вижу ф.п. как модный фетиш, и ничего более, и поэтому время от времени на него наезжаю, т.к. бессмысленные фетиши меня раздражают, т.к. бессмысленные фетиши это может быть круто в дизайне шмоток, например, но не в инженерии.
Кстати, скоро напишу на хабр статью о макросах и метапрограммировании в лиспе, как только продумаю её.
no subject
Date: 2011-11-02 10:20 am (UTC)У вас наверняка есть ссылки на исследования. Не поделитесь?
no subject
Date: 2011-11-02 10:33 am (UTC)Вместо выдумывания типов и натягивания их на требуемую область, мы непосредственно ограничиваем структуру мини-DSL подзадачи так, как нам того хочется.
no subject
Date: 2011-11-02 10:36 am (UTC)Как вы без типов обеспечите правильность взаимодействия двух подсистем?
no subject
Date: 2011-11-02 11:06 am (UTC)Семантическое, если говорить о верификации типами(потому что полностью верифицирующие системы типов не являются тьюринг полными, в отличие от лиспа, где у нас макросы это просто обычные функции лиспа).
Прагматическое, потому что специализированные макросы строить банально удобнее натягивания теории категорий на подзадачу.
И синтаксическое, да.
>Как вы без типов обеспечите правильность взаимодействия двух подсистем?
Очевидно, проверками в точках соединения этих подсистем.
no subject
Date: 2011-11-02 11:27 am (UTC)Что означает, что любое действие внутри Лиспа не может быть верифицировано. То есть, семантика не проверяется логически непротиворечиво.
В отличии от конструктивной теории, например, теории типов Мартина-Лёфа.
>Прагматическое, потому что специализированные макросы строить банально удобнее натягивания теории категорий на подзадачу.
О. Опять попытка принизить достоинства аргументов визави?
>И синтаксическое, да.
Двухуровневые грамматики Тьюринг-полны, если что.
>>Как вы без типов обеспечите правильность взаимодействия двух подсистем?
>Очевидно, проверками в точках соединения этих подсистем.
Неужто проверками во время выполнения программы?
И, кстати, что там про критерий применимости Лиспа? Я ещё парочку раз повторю этот вопрос, ибо мне интересно либо пробудить критическое мышление, либо получить доказательство религиозного отношения.
no subject
Date: 2011-11-02 11:42 am (UTC)Нет, просто я хочу сказать, что обобщенные системы для частных случаев использовать сложнее и неудобнее, чем системы, созданные специально для этих частных случаев. Например, перл хорош в обработке строк и для небольших скриптов, он специально для этого и создавался. Языки типа CL или Хаскеля для этого подходят хуже.
Неужто проверками во время выполнения программы?
Во время компиляции DSL.
>И, кстати, что там про критерий применимости Лиспа?
Я уже как-то писал развернутое мнение по этому вопросу, не помню только где.
CL отлично(идеально) подоходит для создания больших и сложных систем. Лушче всех других языков общего назначения.
Собственно, постинг как раз об этом - сложность программных систем в будущем будет только расти, и CL или, подобные ему языки, будут восприниматься индустрией все больше и больше.
Я думаю, CL довольно плохо подходит для одноразовых мелких задач(для скриптования), и для, естественно, низкоуровневого программирования, так как базовый рантайм CL, абстрактная виртуальная коммонлисп-машина, довольно жирный и высокоуровневый.
no subject
Date: 2011-11-02 11:46 am (UTC)Обобщенные и, в то же время, негибкие(статичные) системы.
Кстати, еще вот пример - WPF. Да, большое, может много, и все такое. Но, иногда GUI удобнее писать на WinForms а то и вовсе на каком-нибудь WTL.
Тут можно наверное спросить - получается что CL, как самая обобщенная система, для всего подходит одинаково плохо? Нет, как раз в этом и фишка. И CL и самого лиспа вообще. В нем ничего нет, но, в то же время, можно создать что угодно, под какой угодно частный случай.
no subject
Date: 2011-11-02 12:11 pm (UTC)>Во время компиляции DSL.
У вас два DSeL. Как они стыкуются?
>Я уже как-то писал развернутое мнение по этому вопросу, не помню только где.
>CL отлично(идеально) подоходит для создания больших и сложных систем. Лушче всех других языков общего назначения.
За исключением, как я полагаю, тех, что подходят лучше.
>Собственно, постинг как раз об этом - сложность программных систем в будущем будет только расти, и CL или, подобные ему языки, будут восприниматься индустрией все больше и больше.
Вы наверное слышали о необходимости вносить изменения в программу в связи с изменениями в техзадании? Это основная проблема современного ПО - как поменять так, чтобы упало минимальное число возможностей.
Статическая проверка типов подходит для этой задачи. Типы представляют собой контракты, изменение которых определяется практически сразу. С этой точки зрения типы можно рассматривать, как систему контроля требований.
Системы контроля требований, кстати, весьма живая область, не только в индустрии ПО.
Как контролировать распространение изменений в Лиспе? Если это невозможно, то он не подходит для больших систем со множеством взаимосвязанных требований.
>Я думаю, CL довольно плохо подходит для одноразовых мелких задач(для скриптования), и для, естественно, низкоуровневого программирования, так как базовый рантайм CL, абстрактная виртуальная коммонлисп-машина, довольно жирный и высокоуровневый.
Большое спасибо.
no subject
Date: 2011-11-02 12:30 pm (UTC)Как стек. Один на другом. Нижний о верхнем ничего не знает.
>За исключением, как я полагаю, тех, что подходят лучше.
Такой язык должен иметь высокоразвитые средства метапрограммирования, и в первую очередь, у такого языка сама структура программы должна быть объектом языка, причем представляться она должна в самой общей форме, потому как какая-либо специализация внесет ограниченность в возможности метапрограммирования. Таким образом, этот язык должен быть лиспом. Возможно, в будущем появятся лиспы лучше CL, пока же таких нет.
>Как контролировать распространение изменений в Лиспе?
Самый лучший вариант это многоуровневые макросы и DSL, естественно.
Задача должна быть описана на самом верхнем уровне, самым высокоуровневым DSL, непосредственно описывающим саму задачу в ее терминах. Этот DSL должен компилироваться в нижележащий DSL, работающий, например, с абстракциями доступных программных средств, и так далее. И вот когда мы изменяем спецификацию задачи, на верхнем уровне, изменения автоматически распространяются на нижележащие слои, без непосредственной работы с ними. Верификация происходит на всех уровнях слоях DSL, естественно. Если DSL не принимает какую-либо "форму", он кричит нам об ошибке, при компиляции.
Это не может полностью защитить от ошибок в логике, но в отличие от типизации, это уменьшит шанс возникновения логических ошибок, за счет сужения сущностей, с которыми мы работаем, за счет максимальной специализации кода под задачу.
no subject
Date: 2011-11-02 01:00 pm (UTC)>Как стек. Один на другом. Нижний о верхнем ничего не знает.
О!
А параллельной композиции быть не может? Типа, "вот здесь играем, а здесь рыбу заворачиваем". Клиент-сервер, такого рода. Нельзя такого сделать?
>Задача должна быть описана на самом верхнем уровне, самым высокоуровневым DSL, непосредственно описывающим саму задачу в ее терминах. Этот DSL должен компилироваться в нижележащий DSL, работающий, например, с абстракциями доступных программных средств, и так далее. И вот когда мы изменяем спецификацию задачи, на верхнем уровне, изменения автоматически распространяются на нижележащие слои, без непосредственной работы с ними. Верификация происходит на всех уровнях слоях DSL, естественно. Если DSL не принимает какую-либо "форму", он кричит нам об ошибке, при компиляции.
Ну, представьте себе, что у вас изменилась спецификация входов и выходов одной из компонент, но общая структура (спецификация верхнего уровня, просто налаживающая отношения между компонентами) осталась прежней. Кто и где у вас будет ругаться?
>Это не может полностью защитить от ошибок в логике, но в отличие от типизации, это уменьшит шанс возникновения логических ошибок, за счет сужения сущностей, с которыми мы работаем, за счет максимальной специализации кода под задачу.
А.
С GADT (generalized algebraic data types) вы знакомы? Как с их помощью построить типобезопасный интерпретатор знаете?
Доступно ли у вас аналог type erasure? Гарантирован ли он? Можете ли вы привести пример гарантии непустого списка на входе в функцию head?
no subject
Date: 2011-11-03 02:01 am (UTC)Что значит "типобезопасный"? Как эта "типобезопасность" сможет гарантировать, что интерпретатор работает корректно и без ошибок (ведь в итоге нам нужно именно это, все остальное - лишь средства достижения указанной цели)? Нельзя ли достигнуть такого же результата без этой вашей "типобезопасности"?
> Можете ли вы привести пример гарантии непустого списка на входе в функцию head?
Неразрешимость подобной задачи вас, конечно же, не волнует? Или вас устроит чекер, который может отвергать корректные варианты использования?
no subject
Date: 2011-11-02 12:34 pm (UTC)Во-первых, за счет синтаксиса можно получить любые ограничения, которые можно получить за счет системы типов (другое дело, что писать на таком DSL никто не сможет). Кстати, за примером того, как семантические ограничения переносятся на синтаксические далеко ходить не надо - haskell. В haskell система типов не позволяет контролировать сайд-эффекты, по-этому мы можем при помощи unsafePerformIO написать корректно типизированную программу, которая не будет работать правильно. Но если этот unsafePerformIO применяется исключительно внутри bind монады IO, то корректная работа гарантируется - гарантируется синтаксисом аппликации bind'a (ну или синтаксисом do-нотации). Во-вторых - главная фича макросов лиспа в том, что они расширяют не только синтаксис, но и семантику языка. По-этому даже с реализацией нетривиальных ограничений проблем нет. Другое дело, что проще, все же, работать с синтаксисом - как видно из того же примера с do-нотацией, даже за счет не слишком сложного синтаксиса можно гарантировать выполнение весьма интересных и полезных на практике свойств.