[Перевод] Как прорешать SICP: Отчёт о создании решебника для самого известного в мире задачника по программированию. Ботаны есть?

(Хабр-Статья представляет собой авторский перевод доклада, представленного автором на Scheme Workshop 2020, проводившегося в рамках Международной Конференции по Функциональному Программированию, 28 августа 2020 года)

Эта статья — своего рода «отчёт» по самому большому проекту, который я сделал в своей жизни по собственной инициативе. Я сделал полное и всеобъемлющее решение всех задач из одной из самых извесных книг по программированию в мире «Структура и Интерпретация Компьютерных Программ» (Structure and Interpretation of Computer Programs — SICP), за авторством Абельсона, Сассмана и Сассман.

В ходе выполнения проекте автор собрал довольно много данных о том, как решалось это задание в частности, и придумал несколько эвристик, помогающих выполнять проекты вообще, а именно:

  • Измерил полную трудоёмкость SICP (729 часов, 19 минут (больше 8 месяцев работы), распределённых по 292 учебным сессиям)

  • Сколько компьютерных языков потребовалось выучить (6)

  • Сколько программ потребовалось использовать (9)

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

В этой статье предлагается:

  • Практичный, поддерживаемый программно, протокол для решения любого вида домашней работы в электронном виде.

  • Несколько предложений по улучшению процесса преподавания любого вида технических навыков.

  • Несколько улучшений для процесса преподавания любых навыков в принципе.

Решебник доступен онлайн (в виде исходного кода, а также скомпилированного pdf):

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

  • Точечной оценки трудоёмкости набора задач SICP.

  • Раздаточный материал для студентов-первокурсников, служащий повышению мотивации к учёбе.

  • Набора данных для изучения поведенческих паттернов характерных для взрослых, занимающихся самообразованием.

  • «Практически готового» протокола для выполнения любого представимого в виде дерева подзадач курсового задания, допускающего применение данного решения при трудоустройстве в качестве портфолио.

  • «Практически готового» и «почти удобного» протокола для измерения трудоёмкости любого набора задач, представимого в цифровом виде.

Данный отчёт подготовлен таким образом, чтобы анализ данный, произведенный по результатами измерения времени, был воспроизводим на машинах, поддерживающих org-mode.
(См приложение: «Код для анализа данных на Emacs Lisp» в английской версии доклада.)

Введение

Учебники программирования не часто сами становятся предметом изучения. Их задача — обучать, а не быть изучаемыми. С другой стороны, преподавателям часто требуется разрабатывать курсы для своих учебных заведений, и им требуется на что-то опираться. Чаще всего, в качестве начального курса программирования выбирается изучение синтаксиса какого-нибудь одного языка программирования, выбранного случайно или согласно веяниям моды.

Однако, были попытки сделать дизайн вводного курса в программирование более систематическим. «Структура и Интерпретация Компьютерных Программ» была написана в результате одной из таких попыток. SICP был революционным уже в годы написания первого издания, и можно сказать, что остаётся революционным до сих пор. Через двадцать лет после выхода первого издания, его практическая применимость книги была проанализирована Маттиасом Феллейсеном в статье «Stucture and Interpretation of Computer Science Curriculum». (См библиграфию) В ней рассматриваются плюсы и минусы курса, целенаправленно разработанного по всем правилам педагогического подхода. В ней же он предлагает то, что по его мнению, является «вторым поколением», продолжающим развитие этого «педагогического подхода». (См «How To Design Programs» Felleisen 2018)

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

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

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

Решебник был структурирован, разбит на части, оснащён программной системой для решения задач, и написан автором сего текста в полном объёме. Тем самым, декларируемая цель была достигнута, а трудоёмкость измерена.
Данные по измерениям находятся в общем доступе. (Прим. к русскому переводу: поскольку данные очень объёмны, в русском переводе они отсутствуют. Предлагается обратиться к английской версии.) Читателям, занимающимся преподаванием профессионально, предлагается в будущем разрабатывать курсы с учётом результатов, полученных в этой работе.

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

Подход к решению

