Christopher Allen and
Julie Moronuki, Haskell programming from first principles, 2015

Vitaly Bragilevsky
5 min readAug 31, 2017

--

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

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

В версии для чтения с экрана 1284 страницы, и в этом серьёзная, как мне кажется, проблема. Книга позиционируется как учебник для начинающих, в том числе для начинающих изучать программирование вообще, не только Haskell. Мой более чем пятнадцатилетний опыт обучения программированию показывает, что чем меньше информации даётся обучаемому, тем лучше. Минимум необходимой информации — масса упражнений — ещё чуток информации — снова упражнения. Только так: умение программировать приходит исключительно с упражнениями, и уж никак не с чтением. Я не могу себе представить изучающего программирование школьника или студента, готового читать тысячу страниц. Мне кажется, что на это способны только взрослые люди с большим количеством свободного времени. Если вы когда-нибудь видели документацию к 1С, то можете себе это представить.

В качестве важной черты книжки всюду указывается подробность объяснений. Да, они очень подробны, слишком подробны, ужасно обстоятельны и детальны, с постоянными повторами и объяснениями другими словами. Ок, повторение — мать учения, мать учения, мать учения…

После титульного листа идут отзывы читателей (эта книга лучше SICP’а, Haskell до этой книги и Haskell после, наконец-то книгу по Haskell написал тот, кто понимает, как ему обучать); 12 страниц с содержанием (здесь и далее по версии для чтения с экрана); предисловие от авторов (отдельно история Криса и история Жюли); благодарности, общие и по отдельности; введение; объяснение, почему нужно читать книгу про Haskell; объяснение, что эта книга не является туториалам по монадам (тут нам повезло, да!); развеивание слухов относительно сложности Haskell (ну да, элементарный язык, тысячу страниц прочтёшь и всё); обращение к новичкам в программировании (где и как искать помощи); Haskevangelism (сравнение с другими языками, начиная с Algol и LISP — ох, какие эрудированные авторы, потрясающе); рассказ о содержимом книги с методической точки зрения (структура глав, убеждение о недопустимости пропускать главы, другие рекомендации по порядку чтения); инструкции по проработке примеров и упражнений. Хорошо, наш абстрактный начинающий в вакууме продрался через эти 12 страниц (скипнул, очевидно) и подошёл к первой главе. Тут-то его и шарахнули академизмом: извольте послушать про лямбда-исчисление. Ведь все знают, что изучать программирование нужно с самого начала: учишь императивный язык — изволь пожевать машину Тьюринга, функциональный — лямбда-исчисление тебе в зубы. Ну ладно.

Во второй главе начинается Haskell: работа с GHCi, выражения, простые функции, порядок вычислений, операторы, ассоциативность, стандартные функции, расстановка скобок. Нормально, в общем, 40 страниц. Потом ещё пять глав на 200 страниц: строки, типы, классы, объявление функций — всё подробно, но поверхностно, только самое необходимое.

В восьмой главе нас начинают учить рекурсии, тема важная, сложная. Впрочем, авторам хватает 25 страниц. Посмотрим на эту главу подробнее. Нельзя просто так начать главу по рекурсии, не продемонстрировав читателю широчайший кругозор автора, ну да ладно, мы уже верим, проскочили кучу текста про логические и математические системы с рекурсией. Факториал! Ну конечно, куда без него: сначала мы вычисляем факториал четырёх, потом пытаемся обобщить на общий случай, сначала, разумеется, неправильно: забываем базовый случай, обнаруживаем зацикливающиеся вычисления. Потом исправляемся, но зачем-то снова смотрим на зацикливающиеся вычисления (любой редактор выбросил бы этот кусок!), наконец, смотрим правильные вычисления (целая страница!). Потом внезапно нам рассказывают, как смотреть на рекурсию по другому, а именно как на композицию функции самой с собой. Ничего не скажешь, так, разумеется, всякому начинающему гораздо понятнее. Глава по рекурсии продолжается рассказом о концепции дна и введением типа Maybe. Отличная структура, где же ещё Maybe вводить! Затем ещё один пример полезной рекурсивной функции — разумеется, числа Фибоначчи (правильная версия получается через много этапов, сначала они выписывают два базовых случая, не работает, потом общий случай, в котором забывают сделать рекурсивные вызовы и поставить знак + между двумя скобками, потом доставляют знак +, но про рекурсивные вызовы не вспоминают, по-прежнему не работает, долгое объяснение, почему, наконец, гениальная идея и вуаля, теперь можно долго объяснять порядок вычислений, уже правильный. Продолжаем изучать рекурсию: реализуем своё деление (с первых принципов, не забывайте!). Много упражнений, часть из них про списки: классика, ни одного примера рекурсивной обработки списков ещё не было, другая часть на то, что было в предыдущих главах! Заканчивается глава определением рекурсии, ну чисто чтобы закрепить, мы же великие методисты. Не могу удержаться, привожу его полностью. Оцените понятность!

Recursion is a means of computing results that may require an indefinite amount of work to obtain through the use of repeated function application. Most recursive functions that terminate or otherwise do useful work will often have a case that calls itself and a base case that acts as a backstop of sorts for the recursion.

Идеальное объяснение! Начинающий побежал писать рекурсивные функции.

И вот практически всё у них так. Далее идут списки, сворачивание списков, алгебраические типы данных, сорта типов, внезапно сборка проектов (Stack, реально неплохо, кстати) и модули, тестирование (c quickcheck), моноиды и полугруппы, функторы, аппликативы, монады, Foldable, Traversable, специальные монады (Reader, State), парсер-комбинаторы (70 страниц!), монадные трансформеры, нестрогость вычислений, обзор базовых библиотек, ввод-вывод (29-я глава!), обработка ошибок, финальный проект. Уфф.

По содержанию это базовый Haskell, но чрезмерно растянутый. Ну вы уже поняли. Впрочем, некоторые отдельные главы лично мне были полезны (те же проекты, неплохая глава по тестированию, обзор библиотек, исключения), остальное я читать не могу, терпения не хватает. В книге есть живые примеры, но их мало. Так, в нескольких главах показывают шаблонизатор Scotty, кое-где обращаются к JSON, но большинство примеров всё-таки бестолковые (по типу факториала и Фибоначчи), объяснение кода этих примеров авторы выдают за обучение. Не обходится без притянутых за уши эпиграфов, глуповатых заголовков и таких же шуток. Буррито упоминается в тексте семь раз. Рекомендовать кому-то эту книгу я не могу, мне жаль чужого времени.

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

--

--