Введение

Грамотное программирование — это парадигма программирования, представленная в 1984 году Дональдом Кнутом, в которой компьютерная программа представляется как объяснение принципа её работы на естественном языке, например, на английском, с вкраплениями (встроенными фрагментами) макросов и традиционного исходного кода, из которого можно сгенерировать компилируемый исходный код. Этот подход широко используется в научных вычислениях и науке о данных для обеспечения воспроизводимости исследований и открытого доступа к ним. Миллионы программистов сегодня используют инструменты грамотного программирования. Парадигма грамотного программирования, в понимании Дональда Кнута, представляет собой отход от написания компьютерных программ в порядке, определяемом компилятором, и предоставляет программистам макросы для разработки программ в порядке, соответствующем логике и ходу их мыслей. Грамотные программы пишутся как изложение логики на более естественном языке, где макросы используются для сокрытия абстракций и традиционного исходного кода, напоминая скорее текст эссе. Инструменты грамотного программирования (LP) позволяют получить два представления из исходного файла: одно, понятное компилятору или интерпретатору, – так называемый "переплетённый" код, и другое – для просмотра в виде отформатированной документации, которую называют "вытканной" из грамотного источника. Если инструменты первого поколения были ориентированы на конкретные языки программирования, то более поздние версии стали языконезависимыми и существуют вне рамок отдельных языков.

История и философия

Литературное программирование было впервые представлено в 1984 году Дональдом Кнутом, который стремился создавать программы, пригодные для чтения как литература. Он реализовал его в Стэнфордском университете в рамках своих исследований в области алгоритмов и цифровой типографии. Реализация получила название "WEB", поскольку он полагал, что это одно из немногих трехбуквенных английских слов, которое еще не использовалось в информатике. Однако это отражает сложную природу программного обеспечения, тщательно собранного из простых элементов, позволяя получить компилируемый исходный код одной командой ("tangle") и документацию – другой ("weave"). Препроцессор также предоставляет возможность выводить содержимое макросов и добавлять к уже созданным макросам в любом месте исходного текста литературной программы, тем самым избавляя от необходимости помнить об ограничениях традиционных языков программирования или прерывать ход мысли.

Контраст с формированием документации

Очень часто грамотное программирование ошибочно понимают как относящееся лишь к форматированной документации, генерируемой из единого файла, содержащего исходный код и комментарии – что корректнее называть генерацией документации, – или к обширным комментариям, включенным в код. Это прямо противоположно идее грамотного программирования: хорошо документированный код или документация, извлеченная из кода, следует структуре самого кода, с документацией, встроенной в него; тогда как в грамотном программировании код встроен в документацию, и его структура подчиняется структуре документации. Это заблуждение привело к тому, что инструменты для извлечения комментариев, такие как Perl Plain Old Documentation или Java Javadoc, стали ошибочно именоваться "инструментами грамотного программирования". Однако, поскольку эти инструменты не реализуют "сеть абстрактных концепций", лежащую в основе системы макросов на естественном языке, и не предоставляют возможности изменить порядок исходного кода с машинной последовательности на порядок, удобный для человеческого восприятия, их нельзя в полной мере считать инструментами грамотного программирования в том смысле, который вкладывал в это понятие Кнут.

Критика

В 1986 году Джон Бентли попросил Кнута продемонстрировать концепцию литературного программирования для своей колонки Programming Pearls в Communications of the ACM, написав программу на WEB. Кнут прислал ему программу для задачи, ранее обсуждавшейся в колонке (выборку M случайных чисел в диапазоне от 1 до N), а также попросил предложить "задание". Бентли дал ему задачу найти K наиболее часто встречающихся слов в текстовом файле, для которой Кнут написал программу на WEB, которая была опубликована вместе с рецензией Дугласа Макилроя из Bell Labs. Макилрой высоко оценил сложность решения Кнута, его выбор структуры данных (вариант хэш-три Фрэнка М. Лянга) и способ представления. Он критиковал некоторые стилистические моменты, такие как то, что основная идея была описана ближе к концу статьи, использование магических констант и отсутствие диаграммы, иллюстрирующей структуру данных. Макилрой также использовал рецензию для критики самой задачи программирования, отметив, что в Unix (разработанной в Bell Labs) уже существовали стандартные утилиты для обработки текста (tr, sort, uniq и sed), и решение, которое было бы легко реализовать, отладить и повторно использовать, можно было бы получить, объединив эти утилиты в скрипте оболочки из шести строк. В ответ Бентли написал, что: [Макилрой] восхищается реализацией решения, но считает задачу неудачной с инженерной точки зрения. (Это, конечно, моя ответственность как автора задания; Кнут решил задачу, которую ему дали, исходя из соображений, важных для большинства инженеров – зарплаты, которые им выплачивают за выполнение заданий.) Позже Макилрой признал, что его критика была несправедливой, поскольку он критиковал программу Кнута с инженерной точки зрения, в то время как целью Кнута было лишь продемонстрировать технику литературного программирования. В 1987 году Communications of the ACM опубликовала статью, продолжающую обсуждение, в которой литературное программирование было проиллюстрировано программой на языке C, объединяющей художественный подход Кнута и инженерный подход Макилроя, с рецензией Джона Гилберта.

Пример

Классическим примером literate-программирования является literate-реализация стандартной утилиты Unix wc для подсчета слов. Кнут представил версию этого примера на CWEB в главе 12 своей книги "Literate Programming". Позже тот же пример был переписан для инструмента literate-программирования noweb. Этот пример служит хорошей иллюстрацией основных элементов literate-программирования.

Замечательные примеры

Аксиома, разработанная на основе Scratchpad — компьютерной алгебраической системы, созданной в IBM. В настоящее время разработка ведется Тимом Дейли, одним из разработчиков Scratchpad. Axiom полностью написана в виде документированной программы.