1. Главная страница » Компьютеры

Haskell язык программирования для чего нужен

Автор: | 16.12.2019
Haskell
Класс языка функциональный, ленивый, модульный
Тип исполнения компилируемый, интерпретируемый
Появился в 1990
Автор Аугустссон, Леннарт [d] , Уоррен Бертон [d] , Kevin Hammond [d] , Худак, Пол [d] , Джон Хьюз [d] , Томас Юнссон [d] , Пейтон-Джонс, Саймон , John Launchbury [d] , Мейер, Эрик [d] , Аластер Рейл [d] и Уодлер, Филип [d]
Разработчик Худак, Пол [d] [1] , Аугустссон, Леннарт [d] [2] , Джон Хьюз [d] [3] , Пейтон-Джонс, Саймон [4] , Мейер, Эрик [d] [4] и Уодлер, Филип [d] [4]
Расширение файлов .hs или .lhs
Система типов полная сильная статическая с выводом типов
Основные реализации GHC , HUGS, NHC , YHC
Диалекты Helium, Gofer, O’Haskell, Haskell++, Mondrian,
Disciple
Испытал влияние ML и Standard ML , Lazy ML [en] , Miranda, Lisp и Scheme, ISWIM, FP [en] ,
АПЛ, Hope и Hope+, SISAL [en] , Orwell [en] * , > [en]
Повлиял на Agda, Bluespec [en] , Clojure, C#, Cat, Cayenne [en] , Clean, Curry, Epigram [en] , Escher [en] , F#, Factor, Isabelle [en] , Java Generics, >Ωmega [en] , Perl 6, Python, Qi [en] , Scala, Swift, Timber [en] , Visual Basic 9.0, Rust
Сайт haskell.org
ОС кроссплатформенность

Haskell ( hæskəl ) — стандартизированный чистый функциональный язык программирования общего назначения. Является одним из самых распространённых языков программирования с поддержкой отложенных вычислений. Система типов — полная, сильная, статическая, с автоматическим выводом типов, основанная на системе типов Хиндли — Милнера. Поскольку язык функциональный, то основная управляющая структура — это функция.

Отличительная черта языка — серьёзное отношение к типизации; во многом в связи с этим язык назван в честь исследователя теории типов и изобретателя комбинаторной логики Хаскелла Карри.

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

Читайте также:  Palit geforce gt 240 1024mb

Содержание

Содержание

История [ править | править код ]

Haskell принадлежит к семейству языков ML. Непосредственно на него оказал большое влияние язык Миранда, разработанный в 1985 году Дэвидом Тёрнером. Миранда был первым чистым функциональным языком, имевшим коммерческую поддержку, и был относительно популярен в 1980-х годах, но оставался собственническим программным обеспечением. Это затрудняло развитие и исследования возможностей ленивого функционального программирования, поэтому буквально за пару лет появилось более десятка схожих языков. Чтобы объединить усилия разных разработчиков в 1987 году на конференции по функциональным языкам программирования и компьютерной архитектуре в Орегоне (FPCA’87) было решено создать комитет для разработки открытого стандарта.

В 1990 году была предложена первая версия языка, Haskell 1.0. В дальнейшем работа комитета продолжилась, и в 1999 году был опубликован «The Haskell 98 Report» [5] , который стал стабильным стандартом языка на много лет. Язык, однако, продолжал бурно развиваться, компилятор GHC был фактическим стандартом в отношении новых возможностей.

Читайте также:  Assassins creed odyssey глава 7

Разработка новых версий языка идёт открыто, этот процесс получил название Haskell’ [6] (Haskell Prime [ˈhæskəl praɪm], «Хаскелл-штрих»). Все желающие могут выдвигать свои предложения к обсуждению, предложения обсуждаются в течение года, комитет отбирает и объявляет предложения, которые готов принять, формируется новый комитет и к концу года готовится новая версия языка. Таким образом, новые версии языка теперь могут появляться каждый год. Планируется объявлять некоторые ревизии «значительными» и поддерживать такие ревизии на протяжении длительного времени.

Версия языка Haskell 2010 — была объявлена в конце 2009 г [7] , но последней «значительной» версией (стандартом) остаётся Haskell 98.

Характеристики языка [ править | править код ]

