Пол Грэм, Design and Research, January 2003
«Хакеры и Художники», глава 15
Проектирование и Исследование
За перевод спасибо knagaev
(Эта статья в своей основе содержит программный доклад на NEPLS осенью 2002 года)
Приезжающих в Америку часто застаёт врасплох манера американцев начинать разговор с вопроса «Чем вы занимаетесь?» Я никогда не любил этот вопрос. Я очень редко слышал достойный ответ на него. Но сейчас думаю, что решил эту проблему. Теперь, если кто-нибудь спрашивает чем я занимаюсь, я смотрю ему прямо в глаза и говорю «Я проектирую новый диалект Lisp.» Этот ответ я рекомендую всем, кто не любит когда интересуются что они делают. Разговор тут же свернёт на другие темы.
Я не считаю, что занимаюсь исследованиями языков программирования. Я всего лишь проектирую один из них, как кто-нибудь может проектировать здание, или стул, или новый шрифт. Я не пытаюсь открыть что-то новое. Я только хочу создать язык, который будет хорош для программирования на нём. В какой-то мере, это делает жизнь намного проще.
Различия между проектированием и исследованием похожи на противопоставление нового и хорошего. Архитектурное решение не должно быть новым, но должно быть качественным. Результаты исследования не обязательно должны быть правильными, но обязаны обладать новизной. Думаю, что эти два пути сходятся на вершине: лучший дизайн превосходит своих предшественников на основе использования новых идей, а лучшее исследование решает задачи, которые не столько новые, сколько на самом деле заслуживающие решения. Так что, в конечном счёте, мы стремимся к одному, просто двигаемся с разных сторон.
Сегодня я хочу поговорить о том, на что похожа ваша цель с другой стороны. Что вы делаете по-другому, когда рассматриваете язык программирования как объект проектирования, а не как тему для исследования?
Наибольшее отличие состоит в том, что вы больше сосредотачиваетесь на пользователе. Проектирование начинается с вопросов: для кого это делается и что от этого им нужно? В частности, хороший архитектор начинает не с создания решения, которое потом принудительно вешается на пользователей, но с изучения вероятных пользователей и оценки их потребностей.
Обратите внимание, я сказал «их потребностей», а не «их пожеланий». Я не намерен создать впечатление, что работа проектировщика означает работу наподобие быстрого выпекания на скорую руку всего, чего только клиент не пожелает.
«Покупатель всегда прав» имеет тот смысл, что дизайн хорош настолько, насколько хорошо он для пользователя работает. Если вы написали роман, который на всех нагоняет скуку, или сделали ужасно неудобный стул, вы отработали плохо, точка. Вас нисколько не извиняет то, что роман или стул спроектирован с учётом передовейших теоретических принципов.
И всё же разработка того, что подходит пользователю, совсем не означает делать то, что он вам говорит. Пользователи не знают всех возможностей, и часто заблуждаются чего они хотят на самом деле.
Решение этого парадокса, по моему мнению, в том, что вы должны проектировать именно для пользователя, но проектировать то, что ему нужно, а не те хотелки, о которых он говорит. Это очень похоже на лечение. Вы не можете лечить пациенту только симптомы. Когда пациент рассказывает вам о своих симптомах, вы должны разгадать что у него не так на самом деле, и вылечить это.
Сосредоточение на требованиях пользователя является одним из принципов, на котором основано большинство приёмов правильного проектирования, и вокруг которого сосредоточено большинство проблем.
Если правильное решение должно удовлетворять требованиям пользователя, то кто же он, этот пользователь? Когда я говорю, что проектирование должно быть для пользователей, это не означает, что качественный проект нацелен на наименьший общий знаменатель. Вы можете выбрать любую группу пользователей, какую захотите. Если вы разрабатываете, к примеру, инструмент, вы можете проектировать его для кого угодно, от начинающих до экспертов, и что будет хорошим решением для одной группы, может быть неприемлемым для другой. Суть в том, что вы должны выбрать определённую группу пользователей. Думаю, что вы даже не имеете права оценивать плох дизайн или хорош, кроме как по отношению к некоторому гипотетическому пользователю.
Вероятнее всего, вы добьётесь хорошего решения, когда в группу целевых пользователей будет входить и сам проектировщик. Когда вы разрабатываете что-то для группы, к которой сами отношения не имеете, обычно получается, что вы рассматриваете этих людей упрощёнными по сравнению с собой.
Это сложная ситуация, потому что, глядя на своего пользователя свысока, пусть и благожелательно, дизайнер неминуемо развращается. Подозреваю, что очень мало проектов жилых зданий в США было разработано архитекторами, кто собирался потом в них жить. То же самое вы можете обнаружить и для языков программирования. C, Lisp и Smalltalk были созданы для себя. Cobol, Ada и Java были созданы для применения другими людьми.
Если вы думаете, что вы проектируете для идиотов, не велики шансы, что вы создадите что-то хорошее, пусть даже для идиотов.
И всё же, даже если проектируете что-то для наиболее квалифицированных пользователей, вы делаете это для людей. Другое положение вещей в исследовательской сфере. В математике вы не выбираете абстракции так, чтобы людям их было легко понимать; вы выбираете такие, которые сделают доказательство короче. Думаю, что это верно для всех основных научных дисциплин. Научные выкладки не обязаны быть эргономичными.
В искусстве всё по-другому. Проектирование целиком для людей. Человеческое тело — это причудливая конструкция, но когда вы конструируете стул, оно является именно тем, для чего вы всё делаете, и ни для чего другого. Все формы искусства должны угождать пожеланиям человека и его недостаткам. Например, для живописи при прочем одинаковом содержании картина с людьми будет более интересна, чем такая же без людей. И это не просто историческая случайность, что великие полотна Возрождения наполнены образами людей. Если бы было не так, живопись как форма искусства не была бы так популярна.
Нравится вам это или нет, но языки программирования так же предназначены людям, и я предполагаю, что человеческий разум такой же неуклюжий и своеобразный, как и человеческое тело. Какие-то идеи ухватываются людьми легко, а какие-то нет. Например, похоже, что у нас очень ограниченные возможности для работы с отдельными элементами. Это то, что в первую очередь делает языки программирования полезным изобретением; если бы мы могли держать в голове множество элементов, мы просто программировали бы в машинных кодах.
Также обратите внимание, что языки, как правило, являются не средством для написания готовых программ, а тем при помощи чего программы должны разрабатываться. Любой человек искусства может вам сказать, что в разных ситуациях вам могут понадобиться разные материалы.
Например, мрамор — это красивый и надежный материал для оформления готовых идей, но он безнадёжно не подходит для отработки новых.
Программа, как и доказательство, является деревом, которое начинает неправильно ветвиться и плохие ветки обрезаются. Так что проверкой качества языка будет не то, как красиво выглядит на нём готовая программа, но насколько прост был путь к этой готовой программе. Вариант, который обеспечит вам элегантность готовых программ, не обязательно обеспечит элегантный процесс разработки. Например, как-то раз я написал несколько макросов с макроопределениями, полных вложенных обратных кавычек, которые выглядят как маленькие бриллианты, но их написание заняло часы отвратительного кодирования методом проб и ошибок, и, честно говоря, я до конца не уверен, что они полностью безошибочны.
Мы часто поступаем, используя для оценки языка внешний вид законченной программы. Это выглядит очень правдоподобно, если рассматриваются решения задачи, написанные на двух разных языках, и при этом одна из версий программы получилась намного короче другой. Но если вы подойдёте к этой проблеме с точки зрения искусства, то, скорее всего, меньше будете полагаться на тестирование таким способом. Вряд ли вы захотите, в конце концов, получить язык программирования наподобие мрамора.
К примеру, громадным прорывом в разработке программного обеспечения является интерактивная среда верхнего уровня, которая в Lisp называется REPL-среда или цикл «читай-вычисляй-печатай» (read-eval-print loop). И когда такая среда реализуется, она оказывает реальный эффект на дизайн языка. Например, она не будет хорошо работать в языках, где вы обязаны перед использованием объявить переменные. Когда вы просто набираете выражения в интерактивной среде, вы хотите присвоить x значение и начать его использовать. Вы не хотите, чтобы вас заставляли сначала объявить тип x. Вы можете оспорить каждое из этих предположений, но если удобным языком считается язык с реализованной средой верхнего уровня, а обязательные объявления типов не совместимы с этой средой, то ни один из языков, который делает объявления типов обязательными, не может быть удобным для программирования.
На практике, чтобы добиться хорошего дизайна вы должны стать близким другом для ваших пользователей и оставаться им. Вы должны непрерывно шлифовать свои идеи с реальными пользователями, особенно на первоначальных этапах. Одной из причин, почему романы Джейн Остин так хороши, является то, что она читала их вслух своей семье. Вот почему она никогда не потакала своим слабостям и не впадала в эстетствующие описания пейзажей или пафосное философствование. (Философия присутствовала, но была вплетена в повествование, а не приляпана поверх, как этикетка.) Если откроете среднестатистический образец «литературы» и представите, что вы читаете своим друзьям вслух, как будто написали это сами, то остро почувствуете, чего это стоит читающему.
В мире разработки ПО эта идея известна как «Чем хуже, тем лучше». На самом деле в этой концепции совмещаются несколько идей, об истинности которых люди до сих пор спорят. Но одна из главных составляющих этой концепции говорит, что если разрабатываете что-то новое, вы должны выложить прототип перед пользователями как можно раньше.
Противоположный подход может быть назван стратегией Хэйл Мэри («пас на удачу»). Вместо того, чтобы быстро выпустить прототип и потом постепенно совершенствовать его, вы можете попробовать создать сразу полный, законченный продукт как один длинный пас с тачдауном. Насколько мне известно, это рецепт катастрофы. Этот путь привёл к саморазрушению бесчисленное множество стартапов во время пузыря доткомов. Я не слышал ни об одном случае, когда такой подход сработал.
За пределами мира программирования люди могут не представлять, что принцип «Чем хуже, тем лучше» можно отыскать в искусстве повсюду. К примеру, в изобразительном искусстве эта идея была открыта во время Возрождения. Сейчас практически каждый преподаватель рисования будет рассказывать вам, что единственной правильной техникой получить точное изображение будет не двигаться медленно по контуру объекта, так как неточности накапливаются, и вы, в конце концов, обнаружите, что линии не совпадают. Напротив, вы должны набросать несколько быстрых штрихов приблизительно в нужном месте, и потом постепенно совершенствовать этот начальный набросок.
Во многих областях искусства для создания прототипов с давних пор применяются другие материалы. Матрицы для шрифтов, которые вырезаются из металла, сначала рисуются кистью на бумаге. Статуи для отливки в бронзе предварительно вылепляют из воска. Орнаменты вышивки гобеленов рисуются на бумаге чернилами. Каменные здания проверяются в уменьшенном масштабе в виде деревянных моделей.
Что сделало рисование маслом таким перспективным, когда оно в пятнадцатом веке стало популярным — это возможность получить окончательный результат из прототипа. Если нужно, можно было сделать черновой рисунок, но вы не были привязаны к нему; вы могли уточнить все детали и сделать значительные изменения в процессе работы над ним.
С программным обеспечением вы можете проделывать то же самое. Прототип не обязан быть всего лишь макетом; вы можете дорабатывать его и получить окончательный продукт. Думаю, что так надо поступать во всех случаях, когда это возможно. Это позволит вам воспользоваться преимуществами от новых озарений, возникающих в процессе разработки. Но что, весьма вероятно, и даже более важно, прототипирование полезно для позитивного настроя.
Позитивный рабочий настрой является решающим фактором в проектировании. Я поражаюсь как мало люди обращают на это внимания. Один из моих первых учителей рисования говорил мне: если рисуешь и тебе скучно, твой рисунок получится скучным. К примеру, предположим, что вам нужно нарисовать здание, и вы решите прорисовать по отдельности каждый кирпичик. Если хочется, можете так сделать, но если на середине вам станет скучно, и вы начнёте механически лепить кирпичи вместо того, чтобы соблюдать качество каждого, рисунок будет выглядеть хуже, чем если бы вы их лишь обозначили.
Создавать что-то, постепенно улучшая прототип, полезно для настроя, потому что это поддерживает вас увлечённым. В разработке ПО у меня такое правило: код всегда должен быть работающим. Если пишете что-то, что может быть проверено в течение часа, у вас есть перспектива быстрого поощрения, которая мотивирует. То же справедливо и в искусстве, в частности, рисовании маслом. Большинство художников начинают с расплывчатого наброска и постепенно прорисовывают его. Если вы работаете в такой манере, вы по сути никогда не будете останавливаться вечером на чем-то, что выглядит незавершённым. И действительно, у художников даже есть поговорка: «Рисунок никогда нельзя закончить, можно только прекратить работать над ним». Эта мысль знакома любому, кто разрабатывал ПО.
Настрой — это ещё одна причина, из-за которой трудно что-то делать для неквалифицированного пользователя. Тяжело оставаться заинтересованным в чём-то, что не нравится вам самому. Создавая что-то хорошее, вы должны думать «ого, это на самом деле отлично», а не «ну что за хрень; ну ладно, этим дебилам понравится».
Проектирование имеет смысл как творчество для людей. Но здесь люди — это не только пользователи. Проектировщик тоже является человеком.
Заметьте, я всё время говорю о «проектировщике», как о конкретном индивиде. Для того, чтобы проектное решение получилось сколько-нибудь качественным, оно должно разрабатываться под контролем единственного специалиста. В то же время считается допустимым, если в одном исследовательском проекте совместно работает несколько человек. Для меня это представляется одним из самых интересных отличий между дизайном и исследовательской работой.
Известны случаи коллективной работы в искусстве, но большинство их выглядит как молекулярные соединения, а не как ядерное слияние. В оперном жанре часто бывает, когда один человек пишет либретто, а другой — музыку. В эпоху Возрождения подмастерья из северной Европы часто нанимались изображать пейзажи для задних планов картин итальянских мастеров. Но это не настоящее сотрудничество. Эти случаи больше напоминают фразу Роберта Фроста: «за хорошими заборами — соседи хорошие». Вы можете склеивать части хорошего дизайна вместе, но в каждой части должен быть один хозяин своего индивидуального проекта.
Я не имею в виду, что хороший проект требует, чтобы один человек продумывал всё. Ничего не может быть ценнее, чем совет специалиста, решениям которого вы доверяете. Но после того как обсуждение завершено, окончательный выбор остаётся за ответственным.
Почему исследования могут вестись совместно, а проектирование нет? Это интересный вопрос. И я не знаю ответа. Возможно, когда проектирование и исследование проводятся одновременно, лучший результат исследования становится хорошим дизайном, и в реальной жизни это не может быть сделано соавторами. Огромное количество самых известных учёных вероятно работали в одиночку. Но данных у меня недостаточно, чтобы сказать есть ли здесь закономерность. Может быть просто дело в том, что многие известные учёные работали в то время, когда коллективное творчество ещё не было популярно.
Но как бы это ни было в науке, в искусстве реальное коллективное творчество встречается исчезающе редко. Коллегиальные проектные решения являются синонимом плохих проектных решений. Почему это так? Есть ли какой-нибудь способ избежать этого?
Я склонен думать, что нет — хороший проект требует диктатора. Одной из причин является то, что хороший дизайн должен быть цельным, с одинаковым качеством всех составляющих. Если решения представляют собой идею, которая укладывается в голове одного человека, она может так же укладываться и в голове пользователя.
(еще свеженькое — Пол Грэм: «Почему Y Combinator?» и Пол Грэм: Высоко-технологичное общество)
Книга «Хакеры и Художники»
Переведенные главы
www.paulgraham.com/hptoc.html
- Why Nerds Are Unpopular
Their minds are not on the game.
оригинал, перевод часть 1, часть 2 - Hackers and Painters
Hackers are makers, like painters or architects or writers.
оригинал, перевод часть 1, часть 2, альтернатива
- What You Can't Say
How to think heretical thoughts and what to do with them.
оригинал, перевод
- Good Bad Attitude
Like Americans, hackers win by breaking rules.
оригинал, перевод
- The Other Road Ahead
Web-based software offers the biggest opportunity since the arrival of the microcomputer.
оригинал, перевод - How to Make Wealth
The best way to get rich is to create wealth. And startups are the best way to do that.
оригинал, перевод
- Mind the Gap
Could «unequal income distribution» be less of a problem than we think?
оригинал, перевод
- A Plan for Spam
Till recently most experts thought spam filtering wouldn't work. This proposal changed their minds.
оригинал, перевод
- Taste for Makers
How do you make great things?
оригинал, перевод
- Programming Languages Explained
What a programming language is and why they are a hot topic now. - The Hundred-Year Language
How will we program in a hundred years? Why not start now?
оригинал, перевод
- Beating the Averages
For web-based applications you can use whatever language you want. So can your competitors.
орининал, перевод
- Revenge of the Nerds
In technology, «industry best practice» is a recipe for losing.
оригинал, перевод часть 1
- The Dream Language
A good programming language is one that lets hackers have their way with it.
оригинал, перевод часть 1, часть 2
- Design and Research
Research has to be original. Design has to be good.
оригинал, перевод
Еще 107+ статей Пола Грэма на Хабре.
(Кто хочет помочь с переводом — подключайтесь)
Если вам интересно попасть в Y Combinator и вам близки идеи Грэма, пишите в личку, есть у меня пара задумок.
Ваш стартап готов подать заявку в Y Combinator?
stalkerg
Как то странно написано и я не понял смысла. Это он про динамическую/статическую типизацию? Как то бредово звучит…
ilmirus
Не каждый статически типизированный язык требует объявления типа переменной перед её использованием. Например, OCaml не требует. Более того, в OCaml'е очень редко нужно объявлять тип функции. Компилятор всё выводит сам. Ах да, и REPL у него есть.
А по поводу того, что имел в виду автор, имхо, это кивок (плевок) в сторону Cobol, Ada и Java.
stalkerg
А чем это плохо?
Просто разница: int a = 10; или auto a = 10; или даже a = 10 не вижу существенной разницы.
ilmirus
std::unique_ptr< MyClass, my_deleter > my_func(MyClass* my, std::string& s, std::pair<int, int> p) {...}
или
let my_func my s p =…
Почувствуйте разницу.
stalkerg
Ну если я прав то в выше указанных языках ужасов шаблонов нету. Да и в C++ появился auto.
т.е. претензия только в том что в редких случаях нужно много писать?
ilmirus
Если я правильно понял, то претензия в том, что типы нужно объявлять. Что, если учесть любовь автора к лиспу, который является динамически типизированным (если не брать в расчет Racket), не удивительно. А вообще, я не телепат, чтобы читать мысли автора.
Лично моё мнение в том, что лисп сосёт (http://www.c2.com/cgi/wiki?LispSucks), как OCaml (http://sds.podval.org/ocaml-sucks.html) и даже С++ (http://whydoesitsuck.com/cpp-sucks-for-a-reason/). И, как известно, нет такого языка програмирования, который повышает производительность програмирования на порядок (http://faculty.salisbury.edu/~xswang/Research/Papers/SERelated/no-silver-bullet.pdf).
Я решил для себя, что отсутсвие модульности, часовая компиляция, отсутсвие ADT и pattern matching'а, и километровые сообщения об ошибках меня бесят больше чем убогая стандартная библиотека (есть батарейки), неотключаемый сборщик мусора (смирился) и компилятор, который, зараза, постоянно пишет только «Syntax error» и не объясняет, в чем же ошибка (видимо, придется искать альтернативный компилятор, или, в крайнем случае, писать свой. Кстати, в случае плюсов, это занимает 2+ года: http://cppgm.org/).
Кстати, а вы пробовали писать на фортране? Кода на нём получается даже больше чем на плюсах… Но зато код намного приятнее читать.
stalkerg
Увы дальше Hello World не продвигался (правда приходилось читать мат либы на нём). А так сейчас я на чистом Си пишу, периодически на Python, Java, JavaScript и C++ наверное в таком порядке.
Хочу добавить в Си перегрузку функций или хотя бы опциональные аргументы как в Python… спасло бы много кода и нервов.
ilmirus
> Хочу добавить в Си перегрузку функций
А что мешает компилировать сишный код плюсовым компилятором? Просто ограничьте плюсы сабсэтом Си+перегрузка+опциональные аргументы.
stalkerg
Ну C99 не шибко совместим с С++. Да и проект мягко говоря не маленький… Postgres.
Yuuri
А ведь некоторые языки ещё и требуют все переменные заранее объявить в начале функции или блока…