Обновить

Итоги двух лет изучения «Structure and Interpretation of Computer Programs»

LispФункциональное программированиеПрофессиональная литератураУчебный процесс в ITЧитальный зал
Из песочницы


Я считаю, что разработка ПО в значительной степени заключается в программировании на псевдокоде. Если ты представил псевдокод, то перевести его на Python, C, что угодно — не проблема. Основная сложность заключается вот в этой концептуальной деятельности, а не в кодировании. Нужно знать, как подходить к тем или иным вопросам. Модульность, абстракция. Гибкость, надёжность, простота. Шаблоны проектирования. Юнит-тестирование. Ю ноу.

Есть на свете курс «Структура и Интерпретация Компьютерных Программ» (далее СИКП), который позиционируется как введение в Computer Science и ранее использовался в MIT для обучения первокурсников. Два года назад я с удовольствием одолел курс лекций по нему и взялся за книгу.

Сначала расскажу о хорошем. Текст повествует о штуках весьма далёких от моей ежедневной работы и позволил мне по-новому взглянуть на программирование. Функциональщина — это целый мир, живущий по своим законам. Язык Лисп очень отличается от привычного мне языка Си бешеной гибкостью за счёт динамической типизации, автоматического управления памятью, возможности переопределения чего угодно во время выполнения. У меня сформировалась более разностороннее представление о том, как в принципе можно решать разные задачи. Говоря шахматным языком, я сильно пополнил свой репертуар домашних заготовок, которые пригождаются в работе (пусть и не каждый день). Упражнения заставляли мой мозг работать (временами очень интенсивно), переосмысливать и систематизировать ранее полученные знания. В общем и целом изучение СИКП сделало меня более хорошим разработчиком, расширило мой кругозор. Уверен, я стал смотреть на разные вещи более системным и зрелым взглядом.

Книга постоянно толкала на размышления, за это ей низкий поклон. Я глубоко осознал вещи, которые вроде бы всем известны, но которые поэтому все ленятся упоминать. Например, что всё ПО сначала делается простым, а потом неизбежно усложняется ради повышения производительности. Пользователю-то плевать, сколько строк исходного кода внутри, а вот скорость имеет значение.

А что там насчёт конкретных эффектов для работы? Я стал лучше видеть недочёты во время code review (в первую очередь, своего же кода). Полюбил маленькие функции, желательно как можно более общего вида. Стал практиковать аккуратное и уместное использование макросов — иногда на Си можно осторожно сделать что-то не по правилам, и от этого все только победят. Опыт, полученный при решении упражнений из книги, помог мне в некоторых задачах по работе.

Но это одна сторона медали. Другая заключается в том, что подход этого курса к обучению можно выразить английским фразеологизмом «sink or swim». Перед тобой стоит перекладина, рядом с ней задание: подтянуться 10 раз. В принципе, этого достаточно для выполнения задачи, но нельзя сказать, что такой подход приятен. Я бы сказал, он весьма выматывает! Тебя бросают в бой полуподготовленного, и часть материала ты познаёшь не на объяснениях, а на своих ошибках. Наверное, это допустимый способ обучения высокомотивированных людей, но меня-лентяя он порядком выжал. Я с трудом терпел его на протяжении 3 глав из 5 (порой я делал паузы на несколько месяцев!), сделал упражнения в них от начала и до конца, но кажется, моё терпение исчерпано.