Автор считает, что хороший решебник должен удовлетворять следующим принципам:

  1. Быть полным.

  2. Представлять собой достаточно реалистичную модель процесса решения задач, как будто бы если она осуществлялась целевой аудиторией курса: студентами начальных курсов высшего учебного заведения с небольшим опытом программирования, скорее всего, полученного в школе.

  3. Быть полностью цифровым, написанным в цифровом субстрате изначально.

  4. Быть измеримым.

В следующем параграфе рассмотрим подробнее, что имеется в виду.

Что имеется в виду под полнотой?

Что значит «решить все задачи курса»?

Автор этих строк считает, что полнота освоения материала — необходимое условие прохождения любого курса обучения чему-либо.

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

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

Ниже представлены потенциальные ответы на этот вопрос, как они придуманы автором этого текста:

  • Сдать устный экзамен.

  • Сдать письменный экзамен.

  • Пройти процедуру защиты проекта перед советом (научным, диссертационным).

  • Успешно выполнить требуемое количество задач в рамках системы непрерывной оценки. (Примерно так, как это делается в начальной школе.)

  • Решить «большое домашнее задание». (Как это принято в МФТИ.)

  • Посетить определённое количество учебных сессий (лекций или семинаров).

  • Прочесть определённое количество учебного материала.

Всё вышеперечисленное, в некой комбинации, может быть объявлено «достаточным» для признания курса «освоенным», то есть перед нами задача из класса «goal attainment». (См: Gembicki 1975) Такие задачи, однако, всё равно решаются путём сведения многих целей к некоторой обобщённой «единой» цели.

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

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

Выбор книги, посвящённой программированию, которая обязана своей известностью включённому в неё задачнику даже более, чем основному тексту, был довольно естественным.

Однако, нельзя сказать, что «решить все задачки из книжки» — это достаточное условие для того, чтобы утверждать, что «материал освоен».

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

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

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

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

Качественная имитация университетского опыта.

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

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

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

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

Более того, имеющиеся данные подсказывают, что для студентов в верхней квартили успеваемости, корреляция посещаемости с оценкой невелика. (См St_Clair 1999 A case agains compulsory class attendance policies in higher education и Kooker 1975 Changes in grade distributions associated with changes in class attendance policies)

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

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

Мета-когнитивные упражнения

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

Основная мысль этого абзаца в том, что преподавание — это не просто процесс передачи данных.
Это еще и процесс передачи метаданных, и развития метакогнитивных навыков. (См Ku 2010 Metacognitive strategies that enhance critical thinking)
Следовательно, передача метакогнитивных навыков, хотя она и является важной составляющей частью обучения, и выполняет важную роль в обучении студента «думать», заслуживает отдельного рассмотрения при написании курсов.

Примерами метакогнитивных упражнений являются:

  • Предъявление материала не согласно «естественному порядку», таким образом, чтобы более ранние (по порядовому номеру) задачи были неразрешимы без предварительного разрешения задач, более поздних по номеру или номеру главы.

  • Сознательная неполнота изложения материала.

  • Немногословность изложения, отсутствие предварительно заложенного дублирования материала во имя повторения пройденного.

  • Отсутствие готового предложения программного обеспечения, поддерживающего излагаемый материал.

  • Отсутствие оценки сложности или трудоёмкости для предлагаемых задач.

  • Демонстративно неравномерное распределение сложности задач.

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

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

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

Личный опыт автора был таков:

  • IRC-канал irc: irc.freenode.org/#scheme был основным местом для задавания вопросов в режиме реального времени. Канал #emacs также был очень полезен.

  • http://StackOverflow.com использовался для задавания вопросов асинхронно.

  • The Scheme Community Wiki http://community.schemewiki.org активно использовалась как дополнительный учебный материал.

  • Автор так же напрямую посылал сообщения по электронной почте многим участникам сообщества Scheme.

  • Автор нашёл некоторое количество ошибок в документах, созданных в рамках процесса по работе с сообществом Scheme.

  • Автор задавал вопросы в списке рассылки Chibi-Scheme.

  • Автор получил некоторое количество помощи на Slack-чате Open Data Science.

  • Автор получил некоторую помощь от членов сообщества Closed-Circles.

  • Автор получил помощь от сообщества rulinux@conference.jabber.ru.

  • Автор получил помощь от членов Shanghai Linux User Group.

  • Автор получил помощь от участников онлайн-сообщества «научный форум» http://www.dxdy.ru.

  • Автор получил помощь от группы в Telegram, посвящённой изучению Haskell.

