[65]. Он указывал, что нам нужно объединить научные и художественные ценности, если мы хотим достигнуть настоящего прогресса.
Когда я сижу в аудитории и слушаю длинную лекцию, то моё внимание к рассматриваемому вопросу начинает ослабевать примерно через час. Я думаю, что вы тоже немного устали от моих разглагольствований о «науке» и «искусстве». Я, конечно, надеюсь, что вы сможете выслушать внимательно и остальную часть моей лекции, хотя бы потому, что сейчас речь пойдет о тех вещах, которые я чувствую наиболее глубоко.
Когда я говорю о программировании как об искусстве, я думаю в первую очередь о нём как о художественной форме в эстетическом смысле. Главная цель моей работы как педагога и автора состоит в том, чтобы научить людей составлять красивые программы. Вот почему я был особенно рад, узнав недавно, что мои книги имеются в Библиотеке изящных искусств при Корнельском университете. (Однако эти 3 тома, очевидно, спокойно лежат на полке без употребления, так что я боюсь, что библиотекари, может быть, совершили ошибку, поняв моё заглавие буквально.)
Я считаю, что составление программы похоже на сочинение стихов или музыки. Как сказал Андрей Ершов[66], программирование может давать нам и интеллектуальное, и эмоциональное удовлетворение, так как овладение сложным и установление системы согласованных правил является истинным достижением.
Далее, когда мы читаем программы, составленные другими, то мы можем расценивать некоторые из них как подлинные художественные произведения. Я всё ещё помню, с каким волнением я читал в 1958 году описание ассемблера Поли (Stan Poley) SOAP II. Вы, вероятно, подумаете, что я сумасшедший, и, кроме того, с тех пор очень сильно изменились стили, но в то время для меня было огромным счастьем видеть, какой элегантной может быть системная программа, особенно если сравнить её с другими тяжеловесными программами, которые я изучал в то же самое время. Возможность составления красивых программ, даже на языке ассемблера, – это то, что заставляет меня придавать программированию первостепенное значение.
Некоторые программы бывают элегантны, некоторые прелестны, а некоторые блестящи. Я утверждаю, что можно составлять великолепные программы, превосходные программы, поистине изумительные программы.
Наконец-то, идея стиля в программировании выходит сейчас на первый план, и я надеюсь, что многие из вас видели замечательную маленькую книжку Кернигэна и Плоджер (Kernighan and Planger) «Элементы стиля в программировании»[67].
В этой связи самое важное для всех нас – помнить, что не существует какого-либо «наилучшего» стиля. Каждый имеет свои собственные предпочтения, и было бы ошибкой, если бы мы пытались заставить людей придерживаться неестественного для них шаблона. Мы часто слышим: «Я ничего не знаю об искусстве, но я знаю, что мне нравится». Здесь важно, что на самом деле вам нравится тот стиль, который вы используете. Должно быть, это наилучший способ, который вы выбираете, чтобы выразить себя.
Эджер Дейкстра подчеркнул это обстоятельство в предисловии к своей книге «Краткое введение в искусство программирования»[68]: «Моя цель – объяснить важность хорошего вкуса и стиля в программировании. Однако специфические элементы стиля, представленные здесь, служат только для иллюстрации в общем виде тех преимуществ, которые могут быть получены благодаря «стилю». В этом отношении я чувствую сходство с преподавателем композиции в консерватории. Он не должен обучать своих студентов, как сочинить конкретную симфонию. Он должен помочь им найти свой собственный стиль и объяснить, к каким результатам это приводит». (Именно эта аналогия навела меня на мысль говорить об «Искусстве программирования».)
Теперь мы должны спросить себя: «Что такое хороший стиль, и что такое плохой стиль?» Мы не должны быть слишком строгими в этом отношении, оценивая работу других людей. Джереми Бентам (Jeremy Bentham), философ начала XIX века, говорит об этом следующее:
«Те, кто судит об элегантности и вкусе, считают самих себя благодетелями человеческой расы, в то время как они в действительности только мешают людям получать удовольствие… Не существует вкуса, который заслуживает эпитета хороший, разве только вкус к таким занятиям, которые доставляют удовольствие благодаря тому, что в них содержится какая-то доля ожидаемой в будущем пользы. Не существует вкуса, который заслуживает оценки плохого, если только это не вкус к некоторым занятиям, имеющим вредные свойства».
Когда мы используем наши собственные предубеждения для того, чтобы «исправить» чей-либо вкус, мы, может быть, невольно лишаем его некоторого вполне законного удовольствия. Здесь важно то, что они создают нечто такое, что они сами находят красивым.
В отрывке, который я только что процитировал, Бентам дает нам некоторый совет относительно надежных принципов эстетики, которые лучше других, а именно – полезность результата. Мы имеем определенную свободу устанавливать наши личные стандарты красоты, но особенно приятно, если вещи, которые мы считаем красивыми, в то же время рассматриваются другими людьми как полезные.
Я должен признаться, что люблю писать компьютерные программы, но я получаю особое удовольствие, когда пишу программы, которые служат в каком-то смысле на общее благо.
Конечно, программа может быть «хорошей» в различном смысле. В первую очередь очень хорошо иметь программу, которая правильно работает. Во-вторых, часто бывает полезно иметь программу, которую было бы нетрудно изменить, если наступила пора адаптировать ее. Обе эти цели достигаются, если человек, знающий соответствующий язык, легко читает и понимает эту программу.
Другой важный способ создавать хорошие программы – дать им возможность элегантно взаимодействовать с пользователями, особенно при исправлении ошибок во входных данных. Это настоящее искусство – сочинять содержательные сообщения об ошибках или разрабатывать гибкие форматы ввода, не подверженные ошибкам.
Ещё один важный аспект качества программ – это эффективность использования ресурсов компьютера. К сожалению, я должен сказать, что в наши дни многие программисты отрицают эффективность программ, утверждая, что это признак плохого вкуса.
Причина этого заключается в том, что мы сейчас испытываем реакцию того времени, когда эффективность была единственным общепризнанным критерием качества и программисты были настолько озабочены эффективностью, что они производили неоправданно сложные коды. Результатом этой излишней сложности было снижение общей эффективности за счет трудностей отладки и эксплуатации.
Настоящая проблема заключалась в том, что программисты тратили слишком много времени в заботах об эффективности в неподходящих местах и в неуместное время.
Преждевременная оптимизация – это корень всех ошибок в программировании (или, по крайней мере, большинства).
Мы не должны быть на пенни мудрыми и на фунт глупыми, мы не должны всегда думать об эффективности в том смысле, сколько процентов времени или пространства мы выиграли или потеряли. Когда мы покупаем автомобиль, то многие из нас не обращают внимания на разницу в 50 или 100 долларов в его цене. Но в то же время мы способны сделать специальный рейс к определенному магазину, чтобы купить какую-нибудь мелочь стоимостью 50 центов всего лишь за 25 центов.
Я считаю, что для эффективности есть время и место. Истинную роль эффективности я рассматриваю в своей статье о структурном программировании, которая выходит в текущем номере журнала «Computing Surveys».
Одна довольно любопытная вещь, которую я заметил относительно эстетического удовлетворения, заключается в том, что наше удовольствие значительно увеличивается тогда, когда мы создаем что-либо при ограниченных средствах труда. Например, программа, которая мне лично доставила больше всего удовольствия и гордости, – это компилятор, который я когда-то написал для примитивной мини-машины, имевшей запоминающее устройство ёмкостью 4096 16-разрядных слов. Человек чувствует себя настоящим виртуозом, когда он достигает чего-то в условиях серьёзных ограничений.
Подобное явление имеет место во многих других сферах. Например, часто люди кажутся влюбленными в свои «Фольксвагены», но редко в свои Линкольны «Continental» (которые, по-видимому, гораздо лучше). Когда я изучал программирование, было популярным развлечением сделать с программой всё возможное, чтобы уместить её на одной перфокарте. Я полагаю, что это как раз то самое явление, которое заставляет энтузиастов APL наслаждаться своими «one-liners» («программа в одной строке»). Когда мы сегодня учим программированию, то наблюдаем любопытный факт: нам редко удается увлечь студента вычислительной наукой до тех пор, пока он не проходит курс, который позволяет поработать с мини-машиной. Использование наших больших вычислительных машин с их удивительными операционными системами и языками не вызывает особой любви к программированию, по крайней мере поначалу.
Не совсем понятно, каким образом применить этот принцип, чтобы программисты получали большее удовольствие от своей работы. Конечно, программисты застонали бы, если бы их менеджер объявил неожиданно, что у новой машины объём запоминающего устройства в два раза меньше, чем у старой. И я не думаю, что кто-нибудь, даже из самых преданных «программистов-художников», приветствовал бы такую новость, так как никому не хочется терять имеющиеся возможности. Другой пример может помочь прояснить ситуацию: кинорежиссёры очень сильно сопротивлялись введению звукового кино в 20-х годах, так как они гордились тем, что могли передавать содержание без звука. Точно так же истинный программист-художник мог бы негодовать по поводу введения более мощной техники. Так, современные запоминающие устройства имеют тенденцию разрушить красоту наших старых методов сортировки на магнитных лентах. Однако сегодняшние режиссеры не хотят возвращаться к немым фильмам. И не потому, что они ленивы, а потому, что они знают, что можно создать прекрасные фильмы, используя новую технологию. Форма искусства изменилась, но вместе с тем появилась масса новых художественных средств. Как же они развивали своё искусство?