Например, в книге нет ни слова о том, как организовать свой рабочий процесс. Нет даже приблизительного рассмотрения таких понятий, как «отладка» (она здесь специфическая), «IDE» (они здесь специфические), «юнит-тесты», «разбиение на файлы для повторного использования». Имеются фрагменты, где разрабатывается некая сложная система, которая будет целиком готова лишь к концу главы, а задания появляются после каждого пункта текста. Т.е. строго говоря, прочитав до страницы N, ты в ряде случаев не можешь решить задачу с этой страницы, не утащив код с последующих страниц. Код нужно тащить аккуратно, ибо в примечаниях могут обсуждаться неочевидные тонкости, а порой какой-то код приводится в качестве примера неработающей идеи. Это раздражает! Да, это прям как в реальной жизни — надо самому доопределять задачу, искать что-то в интернетах, но блин… Этожучебник! Я наедаюсь непростыми задачами на работе, и может, авторам стоило более педантично подойти к тексту? Ладно я, профессиональный погромист с быстрым доступом в интернеты, а как было первокурснику MIT в восьмидесятых? Уверен, несладко…

Подчеркну главные плюсы книги: она позволяет получить личный опыт, набить свои шишки, подумать над сложными проблемами в общем виде. С ними непосредственно связаны минусы: она сложная и зачастую даёт тебе мало подсказок для понимания чего-то. Например, если ты имеешь какой-то боевой опыт, то знаешь, что код без юнит-тестов нельзя назвать решением, но книга тебе об этом не скажет. Надо самому до этого дойти! А как ты думал? Ну или вру, книга об этом скажет, но максимально садистским способом. У тебя будет следующее задание, опирающееся на предыдущее (такое там сплошь и рядом). Если у тебя раньше заработал один тестовый кейс и ты решил «Отлично, едем дальше!», то за поворотом тебя ждёт счастливая отладка решений сразу двух заданий. Наверное, когда это произойдёт несколько раз, ты поймёшь, что делаешь что-то не так. Главное, чтобы в такие моменты ты не бросал курс, а разбирался, тогда всё будет хорошо!

Ещё одна раздражающая черта текста: задания (опять же, как и в реальной жизни) порой недостаточно хорошо определены. Я на днях делал упражнение, за полчаса набросал решение, стал перечитывать формулировку задачи. Оказалось, что если рассуждать педантично, то я выполнил его на 95%, затратив примерно 40% усилий. Большинство чуваков, с которыми я сверялся, сделали так же. Один сделал полноценно, но использовал хак из другого интерпретатора Лиспа. Я огорчился и плюнул, потеряв мотивацию продолжать в ближайшее время. Ещё раз проговорю суть проблемы: есть задания, в которых всё решается просто и логично, но только если не быть к себе строгим. Так и в реальной жизни, я понимаю, но у меня были другие ожидания от учебника. Когда делаешь упражнение в свободное время и сам себя проверяешь, то хочется решить проблему на 100%, а не «достаточно хорошо для текущей итерации».

Проблема с юнит-тестами вообще-то того же рода. Иногда нужно неслабо запотеть и подумать, чтобы просто внедрить их в систему. Я-то знаю, что без них никуда, но более простые ребята просто набрасывают решения без проверки и идут дальше! Чем ты строже, внимательнее, опытнее, тем сложнее для тебя становятся задания. Иногда просто в разы! Это демотивирует, потому что тут, в отличие от работы, за это не хвалят и не платят, а итеративный подход плохо применим. Знания и умения, полезные в реальной жизни, больно бьют по рукам при решении студенческих задачек!

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

В общем и целом, я не жалею, что вписался в эту авантюру, она была для меня полезной. Тем не менее, другим людям я рекомендую поискать что-то получше. Например, на основе СИКП с учётом его ошибок (так говорят, я не проверял) недавно был сделан курс «How to Design Programs». Полагаю, стоило и мне на него позариться, но время уже не отмотаешь.

P.S. Замечательную рецензию на СИКП написал Питер Норвиг.

Оригинал опубликован в моём блоге 11.07.20.
Теги:рецензияSICPLispфункциональное программированиесамообразование
Хабы: Lisp Функциональное программирование Профессиональная литература Учебный процесс в IT Читальный зал
Рейтинг +12
Количество просмотров 5,6k Добавить в закладки 39
Комментарии
Комментарии 5

Похожие публикации

Лучшие публикации за сутки