Будущее программирования

31 Дек
2011

[Автор оригинального текста — Paul Chiusano, программист, работает в Capital IQ, пишет преимущественно на Scala. Один из разработчиков библиотеки scalaz — прим. пер.] Как будет выглядеть программирование через 10-20 лет? В канун нового года самое время пофилософствовать о будущем нашей индустрии. Мы находимся на пороге значительных изменений в деле написания программ, по сравнению с которыми нынешние, 2011 года, техники и идеи будут выглядеть примитивными. Изменения будут происходить в нескольких важных областях: инструментария и инфраструктуры, языков и систем типов, систем времени исполнения. Прежде чем я начну, позвольте мне предупредить вас, что ниженаписанное стоит принимать с долей скептицизма: у меня нет хрустального шара для настоящих предсказаний. Существует множество причин, по которым несовершенные технологии могут доминировать в индустрии гораздо дольше, чем они того заслуживают. Я не буду особо распространяться на эту тему, хоть тема и определенно интересна. Вместо этого я хочу передать вам свое видение программирования будущего. Если бы не было накапливающихся сетевых эффектов, тянущихся за посредственными технологиями, используемыми сейчас, если программирование было бы изобретено заново, с чистого листа—каким бы я хотел его видеть? Образующая идея этих изменений—избавление от случайной [инцидентной] структуры и от её сестры-близнеца, случайной сложности. Проявляющие себя во множестве форм, эти факторы составляют главное препятствие на пути конструирования более сложных программ; большинство основных изменений имеют своей целью развеять это препятствие. Новый мир программирования будет выглядеть по-другому: на порядки увеличатся повторное использование кода, легкость развертывания решений, эффективность приложений, произойдет множество других интересных штук.

Откуда начнем?

Первым существенным изменением будет уход от представления программ в виде текста, разделенного на файлы. Можно вас простить, если вы думаете, что это несущественная деталь. Кому какое дело, как программы представлены и в виде чего хранятся, так? Оказывается, этот крупный источник случайной сложности приводит к хлещущим через край последствиям вдоль всей цепи средств разработки, от захламления процессов мышления программиста, до сред разработки (мы обсудим их дальше) и систем сборки и развертывания. Как и в случае со многими другими вещами, здесь обсуждаемыми, размах, с которым здесь благодаря случайной сложности теряется продуктивность, остается за пределами радаров большинства программистов. Они невольно принимают эту потерю продуктивности как должное, вплоть до того, что находят «разумные» причины в оправдание своей зависимости от файлов и текста в программировании. «А как насчет интенционального программирования?», можете вы спросить. Или сред разработки в духе тех, что у Smalltalk’а? Идея ухода от программ как текста, размазанного по файлам, не нова, но дьявол, как всегда, в деталях. Предыдущие попытки вырваться из лап этой случайной сложности закончились неудачно, в частности потому, что пытались заменить одну произвольную структуру другой. Например, интенциональное программирование отстаивало (хорошую, в общем-то) идею разделения представления кода и формата хранения кода, подсовывая формат (вроде XML) лишь с чуть меньшей случайной структурой. Преимущества, полученные от нового формата и структуры не были использованы образом, приводящим к заметной выгоде; при этом присутствовали вполне ощутимые затраты от потери сетевых эффектов, возникшие из-за того, что старые текстово-ориентированные утилиты были больше неприменимы. То же верно и для сред разработки Smalltalk’а. Также (что в некотором смысле иронично по отношению к Smalltalk, объектно-ориентированному языку) в основные предпосылки включен один из наиболее произвольных выборов из возможных, вечный генератор случайной сложности—решение о том, какой класс должен реализовывать конкретный метод. Любая новая технология столкнется здесь с настоящим барьером. Она должна быть не просто лучше, чем замшелый status quo, она должна быть существенно лучше для того, чтобы преодолеть стоимость сетевых эффектов и перевесить за счет преимуществ затраты на переход с тех средств, которыми уже обладают существующие технологии. По моему мнению, ни одна из предложенных альтернатив тексту-в-файлах пока не приблизилась к взятию этого барьера. Но нет никаких фундаментальных законов, которые бы запрещали это. Не стоит, исходя из того, что прошлые попытки провалились, заключать, что идея неосуществима. Просто попытки были недостаточно хороши. Первая крупная подвижка в осуществлении этой идеи: откажитесь от хранения программ в виде текста вовсе, даже от хранения в виде частично структурированного текстового формата вроде XML, тем более от бинарного частично структурированного формата, его все равно не избавить от присуствия случайной структуры. Избавьтесь также и от файлов. Храните вместо этого кодовую базу реляционно, как базу данных, с использованием инструмента вроде datalog для обновления и запросов. Этот язык обновлений и запросов должен быть тщательно продуман таким образом, чтобы широкомасштабные операции рефакторинга, в текущий момент сложно осуществимые или невозможные, были полностью (или частично, с помощью нескольких операций по трансформации кода в кодовой базе) автоматизируемы. В качестве простого примера избавимся от понятия о том, где функция или тип данных «расположены». Взамен каждая функция получает уникальный идентификатор (возможно, с помощью контентной адресации, дающей простую и автоматизированную форму дедупликации кода), и отдельная таблица имен отображает эти идентификаторы в имена для нужд представления кода в некотором интересном человеку виде (вообще-то, ничто не мешает иметь несколько таких таблиц, так что разные программисты могут использовать разные имена и представления для одних и тех же действий). Это тривиальным образом разрешает производить рефакторинг «переименование» простым обновлением содержимого табличной ячейки. Еще несколько мыслей о том, как это может работать. Во-первых, я не защищаю синтаксисdatalog, это меня не волнует. Ключевая возможность, которую дает datalog в дополнение к реляционной алгебре—возможность выражать транзитивное замыкание и взаимную рекурсию гарантированно завершимым образом. Эти черты дают возможность выразить многие обычные задачи в терминах трансформаций и запросов к кодовой базе. Например, вот гипотетический запрос для нахождения всех ссылок на данный идентификатор функции,
fid
. Не волнуйтесь, если синтаксис выглядит пугающе или бессмысленно. Ключевой момент в том, что это запрос всего лишь из нескольких строк кода, и он может быть использован заново, в том числе как строительный кирпичик для других запросов.
-- propagate reference to containing apply

