Литературное программирование

    Не прошло и месяца как я узнал о литературном программировании, но
    сама концепция произвела на меня неизгладимое впечатление, заставила
    переосмыслить некоторые вещи и поубавить пыла на пару с максимализмом
    в некоторых суждениях. О технической стороне литературного
    программирования (я называю его литературным, а не грамотным; мне
    кажется это ближе по смыслу оригинальному названию) я видел пару
    замечательных статей в рунете, но я хочу рассказать о эмоциональной
    его стороне, надеюсь это придаст вам мотивации копнуть
    глубже. Эмоциональные слова прозвучали бы из моих уст
    несколько… по-фанбойски, так что оставлю их на потом, а сейчас
    предложу вам прочесть несколько цитат создателя методологии, Дональда
    Кнута.

    Перевод я делал с посильной подмогой Google Translate, и это мой
    первый опубликованый перевод — попрошу пинать только по делу.

    Фрагменты из статьи «Literate Programming», 1983 г:

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


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


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


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

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

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

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


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


    Это к слову о том почему многие из инструментов для ЛП имеют в своем
    названии слово web [паутина].

    Смею предположить, что такие достижения в документации возможны из-за
    опыта, который я получил в течение последних нескольких лет во время
    интенсивной разработки программного обеспечения (здесь Кнут говорит о
    разработке TeX и METAFONT). Воспользовавшись несколькими идеями, которые
    существуют уже длительное время, и систематически примененив их слегка
    по-новому, я наткнулся на метод создания программ, который чрезвычайно
    меня взволновал.

    В самом деле, мой энтузиазм настолько велик, что я должен предупредить
    читателя воспринять многое из того, что я скажу, как бред фанатика,
    который думает, что он только что обрел
    просветление. Программирование — это очень личная деятельность,
    поэтому я не могу быть уверен, что то, что работало со мной, будет
    работать со всеми. Однако этот новый подход основательно повлиял на
    мой собственный стиль, и мое волнение не утихает и поныне — уже более
    двух лет. Мне так нравится эта новая методология, что трудно
    удержаться от того, чтобы не вернуться к каждой когда-либо написаной
    мной программе и не переделать её в «литературную».

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


    Небольшой фрагмент из интервью с Дональдом Кнутом, 20 лет спустя:

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

    — Литературное программирование это очень личная вещь. Я считаю, что оно
    потрясающе, но возможно это из-за того, что я очень странный
    человек. У него десятки тысяч фанатов, но не миллионы.

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

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

    Что до меня, литературное программирование — это самая важная вещь,
    которая вышла из проекта TeX. Оно не только позволило мне быстрее и
    надежнее, чем когда-либо, писать и поддерживать программы, оно было
    одним из самых больших источников радости с 1980-ых, и временами без
    него невозможно было обойтись. Некоторые из моих главных программ,
    таких как мета-симулятор MMIX, не могли бы быть написаны с помощью
    любой другой методологии о которой я когда-либо слышал. Они были
    просто черезчур сложны для моего ограниченного мозга; без
    литературного программирования подобное предприятие просто провалилось
    бы.

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

    Из позитивного: я был приятно удивлен открыв, что правила CWEB
    (системы литературного программирования для C) уже являются
    стандартом в предустановленных программах, таких как Makefile, в
    современном Linux.


    Как по мне — я думаю, что литературного программирования очень, очень
    сильно не хватает в опенсорс-проектах и особенно в обучении
    программированию (его не применяют формально с соответсвующими
    инструментами).

    Последний год я очень пристально следил за жизнью коммунити
    лисперов-кложуристов и поглощал всю доступную в сети информацию по
    этой теме: планету блогов, твиттер, 3 вышедшие на сегодня книги. После
    достаточно плотного «погружения» в эту тему у меня появилось очень
    смутное подозрение насчет подхода к изучению языка Clojure и
    сопутствующей ему инфраструктуры. Потом я узнал о ЛП и смутное
    подозрение прояснилось. Судите сами. Сейчас в мире есть три книги о
    Clojure и их содержание очень сильно пересекается между собой,
    примерно его можно описать как 100500 слабо связаных друг с другом
    рецептов по размещению граблей предоставляемых языком данной
    конкретной версии. Прочтение всех трех книг не сделает из вас
    профессионала. Вы можете прочитать и тысячу подобных книг — мастером
    вам не стать. Все 3 книги упираются в непробиваемую стену; вы знаете
    что за стеной лежит сокровище, простое и конкретное; но вам никак не
    добраться до него через тернии разрозненных и неясных
    очертаний. Подобная техническая литература — это эссенция клипового
    мышления: как будто мне скармливают крепко завареную кашу из
    питательных и чертовски полезных кусочков, но я никогда не смогу ею
    насытиться, потому что меня кормят вторичностью, оставляя суть
    недоступной.

    Clojure, как и все лиспы по своей сути являются чрезвычайно простыми
    конструкциями. Кто-то сказал «исходник — лучшая документация»; для
    семейства этих языков это чистая правда. Фактически та часть языка,
    которая непосредственно используется пользователем, описана на самой
    Clojure в одном файле core.clj размером около 5 тысяч строк. Это
    прозрачный как слеза младенца код с комментариями из которых
    генерируется довольно простая, но качественная документация. Прочтение
    этого файла за чашкой чая будет началом того самого путешествия за
    стену клиповости к самой сути используемой технологии. Но дальнейшее
    продвижение оказывается куда более сложным — следующим на пути будут
    Java-исходники, в которых описан компилятор, транзакционная память,
    ссылки, агенты и персистентные структуры данных. И ни одного
    комментария — там сам черт ногу сломит. И ведь вещь-то совсем не
    сложная, но тех кто действительно досконально или хотя бы примерно
    знает устройство всей этой технологии до самой её основы — на порядки
    меньше тех кто изучил её до этой труднопроходимой стены.

    Другое дело TeX — славное творение великого мастера. Если хочешь стать
    настоящим техником — читаешь от корки до корки стандарт-руководство
    описаное в «TeXbook». Решил стать прожженым спецом — опять же изучаешь
    от корки до корки книгу «TeX The Program», в которой все 20000 строк
    программы TeX (TeX написан на Паскале, черт меня дери!) описаны
    простым понятным человеческим языком — это литературное произведение,
    подробное описание программы с высоты птичего полета вплоть до
    мельчайших деталей. Всё. Две книги. Альфа и Омега. Технология описана
    снизу до верху и со всех сторон — никто не скажет больше. Чтобы в
    полной мере прочувствовать методологию, я очень рекомендую взглянуть на три большие литературные программы Кнута «TeX The Program» [http://db.tt/X8debml],
    «METAFONT The Program» и «MMIXware».

    Литературное программирование это не просто еще один подход к
    документации. Оно гораздо глубже — это путь соединяющий сердца
    программы и программиста. И этот путь останется непройденным, до тех
    пор пока литературное программирование не будет применяться на
    практике.
    Поделиться публикацией

    Комментарии 22

      +5
      Для наглядности не помешала бы пара литературных листингов
        +1
        Смотрите «TeX The Program». Я когда первый раз это увидел, меня честное слово, аж на слезу пробило.
          0
          Тоже взглянул. Я правильно понял что объё коментов при таком подходе должен в разы превышать объём кода?

          Читая Ваши цитаты Кнута тое «загорелся», но увидев скока там букаф, задумался, а не противоречит ли Дядька сам себе. Ведь хорошо оформленный код, с информативными именами переменных/функций/итп по большей части вообще не нуждается в комментариях вроде…
            0
            Ведь хорошо оформленный код, с информативными именами переменных/функций/итп по большей части вообще не нуждается в комментариях вроде…


            Вы, видимо, не писали наукоёмких/вычислительных программ, где за одной страницей алгоритма может стоять одна-две статьи и страниц 20 доказательств. Конечно, для типичной энтерпрайзной лапши интерфейса к базе данных даже некоторые комментарии кажутся излишними…
              0
              Вы, видимо, не писали наукоёмких/вычислительных программ

              Ну, скажем, писал, и прямо сейчас пишу весьма сложную математическую систему (дробя код по-максимуму на простые как пять копеек (но, как наставлял дядька Айнштайн, не проще), предельно ясные функции на Scala, с однозначныи инфоративными именами и читабельной структурой).
              где за одной страницей алгоритма может стоять одна-две статьи и страниц 20 доказательств

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

              PS: Я не спорю, я рассуждаю, вполне допускаю что я, вероятно, не понимаю чего-то важного.
                0
                А как потом читать код? В средней GUI программе в общем понятно, надо искать файлы со словами вроде model и controller и читать в первую очередь их. А как читать вычислительные программмы? Можно смотреть main() и спускаться по графу вызовов, попутно пропуская тысячи строк неинтересного кода вроде парсинга входных данных или проверки их на корректность. Так может пусть лучше автор сам расставит всё в нужном порядке?
                  0
                  Литературная программа фактически пишется на смеси псевдокода и реального кода, с последующим объяснением каждой строчки такого псевдокода с помощью более подробного псевдокода и кода (запутано, но просто по сути). Причем код рассказывается и объясняется в том порядке, который удобен человеку, а он может не совпадать с порядком кода в конечном файле программы для машины, который будет сгенерирован из литературной программы.
          +5
          Завтра в своем блоге я выложу один большой наглядный листинг Emacs Starter Kit на 2000 строк, на русском, в стиле литературного программирования. ОК?
          +1
          Да, принцип озвучен, но не расталкован. Чем ЛП принципиально отличается от просто качественного документирования исходников? В чем соль?
            0
            Не уверен, что смогу сейчас правильно растолковать суть. Это статья-затравка, мотиватор чтобы посмотреть оригинальную статью Кнута «Literate Programming» и посмотреть на реальные ЛП-программы: «TeX The Program» [http://db.tt/X8debml],
            «METAFONT The Program» и «MMIXware», дальнейшие выводы можно сделать только после знакомства с примерами.
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                «Статью» если маленькая программа и «книгу» (нет, вот так: книгу; полноценную книгу для технического специалиста), если программа побольше.
              +8
              Программа подготавливается к работе. Тысячи маленьких функций заботливое суетятся, за доли секунды выделяя память, считывая конфигурацию, и прорисовывая интерфейс. Строго, но со вкусом расположенные элементы воявляются на экране. Юркие функции, закончив дело, ложатся спать. Только несколько из них остаются, чтобы следить за работой, программы и быть готовыми разбудить функции обработки формы, когда будет нажата кнопка Ок."...


              Еще листинг.

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

                0
                Бархатное… Но я всё равно не вкурил ни черта.
                  0
                  Бархатное через «о» — это фича, обусловленная спецификацией языка.
                  0
                  А первая цитата откуда? я бы почитал=)
                  0
                  примеры, блин, где???
                    0
                    Перечитай предпоследний абзац.
                    0
                    Конечно не всегда обязательно описывать действия кода художественным языком, однако идея в целом очень полезная. Проблема в том, что многие авторы программ, как например один из комментаторов, считают, что и так все ясно. Название функции и переменных, классов, как бы говорят сами за себя и очевидны. Это далеко не всегда так. Что ясно для автора, может быть совершенно не ясно другому программисту. Поэтому пояснять в идеале нужно всегда.
                    Логика программы бывает достаточно очевидна, но почему именно так, чего хотел этим достичь автор, не всегда ясно. В идеале нужно пояснять смысл программы.
                    Например есть задача обработать массив или строку определенным образом. Автор пишет, хочу обработать строку, на выходе получить другую строку такого то вида. Для этого нужно создать 2 функции, одна делает то то, другая то то. На выходе получаем то что надо. Другой, более опытный программист посмотрит такой комментарий и сразу скажет, уже есть одна встроенная функция для решения этой задачи. Более того эта функция работает оптимальным образом. В итоге ему даже не нужно разбираться в коде, он просто убирает эти 2 функции и вставляет встроенную. Полезность такого рода комментариев я думаю очевидна.
                      0
                      Вот фрагмент из программы, написанной по законам этого жанра:

                      Before opening the thin door:
                      if player wear the uniform:
                      say «Second pilot! Welcome on board!»;
                      continue the action;
                      otherwise:
                      say «For staff only!»;
                      stop the action.

                      After going to Cockpit:
                      end the game in victory;

                      After going through the metal detector:
                      if player carry id and electric switch is switched on:
                      end the game in death;
                      otherwise:
                      continue the action.

                      After taking the news paper:
                      Now the boarding pass is in the location;
                      say «The piece of paper fall down at the floor»;
                      continue the action.

                      Carry out inserting something into the slot:
                      if noun is id:
                      say «Click!»;
                      now the wood door is unlocked;
                      otherwise:
                      remove the noun from play.

                      Report inserting something into the slot: say "[if noun is not id][The noun] falls out of sight, and you know you will never see it again."

                      Instead of giving pass to Stewardess:
                      now Stewardess carries pass;
                      say «All Right, Please find your place rear of plane».

                      Instead of going from Front of Plane to Rear of plane:
                      if Stewardess carries the Boarding pass:
                      continue the action;
                      otherwise:
                      say «Stop. Give me pass»;
                      stop the action;

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

                    Самое читаемое