Текст книги "Кодеры за работой. Размышления о ремесле программиста"
Автор книги: Питер Сейбел
сообщить о нарушении
Текущая страница: 8 (всего у книги 41 страниц) [доступный отрывок для чтения: 15 страниц]
Крокфорд: На самом деле все не так. Есть разработчики Ajax-библиотек, которые достигли немалой изощренности во владении языком. А есть сообщества разработчиков, которые делают черт знает что с помощью этих библиотек, и это работает. Для создателя приложений совсем не обязательно знать все свойства лямбда-выражений, чтобы извлекать из них пользу. Совсем не обязательно отказываться от языка, пытаясь исправить его ошибки.
На самом деле проблема в том, что Ajax-библиотек стало слишком много. Это следствие того, что JavaScript – очень мощный язык, потребность в подобных библиотеках очень высока, а создавать их относительно легко. Поэтому в течение какого-то времени все их и писали. Я жду, что их станет меньше, но пока напрасно. Из-за этого у нас сейчас другая проблема – библиотек столько, что разработчики не знают, какую выбрать. Думаю, все же в будущем их количество уменьшится.
Сейчас заметна тенденция сближения функциональности Ajax-библиотек. В j Query можно получить список объектов из DOM с помощью CSS-ceлекторов и затем управлять группой объектов. Это оказалось действительно хорошей идеей – вот пример того, как JavaScript кое-что делает эффективно. Да, интерфейс взаимодействия с DOM просто ужасен, но он скрыт полностью. Разработчики jQuery очень упростили программную модель и сделали это блестяще.
А теперь каждая библиотека делает то же самое – мы наблюдаем сближение функциональных возможностей. Для пользователей проблема встает еще острее, так как все труднее выбрать нужную библиотеку, поскольку все они становятся очень похожими. Но в конце концов они начнут объединяться, и в результате останется всего несколько библиотек, возможно всего одна. Думаю, одним из победителей будет Microsoft с ее библиотекой Atlas, просто потому что Microsoft всегда оказывается среди победителей. Но, по-моему, у них нет достаточной поддержки. Открытые фреймворки, похоже, намного эффективнее. Думаю, в конце концов победит один или два открытых фреймворка.
Сейбел: Сегодня вы архитектор и евангелист языка JavaScript в Yahoo!, поэтому часть вашей работы, по-видимому, в том, чтобы говорить JavaScript-программистам в Yahoo!: «Делайте так-то». Обязаны ли вы также анализировать код и проекты на соответствие общепринятым практикам кодирования и проектирования?
Крокфорд: Я всегда настаиваю на необходимости чтения кода. Думаю, чтение кода – самое полезное, что программисты могут сделать друг для друга: постоянно уделять часть своего времени чтению кода коллег. При управлении проектами программистов часто предоставляют самим себе, затем всю их работу объединяют, и если результат удается скомпилировать, то полученный продукт выпускают на рынок и забывают о нем.
Это приводит к тому, что если у вас в команде есть слабые или неуверенные в себе программисты, то это обнаруживается слишком поздно. В результате возникает риск того, что в проекте будет множество низкокачественных компонентов, которые приведут к срыву сроков, что неприемлемо. Кроме того, у вас могут быть блестящие программисты, которые оказываются недостаточно хорошими руководителями для других членов команды. Чтение кода решает обе эти проблемы.
Сейбел: Давайте поговорим о том, как читают код у вас.
Крокфорд: На каждом совещании есть ответственные за чтение кода: они разбирают и проверяют код под наблюдением остальных. Это отличная возможность для каждого понять, как его фрагменты кода будут согласовываться с фрагментами других.
Мы садимся за стол, перед каждым лежит стопка бумаг. Мы выводим код на экран и комментируем его по ходу чтения. Кто-то говорит: «Я не понимаю этот комментарий» или «По-моему, этот комментарий не описывает этот код». Это очень важно, поскольку как программист вы перестаете читать свои комментарии, не сознавая, что другому что-то может быть непонятно. Прекрасно, когда коллеги по проекту помогают поддерживать ваш код в чистоте – вы находите ошибки, которые никогда бы не нашли самостоятельно.
Думаю, час чтения кода полезнее двух недель работы тестировщиков. Это действительно эффективный способ устранения ошибок. Если у вас есть человек с большим опытом чтения кода, то новички благодаря ему узнают много такого, чего иначе не узнали бы; если же чтением занимаются новички, то код сможет дать им немало очень ценных советов.
И не нужно оставлять это на заключительный этап работы. Раньше мы откладывали чтение кода до завершающего этапа работы над проектом и никто не делал это постоянно, просто потому что мы опаздывали с выпуском проекта. Теперь я считаю, что чтением кода нужно регулярно заниматься в течение всей работы над проектом. Да, на чтение кода уходит время, но это дает множество преимуществ.
В частности, это облегчает контроль выполнения проекта, поскольку мы видим прогресс каждого участника, что позволяет довольно рано заметить, если мы вдруг начнем сбиваться с намеченного пути.
Я управлял проектами, в которых незадолго до срока сдачи люди говорили: «Все практически готово», – а затем я смотрел их код, но там еще ничего не было или была полная ерунда, или он был очень далек от завершения. Жуткое испытание для руководителя проекта, и я думаю, что чтение кода как раз помогает избежать подобных ловушек.
Сейбел: Допустим, мы читаем мой код. Выводим код на экран – и что дальше? Я буквально читаю код вслух?
Крокфорд: Да, строку за строкой, параллельно его комментируя. Именно так все и должно происходить. Когда есть время, мы читаем код построчно.
Сейбел: Вам приходилось обучать людей чтению кода? Думаю, непросто найти хороший компромисс – сделать достаточно критических замечаний и при этом не задеть самолюбие автора кода.
Крокфорд: Да, здесь требуется взаимное доверие между членами команды, и нужны четкие правила насчет того, что допустимо, а что нет. В неслаженной команде чтение кода приведет к тому, что участники просто разорвут друг друга на части. То есть в процессе чтения кода очень быстро выясняется, слаженная команда или нет. При чтении кода вы можете многое узнать и многому научиться. Поначалу процесс может казаться неестественным, но стоит войти в ритм, как это ощущение пройдет.
Другой момент: нужно писать код так, чтобы другие смогли его прочитать. Здесь важны ясность кода и стиль его написания. Благодаря этому будет постепенно улучшаться качество кода и компетентность команды в целом.
Сейбел: Что для вас делает код читаемым?
Крокфорд: Читаемость складывается из нескольких уровней. Самое простое: нужно быть последовательным в оформлении кода, всегда использовать одинаковые отступы, расставлять пробелы во всех нужных местах. У меня есть дурная привычка, приобретенная еще во времена программирования на Фортране: я использую слишком много однобук-венных переменных, а это нехорошо. Я очень стараюсь избавиться от этой привычки, но это трудно сделать.
Сейбел: Насколько это трудно? Вы пишете код, а затем перечитываете его и думаете: «Боже! Только посмотрите на все эти однобуквенные переменные!»?
Крокфорд: Я мыслю однобуквенными выражениями. Кроме того, в JavaScript есть неоспоримый аргумент, связанный с эффективностью: за скачивание лишних символов вы платите, а более короткие имена переменных помогают сделать программу компактнее.
Сейбел: Для этого есть специальные инструменты?
Крокфорд: Да, можно применить gzip – и готово, так что у меня нет оправдания. Если, просматривая свой старый код, я вижу слишком короткие имена, то при наличии времени я их исправляю. Некоторые переменные, вроде счетчиков цикла, я всегда называю i. He думаю, что когда-то стану исправлять и это. Для многих переменных длинные имена просто неоправданны.
Это первый уровень, грамматический. Как в естественных языках, английском или любом другом. Исправляешь пунктуацию, написание заглавных букв, расставляешь запятые в нужных местах. Затем начинаешь обращать внимание на более высокоуровневые вещи, такие как построение предложений, разбивка на абзацы. В языках программирования этому соответствует то, как задача разбита на набор функций или классов.
Сейбел: На какие конкретно вещи должен обращать внимание разработчик, чтобы его код легко читался?
Крокфорд: Действительно важно использовать определенное подмножество языка, особенно в JavaScript, где есть огромное количество неудачных возможностей. Но это актуально для всех языков. Будучи начинающим программистом, я читал руководство по языку программирования и старался понять каждую возможность. И то, как все их использовать. И постоянно использовал все эти возможности. А потом оказывалось, что многие из них были не самыми удачными.
Вспоминается Фортран, но это справедливо для всех языков. Иногда авторы языка допускают ошибки. С моей точки зрения, в языке Си полно ошибок.
Сейбел: Каких, например?
Крокфорд: Например, оператор switch изначально является неудачным, не нужно было делать его таким. У оператора ++ огромные проблемы в смысле безопасности, поскольку он провоцирует вас на разные хитрости и попытки сделать слишком многое в одной строке кода. В результате код становится трудным для понимания, что часто приводит к различным ошибкам, таким как переполнение буфера. Так что большинство проблем безопасности, которые мы наблюдаем в операционных системах последние пять лет, связаны с использованием оператора ++.
Обычно я вообще не использую оператор ++. Бывает, его можно использовать, но чаще нет, и мне трудно различить эти случаи в своем коде.
Сейбел: Но ведь можно возразить, что проблемы безопасности, связанные с оператором ++, возникают не из-за самого оператора ++, а из-за отсутствия проверки выхода за границу массива или из-за проблем с обычными указателями. В Java нет подобных проблем с безопасностью, поскольку если есть оператор ++ и происходит выход за границу массива, то получается исключение.
Крокфорд: Да, в Java это менее опасно. А в JavaScript такой опасности совсем нет, поскольку там отсутствуют массивы. Но в любом случае, отказавшись от этого оператора, я заметил улучшение качества моего кода, просто потому что перестал записывать выражения в одну строку.
Другой пример – оператор continue. Я еще не встретил ни одного фрагмента кода, который не смог бы улучшить, выкинув оператор continue. Да, с его помощью легче создать какую-то сложную конструкцию. Но я заметил, что всегда могу улучшить эту конструкцию, найдя способ выкинуть его. Так что лично я никогда не использую оператор continue. Если же я вижу continue в своем коде, значит, что-то недодумал.
Сейбел: Как вы читаете чужой код?
Крокфорд: Путем чистки: я переношу его в текстовый редактор и начинаю править. Начинаю с пунктуации и отступов. У меня есть для этого специальные программы, но я предпочитаю делать это вручную, поскольку так ближе знакомишься с кодом. Этому меня научил Мор-нингстар. Он блестяще проводил рефакторинг чужого кода, всегда применял этот подход и доказал его эффективность.
Сейбел: Вам встречался код, который поначалу выглядел сумбурно, но после чистки вы понимали, что на самом деле он хорош?
Крокфорд: Нет, такого никогда не случалось. Мне кажется, очень сложно небрежно написать хороший код (под хорошим кодом я понимаю читаемый). На этом уровне совершенно неважно, что означает этот код для машины, если я не могу понять, что он должен делать; он может оказаться удивительно эффективным, или компактным, или потрясающим еще в каком-то смысле, но это уже неважно.
Сегодня читаемость кода – мой главный приоритет. Она важнее эффективности и почти так же важна, как корректность, и я думаю, что читаемость кода – важнейший шаг к его корректности. А если код тяжело читать, то, по-видимому, разработчики выбрали неверные компромиссы, и нельзя этот код назвать хорошим.
Сейбел: А как насчет глубоко вложенного цикла, который должен выполняться невероятно быстро? Должен ли весь код быть читаемым – или иногда читаемость можно принести в жертву эффективности?
Крокфорд: Думаю, иногда можно пожертвовать читаемостью, но в таком случае я пишу целый роман, по обе стороны этого блока кода, с объяснением того, почему мы делаем то, что делаем. Обычно это упускают из виду. И я не раз видел, как люди боролись за эффективность, когда это совершенно не требовалось. Они не знали, на что тратит время их собственная программа, и оптимизировали код, не требующий оптимизации, поскольку он никогда не изменится настолько, чтобы его выполнение существенно влияло на общую производительность. От такой оптимизации нет никаких выгод или преимуществ, она лишь вносит дополнительный хаос. Я неоднократно встречал такое.
Сейбел: В языках программирования с фигурными скобками программисты ведут бесконечные холивары («священные войны») по поводу того, где расставлять эти скобки, доказывают, что тот или иной стиль делает код более читаемым. Занимаясь чисткой кода, вы приводите его в форму, облегчающую восприятие?
Крокфорд: Непременно – ведь я считаю, что использую единственно правильный способ форматирования! Полагаю, Томпсон и Ричи оказали всем плохую услугу, не определив стандарты оформления кода для языка Си. Они сказали: «Мы используем такое оформление, а вы можете оформлять код как-то иначе», – и тем самым сильно навредили человечеству: теперь, возможно, люди всегда будут использовать только их версию.
Сейбел: То есть вы предпочитаете стиль отступов K&R[40]40
K&R – стиль оформления кода с помощью отступов, названный так в честь Брайана Кернигана и Денниса Ричи, поскольку все примеры кода в их книге «Язык программирования Си» отформатированы подобным образом. Основной отступ состоит из 8 (реже 4) пробелов (или одной табуляции) на уровень вложенности. – Прим. науч.ред.
[Закрыть]?
Крокфорд: Да, думаю, Керниган и Ричи сделали все правильно и их исходный стиль правилен. В особенности это касается JavaScript. JavaScript вставляет точки с запятыми, и во многих местах смысл программы резко меняется в зависимости от того, слева или справа вы поставите скобки. Стиль K&R не страдает этим недостатком, в отличие от стиля без отступов.
Уверен, что для JavaScript это абсолютно правильный способ расстановки скобок. Но не могу сказать то же самое о других Си-подобных языках. Некоторым нравятся скобки без отступа, и я видел, как люди часами спорят о том, какой стиль правильнее. При этом оппоненты не воспринимают доводы друг друга, поскольку каждый защищает стиль, который использовал в школе, или на своей первой работе, или стиль, который применял тот, кто произвел на него впечатление, так что теперь ему нравится именно этот стиль, а все другие кажутся неправильными.
Это примерно то же, что спорить о достоинствах левостороннего и правостороннего движения. Разумных доводов в пользу того или другого нет. Если вы живете на необитаемом острове, то можете ездить как угодно, но общество определенно выиграет, если все будут ездить по одной стороне.
Сейбел: Если вам предложат новую работу, где надо программировать на Си или Java не в том стиле, какой вы предпочитаете, как вы поступите? Скажете: «Хорошо, я перейду на ваш стиль. Уверен, что вскоре буду этому рад»? Или откажетесь от такого предложения?
Крокфорд: Может быть, стоит всегда замечать, какой стиль принят в том или ином месте? Правостороннее или левостороннее там движение? И не соглашаться на работу там, где ездят не по той стороне дороги. Как в сказке Доктора Сьюза, настроение зависит от того, есть ли у тебя на животе звезда. В конце концов приходится перейти на принятый в компании стиль, в надежде, что люди, принявшие этот стиль, знали, что делают. Но если и не знали, неважно. Важнее, чтобы все шагали в ногу.
Сейбел: Итак, чистку кода вы начинаете с оформления. Насколько глубоко или существенно вы перерабатываете код?
Крокфорд: Я переупорядочиваю код так, чтобы объявление и инициализация каждой переменной были размещены непосредственно перед ее использованием. Отдельные языки допускают при этом некоторую гибкость, так что это не всегда необходимо. Но мне такая гибкость не нужна.
Сейбел: Значит, вы против предварительного объявления ?
Крокфорд: Да, против. Или, по крайней мере, предварительное объявление должно быть явным. Я против того, чтобы код располагался в произвольном порядке, кроме случаев литературного программирования (literate programming), когда я изменяю порядок кода для его наглядности, отказываясь от привязки к требованиям языка, – и мне это очень нравится. Но без специальных инструментов лучше это не делать.
Сейбел: В одном из интервью вы цитировали Исход, 23:10-11: «Шесть лет засевай землю твою и собирай произведения ее, а в седьмой оставляй ее в покое», – утверждая, что каждый седьмой цикл следует посвятить чистке кода. Какой разумный временной промежуток вы имели в виду?
Крокфорд: Шесть циклов – это циклы между выпусками чего-либо. Если вы выпускаете новую версию ежемесячно, то каждые полгода следует пропускать один цикл выпуска, посвятив это время чистке кода.
Сейбел: То есть, не делая это через каждые шесть циклов выпуска, можно столкнуться с необходимостью серьезного переписывания кода. А как вы определяете, что настало время для серьезного переписывания, – если с вами такое бывало?
Крокфорд: Обычно команда знает, когда пора этим заняться. Руководитель проекта понимает это гораздо позже. Работа замедляется, ошибок становится слишком много, код становится слишком большим и медленным, команда не укладывается в сроки. И все знают, почему. Не потому, что все внезапно поглупели или обленились, а потому, что кодовая база больше не отвечает своим задачам.
Руководителю очень сложно это увидеть, особенно если он не программист. Но даже для руководителя-программиста это очень непростая задача, поскольку к этому времени сделано слишком много вложений. Начать заново – значит вернуться назад и проделать тот же путь. Но это невозможно, поскольку мы не будем двигаться вперед. Поэтому они говорят: «Нет, будем двигаться вперед с тем что есть».
Ошибочно считать, что во второй раз будет затрачено столько же времени, сколько и в первый раз, хотя есть и противоположные примеры. Это так называемая проблема второй системы: когда те, кто уже чего-то достиг, получают задание начать все с чистого листа и делать то, что считают нужным. Обычно это ведет к провалу, поскольку люди становятся слишком амбициозными в своих целях и не видят границ. В результате вы не получаете ничего. Нужна невероятная дисциплина, чтобы можно было сказать: «Нет, мы не начинаем с чистого листа, а заново реализуем то, что уже сделали ранее; давайте делать то, что мы уже знаем».
Одна из главных трудностей программирования в том, что мы обычно занимаемся тем, чем никогда прежде не занимались. Если мы имеем дело с чем-то, что уже делали, то используем это повторно. Но в основном мы делаем то, чего никогда раньше не делали. А создавать что-то, чего никогда не делал, сложно. Заниматься этим очень интересно, но весьма непросто. Особенно когда работаешь по классической методике и должен классифицировать систему, которую до конца не понимаешь. В этом случае очень высока вероятность сделать неправильную классификацию.
Сейбел: Под «классической» методикой вы подразумеваете применение классов?
Крокфорд: Да. Мне кажется, что в мире прототипирования проблем гораздо меньше, поскольку там делается акцент на экземплярах. Найдешь экземпляр, типичный с точки зрения решаемой задачи, и готово. В таком случае решение не приходится адаптировать. Но в классических системах это невозможно – там всегда идешь от абстракций к экземплярам. И очень непросто создать правильную иерархию. Так что зачастую приходится возвращаться и перерабатывать свое решение, когда в конце концов лучше поймешь проблему. Но это может серьезно повлиять на код, особенно если он разросся по сравнению с первоначальной концепцией. Поэтому не делаешь ничего серьезного, пытаясь прикрутить что-то новое поверх уже существующей иерархии, и все еще больше запутывается и ухудшается.
Сейбел: Но ведь вы считаете рефакторинг кода полезным, раз советуете посвящать ему каждый седьмой цикл? И тогда необходимость в серьезном переписывании отпадает.
Крокфорд: Да, я считаю его полезным. Можно подумать о том, чтобы выкинуть все и начать сначала, только в том случае, когда это писал не ты или сделал это плохо, что-то пошло не так, и в результате получилась база кода, с которой невозможно работать. Всегда можно прикинуть, что быстрее – переписать все заново или вносить исправления.
Сейбел: А как быть с проблемой, когда не полностью понимаешь назначение того кода, который собираешься переписывать? Ведь каждый фрагмент кода несет в себе кусочки знаний – маленькие, неприметные кусочки, которые на самом деле являются частицами дорого доставшейся функциональности, о которой не думаешь, решая все переписать.
Крокфорд: Да, это серьезная проблема. Одна из причин, почему в Сети творится такая неразбериха, – отсутствие спецификаций. Спецификации были неполными, при этом еще и трактовались зачастую неверно, и многие из-за неверного понимания стали частью общепринятых правил. Все эти системы значительно сложнее, чем могли бы быть, именно благодаря историческим причинам. Работая на этом уровне, я, конечно, тепло отношусь к этим недокументированным знаниям, которые содержит исходный код.
У Microsoft аналогичная проблема с операционными системами: они годами выпускали лажу, делая ее совместимой с прежней лажей, основанной на всей лаже, созданной раньше. Поэтому ограничения, которые накладывают старые системы при проектировании новых, просто ужасны. В такой обстановке действительно сложно двигаться вперед. В конце концов они могут обнаружить, что двигаться вперед просто невозможно.
Подобные ошибки в спецификации – действительно очень и очень серьезная проблема. У нас есть такие проблемы в мире Ajax. Основные трудности, связанные с Ajax, заключаются главным образом в отличиях на уровне браузеров. Разработка кроссбраузерных приложений значительно сложнее, чем могла бы быть, именно из-за отсутствия полноценной спецификации Сети, а также из-за существенных различий в реализациях.
В последние пять лет ситуация значительно улучшилась, особенно с появлением Ajax-библиотек. Большинство из них делают очень полезные вещи, хотя и не все, что нужно, но достаточно для повышения вашего уровня как программиста. Теперь не нужно копаться во внутренностях браузера, для этого у нас есть нечто вроде виртуального слоя, на основе которого можно разрабатывать весьма гибкие и переносимые приложения. Здесь, в Yahoo!, у нас есть команда, основная задача которой – работа с проблемами, связанными с браузерами. Хорошая работа этой команды значительно облегчает жизнь другим нашим разработчикам.
Сейбел: С другой стороны, переписывание системы не всегда срабатывает. Ранее вы упомянули эффект второй системы, а в другом интервью назвали это явление в действии «душераздирающим зрелищем». Когда это случилось?
Крокфорд: Это было в Electric Communities. Мы собрали там команду умнейших программистов, которую я когда-либо видел. У нас был достаточный бюджет, мы собирались заново реализовать кусок, который уже написали Чип и Рэнди, так что мы точно знали, что нам делать. Разница была только в масштабе.
Сейбел: Речь шла о переделке Habitat?
Крокфорд: Да, мы собирались переписать Habitat, только на этот раз с учетом его глобального распределения. Это оказалось крайне нелегко. Хотя нам и удалось его создать, это было мучение. Не хотел бы я вновь пережить нечто подобное.
Сейбел: Как вы думаете, тот совет, который вы дали чуть раньше, – быть достаточно дисциплинированными, чтобы реализовать заново только то, что действительно понимаешь, – мог уберечь от беды?
Крокфорд: Думаю, это помогло бы. Мы не продумали как следует процесс с учетом всех его этапов. У нас не было инкрементального подхода. Если бы он был, я бы направил усилия на две параллельные задачи. Во-первых, разработал безопасную распределенную платформу, которая бы не делала ничего, кроме обмена сообщениями и управления объектами. Во-вторых, переписал бы Habitat с учетом всех наших знаний о современных языках программирования. Просто переписал бы и все.
Второй этап заключался бы в соединении одного и другого. Можем ли мы построить одно поверх другого так, чтобы система продолжала работать? Хорошо, а теперь давайте займемся распределенной частью.
При подобном инкрементальном подходе, думаю, нас бы ждал успех. Но мы попытались сделать все одновременно, и это оказалось слишком сложной задачей.
Сейбел: Думаете, вы решили делать все одним этапом именно потому, что уже знали крупные куски будущей программы?
Крокфорд: Потому что мы были очень умны и опытны. Мы решили, что промашка просто невозможна. Программисты по своей природе оптимисты. И мы были оптимистами, иначе эту работу было бы не сделать. Вот почему мы пали жертвой эффекта второй системы, не сумев спланировать свои проекты, вот почему все оказалось для нас таким трудным.
Сейбел: Легче ли программировать со временем? Станет ли в будущем больше способных к тому, что мы сейчас называем программированием?
Крокфорд: Для меня программирование интересно тем, что я помогаю другим заниматься программированием. Я проектирую язык или инструмент так, чтобы он был доступен множеству людей. Именно из этих соображений была начата работа над языком Smalltalk. Smalltalk пошел другим путем, но первоначальная идея была для меня крайне привлекательна. Как создать язык программирования, предназначенный специально для детей, или как создать язык специально для тех, кто не считает себя программистами?
Сейбел: Видимо, вы полагаете, что научиться программировать должен каждый, хотя бы чуть-чуть?
Крокфорд: По-моему, иного выхода нет. Сегодня компьютеры захватили мир, и для того чтобы защитить себя или чтобы быть полноценным гражданином, вы должны хотя бы немного понимать, как все это работает.
Сейбел: Кое-кто считает, что программирование развивает особый тип мышления – в том смысле, что чтение и решение математических задач – это два разных способа мышления, и оба важны.
Крокфорд: Раньше я тоже так думал. Когда я начал заниматься программированием, у меня были потрясающие озарения: для меня все становилось упорядоченным, я видел структуры и вещи, которых прежде не замечал. И думал: «Поразительно! Каждый должен научиться этому», – потому что внезапно чувствовал себя значительно умнее. Но вскоре, беседуя с другими программистами, я понял, что они этого не понимают. Программист может совершенно неправильно воспринимать окружающий мир, как и любой другой человек. Для меня это оказалось грустным открытием.
Сейбел: Вы все еще получаете такое же удовольствие от программирования, как раньше?
Крокфорд: А как же!
Сейбел: Как по-вашему, становится ли программирование уделом молодых?
Крокфорд: Раньше я так и думал. Несколько лет назад у меня произошла остановка дыхания во сне, но я об этом не знал. Я думал, что просто становлюсь старым и усталым, что дошел до той точки, когда сконцентрироваться невозможно. И я решил, что не смогу больше программировать, потому что просто не могу удерживать все нужное в голове. В процессе программирования часто приходится держать в голове множество вещей, пока не сможешь записать их, оформив в виде каких-то конструкций. А как раз этого я больше не мог.
Я утратил эту способность и считал, что причина тому – мой возраст. К счастью, мне полегчало, способность восстановилась, и я снова вернулся к программированию. У меня все прекрасно получается, может быть, даже лучше, чем раньше, потому что я научился не зависеть так сильно от собственной памяти. Я теперь лучше документирую свой код, так как уже не столь уверен в том, что смогу вспомнить через неделю, почему я что-то сделал. На самом деле, иногда я просматриваю то, что написал, и поражаюсь, потому что совершенно не помню этих вещей. Иногда они оказываются ужасными, иногда блестящими. Даже не думал, что я когда-то был на такое способен.
Сейбел: Вы как-то назвали великолепной идеей литературное программирование в стиле Дональда Кнута[41]41
Дональд Э. Кнут, автор книги «The Art of Computer Programming» (Искусство программирования» – Вильямс, 2008 г.).
[Закрыть]. Вы применяете инструменты для литературного программирования?
Крокфорд: Нет. Я думал об этом и даже создал такие инструменты для нескольких языков, с которыми работаю, но сейчас литературным программированием я не занимаюсь.
Сейбел: Дело в проблеме взаимодействия инструментов между собой? Если ее решить, как думаете, вы бы писали литературные программы?
Крокфорд: Да. Думаю, что было бы значительно легче сопровождать JSLint, например с помощью литературного программирования. В литературном программировании мне нравится то, что проектируешь программу специально для чтения. Мне кажется, это придает ей невероятную ценность.
Сейбел: Каковы, по-вашему, основные возможности инструментов для литературного программирования?
Крокфорд: Основное свойство, которое открыл или создал Кнут, – возможность писать код не по порядку. Если меня интересует конкретная вещь, которая неоднократно встречается в коде, я могу собрать все эти фрагменты вместе, вместе их описать, а потом инструмент расставит их по местам.
Еще одна вещь, от которой освобождает литературное программирование, – размер функции. В идеале функция должна целиком помещаться на экране, чтобы ее можно было прочитать всю сразу. Если это не так, приходится создавать намного больше функций, а если такие функции ничего не добавляют системе, то становятся бесполезным шумом.
Благодаря Кнуту можно взять по отдельности все аспекты этой функции, которые могут быть тесно связаны между собой, но при этом объем слишком велик. Литературное программирование позволяет снабдить каждый элемент чего-то большого четкой описательной меткой и сказать: «Эта функция включает:» – и привести список этих меток. Почти то же самое можно сделать с помощью функций, но в этом случае придется вникать во взаимодействие ее элементов и так далее. При этом вводятся новые структуры, которые, собственно говоря, не решают никаких задач.
В идеале я хотел бы увидеть языки программирования, спроектированные специально для литературного программирования. Кнут удачно применил свою идею к Паскалю и Си, но мне хочется видеть новые языки, целиком и полностью разработанные именно для таких задач.
Сейбел: Вы читали программы Кнута, написанные в этом стиле?
Крокфорд: Конечно.
Сейбел: Как вы их читали? Как роман?
Крокфорд: Да, как роман. Я больше читал его книг, чем его программ, но мне действительно нравится, как он располагает код; пишет он действительно здорово, иногда даже вставляет небольшие шутки. Читать его программы действительно приятно.
Сейбел: Что именно вы выносите из них для себя? Вот вы прочли его книгу про ТеХ. Готовы ли вы добавлять новые возможности в ТеХ, или просто восхищаетесь тем, какой Кнут классный парень?
Крокфорд: Отличный вопрос. Я ознакомился с книгой про ТеХ, но читал ее без намерений что-то в нем изменять. Я читал просто с целью посмотреть, что же он такое сделал. Больше всего меня интересовало, как он реализовал разбиение строк, и эту часть я прочел с особым вниманием: я хотел прежде всего разобраться в алгоритме, а не понять, как работает код, чтобы его потом изменять или повторно использовать. Конечно, если бы я намеревался влезть в саму программу, я бы читал книгу по-другому.