Следует заметить, что среди вышеперечисленных средств поддержки, только Open Data Science и группа, посвящённая Haskell, хостятся на «модных» платформах.

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

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

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

Помощь и поддержка, требуемые проектом по написанию решебника для SICP в цифрах:

  • Email-цепочек в списках рассылки, посвящённых компиляторам и интерпретаторам Scheme: 28.

  • Email-цепочек в списках рассылок, посвящённые IDE, текстовым редакторам и сообщениям об ошибках в них: 16.

  • Email-цепочек, посвящённых форматированию и оформлению: 20.

  • Email-цепочек, посвящённых непосредственно задачнику: 3.

  • Цепочек, посвящённых документации и ошибкам не в ней (а также отчётам от битых ссылках): 16.

  • Сообщений в IRC: 2394 сообщений, написанных автором на профильном канале.

  • Проектов, восстановленных на Software Forges (таких как Github), из архивов исходных авторов: 2.

В силу закрытости, идиосинкратичности, и нестандартизированности иных средств общения, таких как Slack, статистика по иным каналам общения не собиралась, но общение в них не было очень объёмным.

Перерисованные иллюстрации

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

Список иллюстраций:

  • 1.1 Древовидное изображение формулы, включая значение всех под-комбинаций.

  • 1.2 Разбиение программы, вычисляющей квадратный корень, на процедуры.

  • 1.3 Линейный рекуррентный процесс.

  • 2.2 Box-and-pointer представление ~(cons 1 2)~.

  • 2.8 Решение задачи о восьми ферзях.

  • 3.32 Процедура интегрирования, представленная как система обработки сигналов.

  • 3.36 RLC схема.

  • 5.1 Пути распространения данных в регистровой машине.

  • 5.2 Контроллер для машины, вычисляющей НОД.

Моделирование поведения, «вроливание» и выбор инструментов

Биография автора сего текста

Перед началом выполнения настоящего проекта, у автора уже была степень кандидата наук в Информатике, хотя и не в промышленном программировании.
Без сомнения, у автора было преимущество перед первокурсником.
Тем не менее, в значительно степени, опыт представляется релевантным, поскольку до момента начала выполнения задач, автор никогда не пользовался функциональными языками программирования, и редакторами программного кода более совершенными, чем Notepad++. Другим важным отличием от типичного первокурсника было то, что автор уже умел печатать десятью пальцами (так называемым, слепым десятипальцевым методом). Этот навык преподаётся в средних школах в США однако, всё ещё не является обязательным в большей части мира.

Замечание: данные, представленные в данном отчёте в большой степени зависят от навыка скоропечати слепым методом, и скорее всего, итоговая трудоёмкость для студентов, не владеющих методом слепой печати, окажется в константу раз выше. При отсутствии у студентов навыка скоропечати, измерения из данного отчёта невозможно брать за основу при оценке сложности разрабатываемого курса, а выбор инструментов может показаться странным.

Цель, которую автор поставил перед собой, была в какой-то степени противоречива, так как «модельный» студент, поведения которого автор старался придерживаться, не существует. Таковое поведение заключается в:

  • Выполнении всех упражнений честно, не обращая внимания на то, сколько времени они потребуют.

  • Не жульничать при выполнении упражнений (однако, консультироваться с решениями других студентов не запрещалось в той степени, в которой это не было прямым списыванием). Использовать инструменты, которые могли бы быть доступны студенту в 1987 году, хотя, возможно в современных версиях.

  • По возможности, следовать методологии «Свободного программного обеспечения, Программного обепечения с открытым кодом, и Unix-way», в формулировке широко известных организаций.

  • Попытаться подготовить «решение задач» в формате, потенциально применимом для «сдачи» в университете.

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