В качестве основных характеристик языка Haskell можно выделить следующие:

  • недопустимость побочных эффектов (чистота языка); возможность писать программы с побочными эффектами без нарушения парадигмы функционального программирования с помощью монад;
  • статическаясильнаяполная типизация с автоматическим выведением типов, основанная на типизации Хиндли — Милнера;
  • функции высшего порядка, в том числе лямбда-абстракции;
  • частичное применение;
  • ленивые вычисления;
  • сопоставление с образцом (англ. pattern matching ), функциональные образцы, охраняющие выражения (guards);
  • параметрический полиморфизм и его объединение с ad-hoc-полиморфизмом в единую модель посредством классов типов;
  • алгебраические типы данных, в том числе псевдобесконечные (за счёт ленивости);
  • генераторы списков (list comprehensions);
  • возможность интеграции с программами, реализованными на императивных языках программирования посредством открытых интерфейсов (стандартное расширение языка Foreign Function Interface (англ.) русск.[8] ).

С момента принятия последнего стандарта языка (Haskell98) прошло много времени, и с тех пор ведущие реализации языка (ghc и hugs) были расширены множеством дополнительных возможностей:

Реализации языка [ править | править код ]

Есть несколько реализаций языка Haskell [9] . Некоторые реализации ориентированы на практическое применение, в то время как другие — представляют прежде всего академический интерес.

Компиляторы и интерпретаторы [ править | править код ]

Наиболее популярен [10] на практике оптимизирующий компилятор GHC, который создаёт быстрый код и позволяет использовать многие расширения языка. GHC может оптимизировать как скорость, так и компактность программ, способен создавать многозадачный и параллелизованный код. В комплекте с компилятором GHC поставляется также интерактивная среда программирования GHCi со встроенным отладчиком. GHC работает в Windows, MacOS X и на нескольких юникс-подобных платформах (Linux, *BSD, Solaris). Именно GHC является стандартным компилятором в Haskell Platform, и именно на нём в первую очередь тестируются все новые библиотеки [11] .

Другая популярная реализация языка — интерпретатор HUGS. Он написан на Си, имеет малый размер дистрибутива и работает практически на всех платформах. HUGS предоставляет интерактивную среду программирования, но может также запускать программы на Haskell в стиле скриптовых языков. Пользователи Windows могут использовать графическую интерактивную среду WinHugs. Поскольку HUGS — это интерпретатор, то программы, запущенные в нём, выполняются медленнее, чем код, созданный большинством компиляторов языка Haskell. HUGS часто рекомендуют в качестве среды для изучения языка. HUGS полностью поддерживает стандарт языка Haskell 98, а также некоторые наиболее популярные расширения языка.

Другие известные реализации [12] :

  • nhc98 — быстрый компилятор, поддерживающий стандарт Haskell 98, написанный на Haskell 98; доступен для всех юникс-подобных платформ, включая MacOS X и Windows/cygwin
  • YHC (York Haskell Compiler) — форк nhc98, ставящий целью быть более переносимым и эффективным, поддерживает отладчик Hat; генерирует промежуточный байт-код, который можно использовать для генерации кода на других языках программирования
  • UHC (Utrecht Haskell Compiler) — компилятор, поддерживающий Haskell 98 почти полностью, а также некоторые расширения; поддерживает глобальный анализ программ; имеет несколько кодогенераторов, в том числе почти полностью функциональный генератор JVM-кода, кодогенераторы для LLVM и CLR в состоянии разработки; работает на юникс-подобных системах (включая MacOS X и Windows/cygwin)
  • HBI и HBC — интерпретатор и компилятор, поддерживающие стандарт Haskell 98 с некоторыми расширениями; точно работает в Linux, поддерживается слабо
  • LHC (The Luxurious LHC Haskell Optimization System) — альтернативный кодогенератор для GHC, поддерживающий глобальную низкоуровневую оптимизацию программы в целом
  • jhc — экспериментальный компилятор для исследования возможностей глобальной оптимизации программ
  • Yale Haskell — ранняя реализация языка Haskell на Lisp

Haskell Platform [ править | править код ]

В 2009 году сформировалась концепция Haskell Platform [13] — стандартного дистрибутива языка, включающего кроме компилятора (GHC), также дополнительный инструментарий (систему сборки и развёртывания пакетов Cabal) и набор популярных библиотек.

Сейчас Haskell Platform — это рекомендованный базовый дистрибутив для разработчиков. Готовые сборки Haskell Platform доступны для Windows, MacOS X и ряда дистрибутивов Linux.