refs(Id) :- apps(Id, fid, _). 

refs(Id) :- apps(Id, _, fid).

refs(Id) :- refs(X), apps(Id,X,_).

refs(Id) :- refs(X), apps(Id,_,X).

return(Id) :- lambdas(Id), refs(Id).

return(Id) :- labdaBodies(Id, fid).
Нынешние интегрированные среды разработки, со всей поддержкой их со стороны громадных команд разработчиков и уймой кода специального назначения, позволяют весьма ограниченное подмножество операций по преобразованию и извлечению кода, все это работает медленно, плохо и с большими затратами ресурсов. Как следствие, существует целая субкультура программистов (включающая меня), отвергающих IDE в пользу минималистских, не обладающих таким набором возможностей, но более надежных текстовых редакторов. Имеющиеся в современных самых совершенных IDE операции рефакторинга будут лишь началом возможностей будущих сред разработки. Широкомасштабный рефакторинг—неизбежное следствие достижения той степени повторного использования кода, которая нужна для построения программ значительной сложности, не умирающих от [термодинамической] тепловой смерти. Время, затраченное на рефакторинг в этой новой модели занимает часы, а не недели и месяцы, и написание кода для трансформаций кодовой базы будет отдельным, но незаменимым умением, не переплетенным с обычным процессом программирования. Так что программисты не задумывают вначале рефакторинг (обычно достаточно простой, чтобы объяснить его другим программистам), а потом начинают утомительный и полный ошибок процесс порчи текста руками, призванный реализовать рефакторинг. Вместо этого программист задумывает рефакторинг, затем придумывает программу для преобразования кода, имлементирующую рефакторинг, и применяет это преобразование к кодовой базе, весь процесс занимает несколько часов. Концепция кода как базы данных имеет своим следствием обширнейшие упрощения и в других инструментах, в частности, для контроля версий. Проблема обработки слияний упорядоченных последовательностей символов, распределенных по файлам и директориям с произвольной структурой чрезвычайно сложна, соответственно, ПО для контроля версий содержит существенные объемы сложности. Эти трудности привели многих к неполноценным VCS моделям (Git, Mercurial), где наборы изменений выстроены в линейный порядок и индивидуальные выборки [cherrypicking] просто не работают. В будущем, с кодовыми базами, мы увидим возрождение теории патчей Darcs, только в этот раз она будет работать так, как надо и будет реализовываться легко. В связи с этим понятием кодовых баз мы получаем более тонкий и точный контроль зависимостей. Управление зависимостями—другая серьезная проблема разработки ПО, огромное препятствие для повторного использования кода, и, опять же, это обычно проходит мимо программистских радаров. Библиотека часто предоставляет какой-то новый интерфейс или абстракцию и дает несколько конкретизированных применений этой абстракции. Библиотека теперь зависит от того, доступны ли эти конкретные типы данных для компиляции. Использование этой библиотеки теперь означает включение всех её зависимостей, даже если вам нужен только один конкретный случай. Дополнительные траты от этого, объединенные с имеющейся сложностью сборок (опять же частично вызванной рассмотрением программ как текста) приводят к тому, что код используется повторно гораздо реже, чем это было бы возможно при другом раскладе. В будущем мы будем в состоянии специфицировать код в зависимости от условий, не полагаясь на ad hoc технологии из 70-х вроде C-препроцессора. Язык запросов и обновлений вроде datalog хорошо здесь себя проявляет, и позволяет выражать вещи вроде таких: если конкретный тип X имеется в кодовой базе, определить некоторый набор функций и новых типов данных. Также, зависимости не будут присущи «библиотеке» или «модулю». Функция будет зависеть только от набора функций и типов, которые она использует, и кодовая база будет довольно гибкой штукой. Представьте: мы можем извлечь любой соединенный набор из функций и типов данных из кодовой базы, и это не требующее усилий автоматическое преобразование, поддерживаемое языков запросов. Здесь есть несколько неясных моментов вокруг версионирования (разрешимых, впрочем), все они связаны с тем, как нам переопределить контроль версий так, чтобы задать частичный порядок над наборами изменений без ненужных зависимостей от представления программ как упорядоченных последовательностей символов.