Интересно, что личный опыт автора в университетском программировании большей частью был посвящён отладке процедур ввода-вывода.
На втором месте по трудозатратности была задача написания тестов.
Собственно решение программистских задач было только на третьем месте по трудоёмкости.

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

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

Противоречивость модели «идеального студента» выражается в необходимости сочетать две модели поведения, характерные для студентов. Одна представляет собой «ленивого» студента, который работал бы в той степени, в которой это необходимо, для того, чтобы «сделать курс», и не более того. Эта модель отвечает за то, чтобы затратить на проект минимально возможное время, и за то, чтобы выбрать такие инструменты, которые сделают процесс «сдачи задания» минимально времязатратным. Другая же модель отвечала «трудолюбивому» студенту, который был бы счастлив изучить материал настолько глубоко, насколько это возможно, и возможно, никогда курс не закончить, «потерявшись» в какой-нибудь наиболее интересной задаче, и должна была отвечать за качество работы, и за выбор наиболее «правильных» инструментов.
Таковые две модели студенческой мотивации в каком-то смысле отвечают концепции «Theory X and theory Y», предложенными McGregor ([[cite: mcgregor:1960: theory_x_and_theory_y]]).

Попытаемся представить себе «идеального студента», смесь двух вышеуказанных моделей, и попробуем принимать решения так же, как это делал бы он.
Неформально говоря, попробуем вести себя как «Я выучу все инструменты, которые потребуются для того, чтобы сделать работу, в том объёме, который потребуется, но не более того».
(Существуют намного более качественные модели поведения студентов, многие с применением математического моделирования (например Hlosta 2018 Modelling student online behaviour in a virtual learning environment), однако данная простая модель казалась достаточной при выполнении данного проекта.

Выбор инструментов

Конечный набор инструментов, применявшийся при выполнении проекта, следующий:

  • Chibi-Scheme: реализация языка Scheme

  • srfi-159:: инструмент для pretty-printing

  • srfi-27:: библиотека случайных чисел

  • srfi-18:: библиотека для работы с потоками

  • (chibi time) :: библиотека для работы с временем и датой

  • (chibi ast) :: (строго говоря, не требующаяся для решения) библиотека для работы с абстрактным синтаксическим деревом языка и экспансии макросов

  • (chibi process) :: вызова ImageMagick

  • GNU Emacs: в качестве IDE

  • org-mode: в качестве основного носителя рабочих данных и в качестве основного инструмента для управления проектом

  • f90-mode: как IDE для низкоуровнего языка

  • geiser: расширение для Emacs для работы с Scheme, оказался неготовым к серьёзному применению, однако, оказался также полезен для выполнения небольших кусков кода

  • magit: как графический инструмен для git

  • gfortran: как низкоуровневый язык

  • PlantUML: как язык рисования диаграмм первого выбора

  • TikZ + luaLaTeX: как язык рисования диаграмм «второго выбора»

  • Graphviz: как язык рисования диаграмм «третьего выбора»

  • ImageMagick: как основной бэкэнд для написания реализации графической библиотеки

  • git: как инструмент для контроля версий

  • GNU diff, bash, grep: как инструменты для работы с текстом

    (Список инструментов, который потребовалось освоить для решения SICP)

Chibi-Scheme была, по сути, единственной реализацией Scheme, поддерживающей самый свежий стандарт языка, r7rs-large (Red Edition), так что выбор был очевиден.
Выбор становится ещё более очевиден, если представить себя на месте студента, не желающего вдаваться в особенности тех школ мысли, которые привели к созданию огромного разнообразия различных реализаций Scheme, не до конца совместимых со стандартом.
Несколько библиотек, три из который стандартизированы, а три нет, потребовались для полного решения всех задач.
Невозможно решить все упражнения из задачника, пользуясь только стандартным языком Scheme.
Даже Scheme, вместе со всеми возможными расширениями языка, всё ещё недостаточно.
За пределами стандартных инструментов, потребовалась одна нестандартная библиотека, (chibi process), послужившая мостом к графическому интерфейсу.

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

ImageMagick оказалась самым простым способом создания изображений, состоящих их простых прямых линий.
Не существует стандартного способа связать приложения на Scheme с приложениями, написанными на других языках.
Согласно принципу минимального выхода за пределы курса, ImageMagick был выбран, как требующий одной-единственной нестандартной процедуры.
Более того, эта процедура, (простой синхронный вызов другой программы), вероятно вообще самый простой примитив для кооперации программ из когда-либо изобретённых.
Практически все операционные системы поддерживают запуск одними программами других программ.

PlantUML — это реализация международного стандарта визуализации программ.
Её синтаксис незамысловат и хорошо документирован.
Интерфейс PlantUML-Emacs существует и относительно надёжен.
Текстовое представление воплощает в себе дух хакерства, и сильно упрощает контроль версий.
UML практически полностью доминирует на рынке визуализации программ, и практически любая университетская программа включает его, до какой-то степени.
Соответственно, автору показалось очень естественным решать те диаграммные задачи из SICP, которые допускали представление в виде UML, в PlantUML.

Применение Graphviz также являлось попыткой использовать (на этот раз уже другой) индустриальный стандарт для решения тех графических задач, которые не допускали решения в виде UML.
Язык ~dot~ хорошо разбирается машинным способом, и даже менее зависит от контекста, чем UML. Однако, на практике он оказался менее удобным.

TikZ — это практически единственный язык рисования общего назначений.
В тех задачах, в которых общность модели изображений была шире, чем позволяют нарисовать UML и Graphviz, автор использовал TikZ.
Довольно естественным выбором было бы рисовать требуемые изображения при помощи инструмета с графическим интерфейсом, такого как Inkscape или Adobe Illustrator.
Однако, одна из проблем с изображениями, создаваемыми при помощи таких инструментов состоит в том, что они плохо обрабатываются системами контроля версий.
Вторая проблема заключается в том, что автору хотелось сохранить все результаты курса в одном цифровом артефакте (грубо говоря, в одном файле). Упаковка решения в один файл уменьшает путаницу, вызываемую большим количеством версий одного кода, делает поиск в коде намного более простой задачей, а также упрощает презентацию решения потенциальному экзаменатору.

gfortran, он же GNU Fortran, был выбран в качестве низкоуровнего языка для решения последних двух задач в задачнике.
Причины выбрать такой не самый популярный язык были следующими:

  • Автор уже знал язык Си, то есть имел преимущество перед гипотетическим «студентом-первокурсником».

  • Фортран достаточно низкоуровневый для решения низкоуровневых задач из SICP.

  • Существует свободная реализация Фортрана.

  • Фортран 90 уже существовал во время выпуска второго издания SICP. was published.

GNU Unix Utilities автор изначально не планировал использовать, однако~diff~ оказался очень полезным для иллюстрации разницы между двумя кусками кода в Главе 5. Они так же оказались полезными в качестве «клея», для соединения разных программ в единую систему.

GNU Emacs де факто является самой популярной IDE среди пользователей Scheme, это IDE используемая основателями Free Software Foundation, среди которых и авторы SICP, и, вероятно, использовался в качестве текстого редактора для написания SICP, также с большой вероятностью может быть выбран студентом-первокурсником из-за его ассоциации с «хакерской» субкультурой.
Это, вероятно, не очевидный выбор, поскольку на протяжении многих лет одной из самых популярных сред разработки среди первокурсников являлась Microsoft Visual Studio.
Другим возможным выбором был бы Dr. Racket, в который библиотеки, необходимые для прохождения SICP включены в поставку по-умолчанию.
Однако, для любителей Lisp, и для продвинутых студентов, Emacs всё ещё является популярным выбором, и поддержка Lisp в нём хороша, хотя для Scheme и не так хороша, как можно было бы подумать.
Наличие org-mode оказало решающее влияние на выбор Emacs, и она заслуживает отдельной подглавы.
Говоря неформально, выбор платформы Emacs в качестве главной операционной среды для работы на ЭВМ, оказался настолько важным, что полностью преобразил вообще всю парадигму в которой автор этого отчёта работает с вычислительными устройствами.
Кривая обучения для Emacs, без сомнения, очень крута.

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

© Habrahabr.ru