Альтернативные целевые платформы [ править | править код ]

Большинство компиляторов языка Haskell создают непосредственно машинный код для используемой платформы, но есть несколько проектов, позволяющих производить код для виртуальных машин или генерировать код на других языках программирования. Степень зрелости и уровень поддержки подобных проектов сильно разнится.

  • LLVM:
  • патч для GHC [14] , добавляющий генератор кода для LLVM, в настоящее время включён в компилятор GHC [15] ; использование LLVM позволяет достичь большей производительности на ряде задач [16] .
  • альтернативный кодогенератор в UHT (работоспособен частично)
  • виртуальная машина Java (JVM):
  • LambdaVM [17] — патч для GHC, добавляющий генератор байткода JVM
  • jvm-br >[18] — мост между Haskell и JVM (для GHC)
  • jaskell [19] — генератор байт-кода JVM (вероятно заброшен)
  • альтернативный кодогенератор в UHC (работоспособен почти полностью)
  • Common Language Runtime (.Net):
  • прототип генератора MSIL-кода [20] для компилятора EHT/UHT
  • некоторые проекты по поддержке CLR упоминаются в GHC FAQ [21] , на начало 2010 года их состояние не ясно
  • JavaScript:
  • кодогенератор JavaScript для GHC [22] — патч для GHC, позволяющий компилировать программы в JavaScript-код
  • Ycr2Js [23] — конвертер байт-кода компилятора YHC в JavaScript
  • Fay — компилятор подмножества Haskell в JavaScript [24]
  • Языки описания архитектуры (Verilog/VHDL):
  • Clash [25] — альтернативный способ разработки ASIC и программирования FPGA

Несколько интересных целевых платформ доступны при использовании компилятора YHC, в частности существуют интерпретатор байт-кода YHC на Python и конвертер байт-кода YHC в Erlang Core, но эти разработки пока ещё экспериментальны. Также существуют реализации подмножеств языка на разных целевых платформах.

Расширения языка [ править | править код ]

  • макрорасширение с контролем типов ( Template Haskell[en] );
  • объектно-ориентированное программирование (O’Haskell, Haskell++ и Mondrian).

Расширения реализаций языка (относится к GHC):

Примеры [ править | править код ]

Вычисление факториала [ править | править код ]

Следующий пример показывает синтаксис языка Haskell при реализации функции для вычисления факториала:

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

что соответствует математическому определению факториала.

Первая строка в приведённом выше коде необязательна и является объявлением функционального типа, то есть задаёт типы аргументов (указаны до последней « -> ») и тип возвращаемого значения (указан после последней « -> »). Эта строка может быть прочитана как: функция fac имеет тип ( :: ) из целого в целое ( Integer -> Integer ). Это значит, что она получает на вход один целочисленный аргумент (записан слева от «->») и возвращает результат также целого типа (записан справа от «->»). Если программист не указал типы явно, компилятор или интерпретатор может определить их автоматически.

Вторая и третья строки формируют определение тела функции. Определение состоит из предложений, или «клауз» (англ. clause ). Каждое предложение представляет собой пару «образец — выражение». Компилятор или интерпретатор использует механизм сопоставления с образцом для выбора одного из выражений. В данном случае вторая строка определения будет выбрана тогда, когда фактический параметр при вызове функции fac будет равен нулю.

В третьей строке помимо механизма сопоставления с образцами использовано охраняющее выражение — n > 0 . Оно гарантирует, что функция не будет работать для отрицательных чисел, для которых факториал не определён. Если отрицательное число будет передано в качестве фактического параметра в функцию fac , то программа остановится с сообщением об ошибке.

Калькулятор [ править | править код ]

Простейший калькулятор для вычисления выражений в обратной польской записи может быть определён на языке Haskell при помощи одной функции:

Исходная строка со входным выражением тут разбивается стандартной функцией words на список слов — строк между пробельными символами — который обрабатывается функцией левосторонней свёртки ( foldl ) слева направо по одному слову с помощью функции f , которая поддерживает рабочий список прочитываемых чисел и промежуточных значений (поначалу [] — пустой список) и интерпретирует каждое входное слово как обозначение арифметической функции или как число, в ходе вычисления ею окончательного значения выражения (которое будет первым оставшимся значением в рабочем списке по окончании обработки списка слов входного выражения, так что его можно достать оттуда с помощью стандартной функции head ).