Редактирование кода, среды разработки и системы типов

Редактирование кода будет производиться в структурных редакторах, которые будут совсем не похожи на современные IDE (те представляют из себя приукрашенные текстовые редакторы, ничего больше. Кстати, посредственные текстовые редакторы, если соскрести позолоту). В структурном редакторе программист будет создавать выражения, которые содержат незаполненные дырки. Важно, что эти структурные редакторы будут управляться типами, так что для каждой дырки программисту будет предложено множество значений, подходящее под ожидаемый тип, упорядоченное поудобнее. Редактор будет производить локальный поиск по программе для автодополнения сложносоставных выражений. Если вы когда-либо видели живую сессию программирования на Agda, вы знаете насколько мощной и продуктивной может быть эта идея. Да, текущий интерфейс написания программ на Agda родом из 70-х (самодельный мод для Emacs), но мощь идеи управляемых типами редакторов видна. Ясно видно, что типы эффективны не только для предотвращения ошибок, но и для руководства и направления разработки. Это мощный усилитель наших маленьких программистских мозгов. Сообразно этому, восход управляемой типами разработками в языках с настоящими, state of the art системами типов обозначит закат эпохи динамически типизированных языков (они же языки-с-одним-типом). Динамическая типизация будет считаться забавным, причудливым эволюционным тупиком в истории программирования. Эта точка зрения уже сейчас принята в некоторых программистских кругах, где принято считать, что большая часть защитников динамической типизации просто не знакома с управляемой типами разработкой в языке с настоящей системой типов и не знает, где находится передний край систем типов и теории языков программирования. В процессе дальнейшего развития области систем типов мы увидим, как последние преимущества динамических проверок тают в воздухе. Связанное с этим изменение состоит в том, что типы станут еще более необходимы и системы типов обзаведутся новыми возможностями, чтобы лучше справляться с приданием данным структуры, отсутствие которой есть главный источник случайной структуры и сложности. Большая проблема больших кодовых баз—нормализация данных. Недостаток структурности в представлении данных ответственен за значительные количества склеивающего кода, соединяющего два куска кода таким образом, чтобы они могли общаться друг с другом. Большинство меинстримного программистского мира не осведомлено об этой проблеме, потому что повторное использование кода в большинстве императивных кодовых баз сильно ограничено (побочные эффекты сдерживают композицию). В мире функционального программирования невообразимое количество кода используется повторно, хотя вместе с ним существует приличное количество кода, служащего для склейки. В качестве небольшого примера рассмотрим функцию
f
типа
X -> Y -> Int
, и значение
xs
типа
[(Y, X)]
и предположим, что мы хотим применить
f
к списку
xs
. Опытный функциональный программист напишет
map (uncurry f . swap) xs
за три секунды, не задумавшись дважды. Но этот код почти полностью состоит из боилерплейта, его цель—убедить компилятор, что мы действительно хотим это сделать; это шум. Мы получаем повторно используемый код (императивный программист все еще писал бы for в миллионный раз вместо использования функций высшего порядка), это так, но можно прийти к цели более чистой дорогой. Если этот код должен существовать (а я в этом не уверен: пояснения ниже), я бы предпочел, добравшись до этого места в процессе написания, сказать моему редактору
map f over xs
. Редактор найдет в программе необходимое для того, чтобы совместить типы, покажет мне программу для подтверждения если я это запрошу, и затем непокажет это подвыражение в главном окне редактора, возможно, просто показав вместо этого
map f* xs
, где
*
может быть развернута в полный текст. Что даже лучше, мы, вероятно, сможем сделать то же с меньшим количеством кода для склейки. Такой код может быть удален двумя путями: первый способ, который я уже описал, в том, чтобы генерировать его автоматически, не показывая его до явного запроса. Второй способ—иметь типы(и системы типов), выражающие больше структуры, так что нет случайной структуры, нуждающейся в стыковке. В качестве средств, делающих это возможным, мы увидим полиморфизм на строчных переменных, неупорядоченные типы и тому подобные вещи, а также различные механизмы систем типов, делающие эти средства удобными в использовании. Особенно интересной представляется мне явное разделение модели, лежащей в основе типа (она может быть упорядоченной, без случайной структуры) и представлений этого типа, которые могут содержать некоторую дополнительную структуру. Функции будут работать с моделью, задавая преобразования, из которых потом может быть восстановлено любое количество представлений. Компилятор и среда времени исполнения умны достаточно для выбора представлений времени исполнения, которые позволят сократить количество ненужных преобразований между представлениями.

Среды времени исполнения

Языки с нестрогой семантикой будут доминировать в новом мире благодаря увеличению повторно используемого кода и модульности, которая характерна для «нестрогости по умолчанию». Как я уже говорил в предыдущем посте, опциональная ленивость не справляется. Как и в случае с другими упомянутыми проблемами, проблемы со строгостью по умолчанию неочевидны для большинства программистов, включая тех, кто считает себя знакомым с областью функционального программирования. Проблемы, которые привносит строгость, становятся хорошо заметны только после существенного углубления в функциональный стиль разработки, в частности, после ознакомления с идеей библиотек комбинаторов и абстракций, необходимых для уничтожения дупликации кода [DRY] в этих библиотеках. Эти проблемы стали источником затруднений в библиотеке Scalaz, которая поддерживает функциональный стиль в Scala, строгом по умолчанию языке, также эти проблемы заметны в нашей рабочей кодовой базе на Scala. Единственная существенная проблема с ленивостью—необходимость понимать, как используются память и стэк. Эта проблема пользуется популярностью среди людей, которые предпочитают находить своему нежеланию учить Haskell и ФП рациональные объяснения, но исследования и более умные стратегии вычисления в состоянии с ней справиться. Опять же, нет законов природы, утверждающих, что мы должны уступить и искать утешения в строгом порядке вычислений. Привычная нормальная стратегия вычислений гарантированно завершима, если нормальная форма существует, но понимание того, как при этом используется память может быть проблематичным. Можно сделать лучше. Помимо статического анализа строгости, который покрывает только часть желаемых случаев, мы можем обратиться к дополнительным стратегиям вычисления, которые завершаются для тех же программ, что и нормальная стратегия и при этом могут обеспечивать дополнительную информацию о строгости. Из таких стратегий мне особенно интересна специализирующая стратегия с распространением строгости. Я опишу её подробнее отдельным постом, если вкратце, то в этой модели вычислений вызов функции подобен двум сообщающимся корутинам. При вызове функции вызываемая сторона начинает вычислять её тело, передавая контроль назад вызывающей стороне как только возникла необходимость в первом аргументе, и также отмечая, должен ли аргумент быть передан строго, опираясь на информацию, доступную во время исполнения. Последующие аргументы обрабатываются так же. В результате функции специализируются автоматически, по мере передачи аргументов, и мы не создаем отложенные вычисления, если они будут в строгом виде использованы вызывающей стороной. Это может быть эффективно реализовано с использованием двух стэков, возможны некоторые дополнительные оптимизации. Назначение такой стратегии—дополнить, а не заменить существующий статический анализатор строгости и передачи аргументов. В общем, целью новых стратегий вычисления должна быть не столько эффективность (хоть это и хорошая цель), сколько более простая модель использования памяти и стэка, так что эти вещи оказываются независящими от случайных деталей вроде того, как функция собрана или что компилятор решил заинлайнить (необходимость понимать эти вещи в Haskell ломает черную коробку абстракции функций, от которой зависит ФП и функции высшего порядка). Среды времени исполнения и виртуальные машины будут все шире поддерживать подобные новые стратегии вычислений, и текущий выводок виртуальных машин «общего назначения», который ощутимо специализирован под строгие императивные языки, скорее всего отойдет на второй план.

Распространение кода и будущее web.

А что же с web, javascript, html 5 и остальным? Будем ли мы и дальше идти, прихрамывая, вместе с этими технологиями? Не думаю, что сильно удивлю кого-то, сказав, что написание приложений значительной сложности для web требует гораздо большей работы, чем требовалось бы при наличии действительно богатого клиентского языка. Снова, я не думаю, что многие web-программисты осознают, насколько сейчас всё плохо. По сравнению с меинстримными языками, такими как Java, C# или Python язык Javascript не так и плох; в некоторых отношениях он даже лучше. Но Javascript не выдерживает сравнения с языками, имеющими хорошую систему типов и настоящую поддержку ФП, вроде Haskell, Scala и тех языков будущего, которые придут им на смену. Конечно, сторонники существующих web-технологий всегда найдут разумное объяснение существующему положению, указывая на то, как вещи улучшились по сравнению с тем, как оно было раньше. Это, возможно, верно. Но зачем останавливаться? Предвижу будущее, в котором Javascript постепенно отходит на второй план, как уходят и специализированные плагины для браузеров вроде Flash, уступая место коду, написанному на произвольных, компилируемых языках, использующих для работы что-нибудь вроде NaCl. Это будет совмещено с кешированием подписанного кода и механизма отслеживания зависимостей, так что, например, станет возможным предоставить приложение, которое подгружает виртуальную машину Java и другие зависимости, если они еще не закешированы на вашем компьютере и подписи совпадают. Это изменяет способ мышления о программном обеспечении. ПО не всегда будет чем-то из категории «скачай это себе на компьютер и запусти». Напротив, ПО существует «само по себе», а вы его запускаете. Как деталь реализации процесса запуска вы можете позволить подгрузить дополнительный код, который нужен ему для работы. Так закончится монополия HTML и Javascript на клиентской стороне, и большая часть затрат на переход к новым клиентским технологиям будет снята. Горстки низкоуровневых протоколов и стандартов будет достаточно, чтобы связать все вместе и поддерживать те хорошие вещи, которые существуют в web сегодня (позже я скажу об этом больше), но не будет необходимости ни в чем настолько высокоуровневом, как задание конкретного языка с клиентской стороны для взаимодействия (будь то Javascript, Dart или какой угодно ещё язык) или клиентского языка для описания способа упорядочивания и отображения интерфейса (HTML + CSS). В будущем клиентский код будет писаться на каком угодно языка, компилируемом в нативный код по желанию. Вместо, или вместе с поддержкой Native Client другим решением может стать некоторого сорта встроенная в браузер низкоуровневая виртуальная машина, сделанная людьми, понимающими, что они делают и знакомыми с передним краем разработок в области языков программирования и сред времени исполнения. Вероятно, это будут не те люди, которые разработали Dart, Go, Ceylon и другие языки, отстающие от переднего края на 30 лет или больше. Нам нужно что-то, что действительно может поддерживать работу языков будущего, а не перетасовывающие колоду на тонущем корабле нынешних меинстримных языков. Что насчет предложения просто использовать Javascript как «язык ассемблера» для web, как конечную точку компиляции, и воздерживаться от прямого написания кода на нем? Это, очевидно, не лучшее решение. Компилирование неигрушечного языка программирования, вроде того же Haskell или что там придет ему на замену, в Dart или Javascript это, конечно, не то, что кто-то придумал бы, если бы ему дали чистый лист и попросили придумать все заново. Даже если получится это сделать без раздувания размеров кода с клиентской стороны сверх допустимого, остается неизбежный штраф эффективности от компиляции в язык, сравнимый с Javascript по производительности. Если вы задумаетесь об этом, нет реального повода оставаться на одной десятой или одной сотой от производительности, которой может достичь нативный код или виртуальная машина с хорошим JIT только из соображений легкости развертывания готовых решений. Этот компромисс себя не оправдывает, и с развитием NaCl или настоящей виртуальной машины в браузере мы будем лишены необходимости воспринимать этот компромисс всерьез. Здесь есть один тонкий момент. Web обладает грандиозными сетевыми эффектами. Это составляющая её силы и полезности, нам не хотелось бы её терять. Нам все ещё нужны эквиваленты URL, но DOM нам не нужен. Что займет его место? Не нужен ли нам DOM для mashup’ов и поисковых движков? Нет. Кроме обхода DOM существуют другие пути, по которым программы могут получать информацию от приложений в web, и если вы задумаетесь об этом, то увидите, что в этом нет особенной сложности. Зачем царапать поверхность, когда вы можете использовать настояший API? Этот переход фактически уже происходит; большинство современных web-приложений предоставляют API в виде REST+JSON. Надо просто продолжать в этом направлении. На что это может быть похоже? Во-первых, нам нужна стандартная система типов для web. Под этим я подразумеваю стандартный способ для приложений, которые живут по адресу URL предоставлять модуль с типами и функциями, которые они поддерживают. Лежащая в основе система типов должна быть достаточно выразительной, чтобы быть в состоянии выразить данные более богато, чем это сейчас позволяет JSON (который, кроме того, что динамически типизирован, не в состоянии эффективно выразить даже типы-суммы); такая система будет поддерживать алгебраические типы данных и некоторые из возможностей систем типов, упомянутые выше. С учетом этого появятся стандарты для некоторых сигнатур функций, со стандартными ролями для них. Так, например, googlebot вместо обхода DOM в поиске ссылок может вызвать функцию getAllLinks у приложения по данному URL, и получить готовый список URL. getAllLinks будет описано специальным стандартом, и новые стандарты могут появляться по мере появления новых режимов взаимодействия с web-сайтами. Так, будут почти универсальные стандарты (вроде getAllLinks) и более специализированные, рассчитанные под конкретные web-приложения (например Facebook предоставляет некоторые функции и типы данных, специфичные для Facebook, они навряд ли будут реализованы другими сайтами, хотя они и могут это осуществить). Опять же, это уже начало происходить: существует множество ad hoc API и механизмов, по сути контролирующих то, как web-crawler’ы должны интерпретировать DOM. При наличии стандартного способа программного взаимодействия с web-сайтами не будет больше нужды в DOM и мы сможем увидеть расцвет инноваций разнообразных технологий упорядочивания и изображения элементов.

В завершение: о становлении функционального программирования

Я уже намекал на это: функциональное программирование бесспорно победит. Не все разделяют мою точку зрения, однако многие из путей развития, о которых я говорил, возможны только в предположении, что мы работаем в пост-императивном, функциональном мире. ФП позволяет добиться поразительного прироста продуктивности благодаря существенному увеличению количества повторно используемого кода и облегчения рассуждений о поведении кода (не говоря про облегчение параллелизации). Индустрия постепенно начинает осознавать это, но то, что многие программисты по каким-то причинам не желают этому учиться, на самом деле неважно. Со временем давление отбора на конкурирующем рынке удалит менее продуктивные и эффективные техники, как сорняки на грядке, и это по большому счету будет означать конец императивного программирования как мы его знаем, за исключением нескольких нишевых областей. Независимо от начальных склонностей и предпочтений, программисты и компании которые желают быть конкурентноспособными, будут пользоваться услугами функционального программирования. И относительно того, почему ФП не получило большего распространения уже сейчас: возможно, я напишу об этом подробнее в отдельном посте. Что я хочу сказать, так это то, что ФП сейчас достигло переломного момента, за которым открывается горизонт более широкого принятия и значимости. Здесь вступает в игру несколько факторов: технология компиляторов функциональных языков развилась достаточно, компьютеры стали мощнее, и, самое важное, сообщество ФП интенсивно открывает необходимые техники для организации больших программ с сохранением ссылочной прозрачности. Сообщество Haskell возглавляет эти перемены, так как Haskell, будучи единственным широко используемым языком с нестрогим порядком вычислений, не имеет другого выбора кроме как сохранять всепроникающую ссылочную прозрачность. Десять лет назад бытовало мнение, что выражение многих программ в чистом функциональном стиле требует новых исследований. Сейчас большинство этих техник уже известны, и выражение функциональности, обычно ассоциируемой с императивными программмами вполне возможно, а для опытного функционального программиста и нетрудно. Существуют еще интересные открытые вопросы относительного того, как представлять некоторые типы программ, но их количество стремительно уменьшается. Тем не менее, я понимаю, почему многие заявляют, что ФП это слишком трудно, неестественно или неудобно. Подобно многим полезным дисциплинам, свободное владение ФП нелегко и требует усилий. Хотя после того, как этот барьер преодолен, написание программ в функциональном стиле вполне естественно и не требует особых затрат. (конечно, проектирование ПО продолжает быть тяжелой задачей, но проектирование функциональных моделей становится легче с практикой). Для стороннего наблюдателя техники ФП кажутся непонятными и неоправданно сложными. Для людей, свободно владеющих этими техниками в них нет ничего сложного или запутанного, зато выгода значительна. А тем, кто предпочитает критиковать ФП, я считаю, не помешает заиметь немного скромности. Пользуясь аналогией, человек без математического образования навряд ли будет чувствовать себя в состоянии опровергать и критиковать целые области математики («глупая задумка вещественный анализ»), тем не менее программисты с очень приблизительным пониманием того, про что такое ФП находят в себе силы регулярно и громко критиковать его. Я понимаю, почему некоторые разочарованы существующими ресурсами для изучения предмета. Но неверно отвергать целую дисциплину по этой причине, или оглядываясь на личности тех людей (включая меня!), которые считают, что ФП более продуктивно. Это обективный параметр: или ФП стоит изучения благодаря продуктивности и другим выгодам, или нет. Что касается меня, то я один из соавторов книги по ФП, которая, надеюсь, будет полезна заинтересованным в изучении предмета. Со становлением техник ФП я надеюсь видеть все больше ресурсов, подобных этому, вплоть до состояния, когда свободное владение и значительная выгода в итоге будет чем-то, чего любой мотивированный программист сможет достичь, без необходимости сталкиваться с некоторыми разочаровывающими препятствиями, которые поджидают его на этом пути сегодня. Будет ли программирование в будущем выглядеть похожим на то, что я описал? Может быть, а может и нет. Но я надеюсь, что будет.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх