СЕМИНАРИ.А. Сукин,г. Переславль-Залесский36сентябрь 2011 / ИНФОРМАТИКАHaskell: серебрянаяпуля современногопрограммирования?Что такое функциональноепрограммирование?Описать язык Haskell непросто. Сам основнойразработчик и законодатель мод этого языкаСаймон Пейтон-Джонс полагает, что главныйминус Haskell — его чрезмерная полнота инепривычность для среднестатистического современногопрограммиста. Поэтому я вынужденсовершить небольшой экскурс в историю ипричины появления такого явления, как функциональноепрограммирование. Надеюсь, чтоэто краткое путешествие позволит вам лучшевникнуть в глубины этого чисто функциональногоязыка.Традиционно, когда мы в современном миреупотребляем термин “программирование” или“язык программирования”, мы имеем в видупрограммирование императивное и такие широкораспространенные в наше время языки,как C, Pascal, Java, C#. У многих информатиковтермин “программирование” неустанно следуетвместе с понятиями объектов и объектноориентированногоподхода. Немалое же количествопрограммистов вообще имеет очень смутныеи крайне общие представления о разделенииязыков и парадигм программирования.Для тех читателей, что не стесняются относитьсебя к последней категории (признаться, я сампостоянно сомневаюсь, что в этом хитросплетениисущностей можно хоть как-нибудь разобраться),необходимо ввести некоторые определенияи строго показать структуру современного“зверинца” языков программирования.В современном состоянии вычислительнаятехника переживает некоторый кризис, связанныйс принципиальной несовершенностьюсуществующих компьютеров и отсутствиемпрактических реализаций компьютеров другоготипа, например, биологических или квантовыхвычислителей. Современная ЭВМ — этомашина фоннеймановского типа, нравитсянам это или нет. Несмотря на то что идея такихмашин считалась устаревшей уже 30 лет назад,они до сих пор являются фактически единственнымизвестным нам способом аппаратнореализовать вычислительное устройство, обладающееприемлемыми для нас характеристикамии производительностью. Все основныеимперативные языки программирования, будьто C, Pascal, с оговорками Java и C#, являютсямоделями машины фон Неймана.Чем же плоха такая машина и чем плохи еемодели, а также какие из возникающих приэтом проблем можно устранить при помощи
функционального программирования? Напомнюосновную структуру машины фон Неймана: в самомобщем случае у нас имеются процессор и память,подключенные к одной соединительной шине, черезкоторую они и вынуждены общаться. Эта шинане зря издавна называется “узким местом фонНеймана”: вся основная нагрузка в машине такоготипа ложится на нее. В принципе, можете сказатьвы, ничего страшного в этом нет. Но вспомнитесвой опыт программирования, например, на языкеСи, или даже на языке ассемблера: основную массуконструкций языка занимают имена, имена данныхи операций, а также операции по раскрытиюсоответствующих имен (вспомните, например, такиевещи, как косвенная адресация) — именно этанагрузка бесполезным грузом ложится на “узкоеместо фон Неймана”.Рассмотрев главную проблему самой концепциифоннеймановской машины (тут уж мы ничего неможем сделать, реализация ЭВМ другого типа выходитза рамки данного обсуждения), обратимсяк проблемам собственно языков программирования,являющихся моделями машины фон Неймана.Исследователи выделяют четыре основных критерияоценки подобных моделей: математическаяобоснованность, историческая чувствительность(другими словами — степень зависимости текущегосостояния модели от ее предыдущих состояний),удобство и тип семантики, ясность и концептуальнаячистота программ, описываемых конкретноймоделью. Я не буду подробно описывать то, чтостоит за каждым из этих понятий, интересующиесямогут обратиться к соответствующей литературе,скажу лишь, что подавляющее большинство столповнынешней computer science справедливо считают,что модели фоннеймановского типа заслуживаютвесьма низких оценок по этим критериям.К примеру, возьмем слова создателя языка FortranДжона Бэкуса: “По-видимому, с языками программированияпроисходит что-то неладное. Всякийновый язык включает с небольшими изменениямивсе свойства своих предшественников плюс коечтоеще... но фактически дела обстоят так, что лишьнемногие языки снижают затраты на программированиеили повышают его надежность...” [1]. Этоположение было высказано Бэкусом в его лекции,как раз посвященной функциональному программированию.В заключение этих нескольких абзацев подчеркнуих основную идею: современные популярныеязыки программирования своими корнями прочностоят в императивной парадигме программирования;императивная парадигма программированияявляется прямой моделью машины фон Неймана;мы согласимся со светилами информатики XX векаи поддержим мысль о том, что императивное программированиедавно изжило себя.Неудивительно, что многие исследователи ужедавно пришли к выводу о том, что нужно искатьдополнительные пути и придумывать новые парадигмыпрограммирования. Однако сама идеяфункционального программирования в виде использованияоткрытий таких математиков и логиков,как Хаскелл Карри, Алонсо Черч, МоисейИсаевич Шейнфинкель, появилась гораздо раньшеразочарования программистов в императивныхязыках и пришла к нам из разработок в области искусственногоинтеллекта в виде языка Лисп. Лиспбыл и остается совершенно утилитарным языком,хорошо заточенным под нужды задач, близких кискусственному интеллекту. Идея создания чистогоматематически обоснованного языка, специальнопризванного для преодоления проблемфоннеймановских моделей, возникла в конце60-х — начале 70-х годов XX века в работах такихисследователей, как вышеупомянутый Джон Бэкус,Робин Милнер, Дэвид Тернер, отчасти ВалентинФедорович Турчин. Из этих идей родились языки,не привязанные к аппаратной части компьютеров,красиво описываемые математическими формализмами:ML, Рефал, FP, SASL. В начале своего путиэти языки были далеки от требуемого идеала, ониявлялись лишь доказательством того, что программированиеможет быть отделено от фоннеймановскогостиля. В дальнейшем функциональные языкиактивно развивались, и венцом этого развитиястал виновник нашего “торжества”: язык Haskell(названный в честь уже упомянутого математикаХаскелла Карри, одного из авторов комбинаторнойлогики, лежащей в основе многих языков функциональногопрограммирования).Справедливости ради надо сказать, что созданиефункциональной парадигмы было не единственнымответом на моральное устаревание императивныхфоннеймановских языков, примером могут служитьлогическая и объектно-ориентированная парадигмы.Однако эти парадигмы страдают от отсутствия мощнойматематической базы и могут быть выраженыв терминах функционального программирования,поэтому мы не будем сильно заострять на них нашевнимание. Интересующиеся могут обратиться к соответствующейлитературе [2, 3].Haskell: о самом важномНадеюсь, предыдущий раздел оставил у вас положительныевпечатления о функциональном программированиии заставил несколько обновитьсобственные взгляды на программирование императивное.Если нет, у вас еще будет предостаточновремени сделать это, читая остаток этой статьи.Что же такое Haskell? Haskell — это чисто функциональныйязык программирования. Заостритесвое внимание на слове чисто. Чуть позже вы поймете,почему оно так важно в определении этогоязыка. В императивных языках работа программысостоит в выполнении компьютером последовательныхзаданий, описанных на вашем любимом37сентябрь 2011 / ИНФОРМАТИКА