Здесь (.) есть оператор композиции функций, (f . g) x = f (g x) . Например,

Числа Фибоначчи [ править | править код ]

Другой пример показывает способ вычисления бесконечного списка чисел Фибоначчи за линейное время:

Бесконечный список здесь определён при помощи механизма корекурсии — последующие значения списка здесь задаются на основе предыдущих, с начальными 0 и 1 в качестве первых двух элементов списка, и выражением-генератором zipWith (+) fibs (tail fibs) , вычисляющим все элементы начиная с третьего на основании предшествующих двух, через стандартную функцию zipWith (+) которая суммирует попарно элементы двух своих входных списков.

Это определение является примером применения механизма ленивых вычислений, который является важнейшей частью языка Haskell. Для понимания того, как это определение работает, можно рассмотреть вычисление первых семи чисел Фибоначчи с его помощью:

То же самое может быть записано также при использовании определителей списков,

или расширения языка Haskell, реализованного в компиляторе GHC (параллельных определителей списков, англ. parallel list comprehensions ):

Простые числа [ править | править код ]

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

или с помощью решета Эратосфена, в прототипичном, неэффективном варианте,

или эффективно, с предварительным каскадным объединением потоков составных чисел:

или посегментно, массивами,

с использованием канонических функций minus , union [26] ):

Описание игральных карт [ править | править код ]

Простой пример использования алгебраических типов данных для описания игральных карт. Идентификаторы типов начинаются с заглавных букв. Идентификаторы переменных и функций — со строчных. Новые алгебраические типы определяются ключевым словом data . Синонимы типов определяются ключевым словом type .

Численное интегрирование [ править | править код ]

Численное интегрирование ∫ 0 2 π x sin ⁡ x d x = − 2 π <displaystyle int limits _<0>^<2pi >xsin x,<
m >x=-2pi > методом трапеций:

Проверка палиндромов [ править | править код ]

В примере ниже демонстрируется работа со строками в Юникоде.

Приложения, написанные на языке Haskell [ править | править код ]

Мозаичный оконный менеджер Xmonad для X Window System целиком написан на языке Haskell. Darcs — распределённая система управления версиями с рядом уникальных возможностей — написана на Haskell. Первая реализация компилятора и интерпретатора языка Perl 6, Pugs, была написана на Haskell за несколько месяцев. Компилятор GHC часто выступает экспериментальной площадкой для проверки новых возможностей функционального программирования и оптимизации.

Коммерческие приложения [ править | править код ]

Haskell всё чаще используется в коммерческой среде [27] . Этому способствует и принятая в сообществе традиция выпускать библиотеки под либеральными лицензиями (более 70 % свободно доступных библиотек распространяются на условиях лицензий BSD, MIT или являются общественным достоянием).

Вот примеры некоторых коммерческих приложений, написанных на Haskell: Bluespec SystemVerilog, встраиваемый язык проектирования и верификации полупроводниковых схем, является расширением языка Haskell [28] . Cryptol, коммерческий язык для разработки и проверки криптографических алгоритмов, реализован на Haskell. Примечательно, что первое формально верифицированное микроядро seL4 было тоже написано на Haskell.

Haskell активно применяется в области финансового программирования, анализа рисков, в системах поддержки принятия решений. Haskell применяют разработчики генератора городских ландшафтов для игр и моделирования Gamr7 [29] . Есть примеры успешного применения языка для разработки частных информационных систем в коммерческих организациях (в том числе, в странах СНГ) [30] .

Приложения с открытым исходным кодом [ править | править код ]

Также на Haskell написано много приложений c открытым исходным кодом. Большинство из них доступны в архиве Hackage, ниже приведены некоторые из них.

Рассказывает автор блога Mechanical Elephant, Мэтью Гриффин

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

И хотя я иногда прибегаю к помощи Python, большую часть работы в вебе я теперь делаю на Haskell.

В первую очередь — данные

Я думал о переходе от динамического языка к статическому, а в Haskell’e структура данных, с которыми вы работаете, четко описывается при объявлении. В Python в большинстве случаев эту задачу выполняет код.

Когда я впервые увидел функции в Haskell, я задался вопросом: «Что представляют собой данные? Эта функция что-то берет на вход и выдает что-то на выходе?» А при работе с Python у меня возникал вопрос: «WHAT DOES THE CODE SAY?»

XYZ school, Москва, до 250 000 ₽

Структура данных Haskell сформировала качественно новый образ моего мышления, который я принес и в свою работу на Python. Мой код стал заметно лучше. И хотя очень часто мне казалось, что форма описанных мною данных менялась без причины, однако на деле все становилось ясно при небольшом изучении вопроса. Ограничения свободы в изменении данных также делают код менее сложным и более понятным.

Читаемость кода

Python привлекал меня возможностью писать действительно читаемый код. Примеры кода же на Haskell выглядели просто ужасно, за исключением некоторых сниппетов, которые, казалось, были подобраны специально, чтобы не напугать новичков. И хотя некоторые куски кода смотрелись очень даже приятно, большая часть исходников была наполнена чем-то страшным. А за этим «страшным» как раз и скрывалась вся мощь языка.

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

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

Я понял, что Haskell — это язык не «умный», но с хитринкой. Написать «умный» код на Haskell, конечно, можно, но это не распространенный случай. В то же время, мощь «умного» кода ограничена строгой типизацией. Если функция должна вернуть Int, она вернет Int. Ну или выкинет ошибку компиляции в крайнем случае.

А более мощные абстракции в Haskell и вовсе напоминают некую магию, которой я пытался избегать при работе с Python.

Про читаемость я говорю серьезно

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

Комментарии. Они занимают верхнюю строчку в одной из глав нашей «книги».

Эта глава описывает то, как Томми пошел в магазин и купил утку.

Функции из другой, уменьшенной функции, в общей картине сокращают код по максимуму.

Краткость. Вам не потребуется тонна кода для воплощения ваших идей.

Вставные символы

Я также хотел упомянуть о вставных функциях, которые распространены в языке Haskell. Вставные функции (или операторы) — это те функции, которые используют between для двух аргументов вместо before. Простым примером является «+».

В языке Haskell мы имеем несколько вставных символов, которые используются по умолчанию: $, , , др. Они могут вас немного смутить на начале пути.

Не переживайте! Как только вы научитесь применять их, вы поймете, как они полезны и просты. Я насчитал около 5 символов, которые я использую регулярно.

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

Нужно полностью обновить знания

При изучении Haskell вы будете попутно сталкиваться с новыми терминами, например, функтор или монада.

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

Мы запоминаем информацию путем ассоциирования ее с другой информацией. Например, у меня нет ассоциаций со словом функтор, поэтому выучить этот термин мне будет не легко.

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

В языке Haskell многое отображается на вашем экране. Например, список — это и есть функтор. Это значит, что отображающая функция, которая использует другую функцию, и выводится в списке. Затем создается новый список с результатами.

Так я дал название этому — мапа. Слово «мапа» является очень простым для запоминания. Список — это функтор. Список — это мапа.

Моя система проверки ошибок

Когда я писал на Python, моим инструментом отладки были операторы печати.

В Haskell я пользовался систематическими инструментами.

Но! Вы можете применить Debug.Trace. Данный прием схож с тем, как в Python функция печати не зависит от Haskell IO. И данный модуль может вначале принести пользу . Когда вы только начинали работать с Haskell, вы думали о том, как много вы будете его использовать?

Если вы не будете использовать операторы трассировки в вашем коде после проверки ошибок, то вы сразу заметите, что ваш код в Haskell выглядит хуже, чем в Python.

Лучший учебник по монадам

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

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

Окей, сейчас я расскажу подробнее. Я буду объяснять на Haskell.

Я нашел видео на YouTube, «Parsing Stuff in Haskell», в котором описывалось, как сделать JSON анализ в Haskell, используя при этом библиотеку Parsec.

Это видео помогло мне ненароком понять, как можно, используя монады и аппликативные функторы, создать то, что мне требовалось. Я понял, как их функции (har, har) соединяются друг с другом.

После написания синтаксического анализа при помощи видео, я начал понимать весь код. Я также начал понимать всю его «природу». Но на начальном этапе это не пригодится.

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

Польза от ваших знаний

Haskell является моим основным языком по нескольким причинам:

  1. Выбор технологий, которыми я буду пользоваться.
  2. Я могу писать свои программы быстрее, и чаще всего эти программы я и продаю.
  3. Не приходится иметь дело с мелкими багами.
  4. Даже сталкиваясь с несколькими ошибками, я быстро решаю их, так как они более-менее понятны.
  5. Python не делал акцент на скорости работы. Haskell делает то же самое, но выбор все же за мной.
  6. Рефакторинг, по сути, достаточно «ветреный». В Python я иногда сильно ругал себя, когда забывал править небольшие ошибки в коде, которые позже вызывали огромные затруднения.
  7. Замечательные библиотеки. Основная особенность Haskell заключается в высоком качестве библиотек.
  8. Сообщество, всегда готовое помочь.
  9. Простота масштабирования кода до нужного ядра.
  10. Haskell часто обновляется. В прошлом году, когда GHC (компилятор для Haskell) был обновлен до версии 7.8, делая при этом написание кода в два раза удобнее, были ускорены многие веб-сервера.

И в заключение хочу сказать, что Haskell доставил мне уйму удовольствия. Это был лучший опыт за всю мою жизнь.

С чего можно начать?

Я постарался и нашел много «отправных точек» для начала вашего знакомства с Haskell.

Здесь я продемонстрирую то, как бы я начинал, если бы был не знаком с Haskell.

Отлично! Теперь выполните следующие пункты:

Ещё одна копия хабора

Когда в конце 2006 года я готовил последние материалы для публикации своей первой книги по функциональному программированию и языку Haskell [1], один из коллег автора, приглашённый для вычитки и рецензирования, попытался сделать пророчество относительно «золотого» будущего функциональной парадигмы в деле разработки программного обеспечения промышленных информационных и автоматизированных систем (в качестве лирического отступления можно привести несколько смягчённые слова пророчества: «Скоро настанут времена, когда программисты на языке Haskell будут жить в дворцах с золотыми унитазами, а программисты на языках Java, C++ и им подобным будут работать за еду»). С тех пор прошло достаточно времени, чтобы успеть построить если и не дворец, то хотя бы домик, однако в деле распространения и повышения популярности языка Haskell и функционального программирования в целом каких-либо значимых результатов практически нет.

Имеет смысл разобраться с этой ситуацией и рассмотреть основные причины и факторы, не дающие языку программирования Haskell стать достаточно популярным для того, чтобы работодатели отрывали знатоков этого языка с руками, а функциональная парадигма программирования стала «мейнстримом».

Ещё в 1998 году Филип Уодлер написал неплохой обзор «Почему никто не использует функциональные языки программирования» [2]. В этой статье автор резонно указал, что такие факторы как эффективность, быстродействие, наличие компиляторов под основные промышленные платформы и др. — это не причины низкой популярности функциональной парадигмы. Более того, уже сегодня практически сходит на нет воздействие таких факторов, как совместимость, наличие достаточного количества библиотек, мобильность и интероперабельность, доступность утилит и инструментальных средств. Сообществом любителей функциональной парадигмы все эти аспекты использования языка Haskell развиваются в достаточной мере.

Тем не менее, отмеченные в статье Ф. Уодлера такие факторы непопулярности, как доступность технической поддержки, обучаемость и, как ни странно, популярность являются на текущий момент наиболее существенными причинами, по которым язык Haskell остаётся инструментом энтузиастов и научных лабораторий, но не выходит на уровень языка, используемого в промышленности при разработке программного обеспечения информационных и автоматизированных систем. Эти три фактора стоит рассмотреть более подробно:

Доступность технической поддержки. Одним из факторов, принимаемым во внимание руководителем проекта при рассмотрении готовых к использованию инструментальных программных средств и библиотек сторонних производителей является доступность технической поддержки и ответственность разработчика за своё изделие. Особенно это касается разработки автоматизированных систем управления для непрерывных технологических процессов на опасных производствах. Если для информационных систем управления каким-нибудь документооборотом нет нужды следовать стандартам безопасности (не информационной, а самой непосредственной, физической безопасности), то для пожароопасных и взрывоопасных производств техника безопасности является одним из главных факторов даже при разработке автоматизированных систем.

В случае разработки автоматизированных систем классов АСУ П (автоматизированная система управления предприятием, в англоязычной терминологии — ERP) и СППР (система поддержки принятия решения, в англоязычной терминологии — BI) одним из главных является вопрос информационной безопасности. При использовании сторонних программных средств руководитель проекта всегда будет думать о том, кто даст гарантии и ответит за проблемы, возникшие по вине разработчиков сторонних продуктов. Даже идеология открытых исходных кодов здесь не помогает — открытая библиотека доступна для изучения, но ответственных за неё всё же нет. И получается, что ответственность за чужой по сути код возьмёт на себя проектная команда. И, соответственно, для минимизации рисков проектная команда должна будет очень скрупулёзно изучить и протестировать эти самые открытые исходные коды, что по времени вполне сравнимо с разработкой «с нуля».

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

Обучаемость. Другой важной причиной, почему руководители проектов с опаской и недоверием относятся к «эзотерическим» языкам программирования и нестандартным (не «мейнстримным») парадигмам, является то, что для получения серьёзного специалиста в таких языках и парадигмах необходимо вложить в него несравненно больше знаний, чем при использовании обыденных инструментов вроде объектно-ориентированного программирования. Не «мейнстримные» парадигмы программирования требуют от своих адептов при овладении намного больше усердия и рвения, чем те, которые «используются всеми». Это — странная ситуация, поскольку невозможно доподлинно сказать, что естественней для человеческой психики — выражать решение задачи через последовательность действий (императивная, процедурная парадигма), или через декомпозицию задачи на подзадачи, в том числе и рекурсивно (функциональная парадигма). Что естественней — выражение сущностей предметного мира через объекты и их свойства (объектно-ориентированная парадигма) или через функциональность, которую можно применить к имеющимся сущностям (функциональная парадигма и теоретико-категориальный подход)? Эта тема ещё ждёт своего исследователя (см. также мысли в [3]).

В итоге я вспоминаю, что после выхода очередного номера научно-практического журнала «Практика Функционального Программирования» в сети Интернет в блогах читателей появляются слова вроде: «Читаю журнал. Хочется бросить всё и поступить в хороший технический ВУЗ» [4]. Естественно, что подобное реноме сложных для постижения языков программирования не усиливает их позиций в глазах руководства, принимающего решения о выборе средств разработки.

Кроме того в этом деле имеется ещё один аспект, связанный с межличностными отношениями в проектной команде. Руководитель проекта, набирающий персонал под своё руководство, ещё сто раз подумает над тем, кого выбрать — «ботаника», закончившего ВМК МГУ с красным дипломом и имеющего на очках линзы толщиной 5 см (это стереотипное описание — просто фигура речи; никого конкретного я не имею в виду; более того, я против такой стереотипизации образа людей, работающих с функциональными языками, поскольку опыт показывает, что всё далеко не так), но зато владеющего сотнями различных парадигм и свободно общающегося на сотнях же «эзотерических» языках программирования, либо вполне обычного человека, умеющего не только закодировать какой-либо алгоритм, но и поговорить на общие темы, сыграть в кегельбан после работы или даже съездить на шашлык в грядущие выходные.

Проектные команды, состоящие из социопатов, вряд ли добьются успеха в современном окружении. Будет намного проще и эффективнее инвестировать время в социально адаптированных сотрудников, для которых можно провести пару или тройку занятий по информатике и математике (если необходимо). Например, специалисту, заявляющему на собеседовании, что «настоящему программисту нет необходимости владеть математическим аппаратом» (из моего личного опыта), можно для систематизации и структуризации знаний преподать теоретические основы представления и кодирования информации. Обучать сотрудников хотя бы основам той же теории категорий для получения эфемерных эффектов при работе — бесполезная и нецелесообразная трата проектного времени, поскольку усилия, затраченные на разъяснения, не окупятся ни при каких обстоятельствах.

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

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

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

Рассмотренная ситуация приводит к тому, что традиционные императивные и объектно-ориентированные языки программирования перевешивают в споре парадигм, поскольку при более или менее равных условиях по производительности, эффективности кода и т. д. существуют дополнительные факторы, которые не позволяют руководителю проекта принять в качестве рабочего немейнстримный инструментарий. Дело в том, что имеются серьёзные риски получить неподдерживаемые исходные коды на «эзотерическом» языке программирования, адептов которого на рынке труда можно пересчитать по пальцам рук и ног (соответственно, их можно назвать локальными «звёздочками» с вытекающими из этого последствиями — повышенные требования к оплате за услуги по обучению инженерного персонала и ведению проектов, что в свою очередь влечёт риски по срыву сроков и бюджета проекта). На другой чаше весов лежат эфемерная возможность кардинального уменьшения сроков разработки и практическое отсутствие необходимости в функциональном тестировании исходных кодов (при этом другие виды тестирования, в том числе и комплексное тестирование готовой автоматизированной системы управления, всё так же будут необходимы). Само собой разумеется, что руководитель проекта не будет даже смотреть в сторону функциональных языков программирования, какими бы прекрасными они ни были, даже если он сам является энтузиастом и апологетом того же языка Haskell.

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

С другой стороны всё вышеописанное приводит к появлению эффекта, который вслед за Б.

Гейтсом можно назвать «петлёй положительной обратной связи» [5]. Отсутствие интереса работодателей к функциональной парадигме программирования приводит к нежеланию молодых специалистов инженерных специальностей заниматься повышением своей квалификации в этом направлении. Это приводит к отсутствию специалистов в области функциональных языков программирования, что в свою очередь усиливает влияние на руководителей проектов в их нежелании применять «эзотерические» парадигмы программирования.

Этот эффект можно пояснить простым примером. На ХедХантере, одном из ведущих web-сайтов по поиску работы, среди всех опубликованных вакансий во всех областях деятельности за последний месяц словосочетание «функциональное программирование» (в любой форме, даже в виде сокращения) встречается только 2 раза, в то же время словосочетание «объектно-ориентированное программирование» встречается порядка 550 раз. Что касается упоминания в описаниях вакансий конкретных языков программирования, то языки Haskell и Erlang упоминаются по 6 раз, язык Lisp упоминается 5 раз, язык OCaml упоминается 3 раза, причём можно считать, что всего имеется 6 вакансий, которые интересны программистам на функциональных языках программирования, поскольку все перечисленные языки встречаются в описании одних и тех же вакансий, причём в контексте «желательно знание интересных языков программирования, таких как…». С другой стороны, такие языки как Java, C++ и C# встречаются в описаниях вакансий от 500 до 1000 раз.

Такая ситуация не может не влиять на выбор молодых специалистов. Естественно, что мало кто захочет тратить своё время на изучение необычных языков программирования, пусть даже превосходящих по красоте и продуктивности деятельности разработчика обычные «мейнстримные» языки, но не интересные работодателям.

В качестве дополнительного предположения из вышеизложенного можно отметить, что данная петля положительной обратной связи уже пагубно сказалась на многих аспектах использования функционального программирования в общем и языка Haskell в частности. Например, можно отметить, что по данным аналитического отчёта компании TIOBE Software [6] популярность функциональной парадигмы программирования находится где-то в районе 3 %, в то время как у объектно-ориентированной парадигмы популярность зашкаливает за 50 %. В первую двадцатку входит лишь один язык программирования, который с натяжкой можно назвать функциональным — Ruby. Все функциональные языки программирования крепко сидят в интервале от 21 (Lisp) до 50 (Haskell) места.

Данные этого отчёта коррелируют с текущим уровнем популярности языков программирования, которые используются в учебных и развлекательных целях. Если рассмотреть такие интернет-ресурсы, как «Проект Эйлер», то и на них уровень популярности функциональных языков программирования снижается (официально подтверждённых данных нет, данное утверждение основано на личном опыте автора). Если несколько лет назад язык Haskell находился в пятёрке используемых для решения задач языков программирования, то сегодня пользователи, решившие наибольшее количество задач, используют такие языки программирования как C++, Java, Python, C# и др.

Ситуация плачевна. Работа на ниве популяризации функциональной парадигмы программирования в общем и языка Haskell в частности видится безблагодатной. В будущем популярность языка Haskell будет только падать в относительном сравнении с объектно-ориентированными языками программирования. Скорее всего, такое положение вещей никогда не будет выправлено, и пророчество о «золотых унитазах», приведённое в начале статьи, так и останется голословным.

В связи с вышеописанным можно дать рекомендацию, которая, возможно, поможет как начинающим, так и умудрённым опытом разработчикам программного обеспечения. Учитывая данные уже упомянутого аналитического отчёта [6], имеет смысл развивать свои навыки в таком языке программирования, как PHP. Этот язык набирает мощнейшие обороты в практике разработки промышленных программных средств и создания автоматизированных и информационных систем. Учитывая, что стоящие на первых двух местах языки программирования Java и C/C++ являются более или менее общеизвестными, то как для повышения своего уровня привлекательности для потенциальных работодателей, так и для собственного развития имеет смысл изучать именно этот язык.

Ну, а функциональную парадигму программирования и язык Haskell можно оставить фанатикам.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *