Being Popular

Оригинал Перевод

Май 2001

(Эта статья была написана в качестве некоего бизнес-плана для нового языка.)

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

Что делает язык популярным? Заслуживают ли популярные языки свою популярность? Стоит ли пытаться определить хороший язык программирования? Как бы ты это сделал?

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

1 Механика Популярности

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

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

Возможно, что большинство программистов не способны отличить хороший язык программирования от плохого. Но с другими инструментами тоже самое. Это не значит, что попытка разработать хороший язык программирования является пустой тратой времени. Хакеры-эксперты могут узнать хороший язык программирования, посмотрев на него, они будут использовать его. Хакеры-эксперты – это, по общему признанию, крошечное меньшинство, но это крошечное меньшинство пишет всё хорошее ПО, и их влияние настолько велико, что остальные программисты будут стремиться использовать тот язык программирования, который будет использоваться этими хакерами. Часто, indeed, это не просто влияние, но команда: часто хакеры-эксперты являются именно теми людьми (начальники или faculty advisors), которые говорят другим программистам какой язык программирования использовать.

Мнения хакеров-экспертов не единственная сила, которая определяет относительную популярность языка программирования – унаследованное ПО (Cobol) и шумиха (Ada, Java) также играют определённую роль – но, по моему мнению, это самая влиятельная сила. Имея первоначальную критическую массу и достаточно времени, язык программирования вероятно сможет стать настолько популярным, насколько он этого заслуживает. И популярность будет отделять плохие языки от хороших, потому что обратная связь с настоящими живыми пользователями всегда ведёт к улучшениям. Посмотрите насколько сильно меняются все популярные языки в течении их жизни. Perl и Fortran – крайние случаи, но даже Lisp изменился более чем сильно. Например, в Lisp 1.5 не было макросов; они появились намного позже, после того как хакеры из MIT потратили пару лет на использование Lisp для написания настоящих программ. [1]

Должен ли язык быть хорошим для того чтобы быть популярным или нет, я думаю, что язык должен быть популярным для того, чтобы быть хорошим. И он должен оставаться популярным для того, чтобы оставаться хорошим. Уровень искусства разработки языков программирования не стоит на месте. И Lisp сегодняшнего дня до сих пор очень похож на Lisp из MIT, каким он был в середине 80, из-за того, что именно тогда у него была достаточно большая пользовательская база.

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

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

2 Внешние Факторы

Давайте начнём с того, что признаем тот факт, что один внешний фактор влияет на популярность языка программирования. Чтобы стать популярным, ЯП должен быть скриптовым языком популярной системы. Fortran и Cobol были языками скриптов на ранних мэйнфреймах от IBM. C был языком скриптов в Unix, и так далее. Tcl был языком скриптов в Tk. Предназначение Java и Javascript быть языком скриптов в веб браузерах.

Lisp не является массово популярным языком по причине того, что он не является языком скриптов массово популярной системы. Остаточная полярность Lisp относится к 60-70 годам двадцатого века, когда он был языком скриптов в MIT. Множество великих программистов того времени были так или иначе связаны с MIT. И в ранних 70-ых, до C, диалект Lisp из MIT, называемый MacLisp, был одним из тех языков программирования, который стали бы использовать серьёзные хакеры.

Сегодня Lisp является языком скриптов двух умеренно популярных систем – Emacs и Autocad, и именно поэтому я считаю, что большая часть программирования на Lisp имеет место в Emacs Lisp или AutoLisp.

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

Common Lisp непопулярен частично из-за того, что он сирота. В самом начале он поставлялся вместе с компьютером, который можно было хакнуть: Lisp Machine. Но Lisp Machine (вместе с параллельными компьютерами) были раздавлены возрастающей мощью процессоров общего назначения в 1980-ых. Common Lisp мог бы остаться популярным, если бы он был хорошим скриптовым языком для Unix. Но, увы, он ужасно плох.

Можно сказать, что языки оцениваются не с точки зрения своих достоинств. А можно сказать, что ЯП не является языком программирования если он не является скриптовым языком для чего-либо. Это только с первого взгляда кажется нечестным. Я считаю, что это не более нечестно, чем ожидать от языка того, что у него будет, скажем, реализация. Это только часть того, чем является ЯП.

ЯП нуждается в реализации, конечно же, и она должна быть свободной. Компании заплатят за ПО, но хакеры нет, а вам нужно привлечь именно хакеров.

Также языку требуется книга об этом языке. Книга должна быть толстой, хорошо написанной, и полной отличных примеров. K&R является идеалом. На данный момент, я почти готов сказать, что книга должна быть опубликована O'Reilly. Это становится определённым тестом для хакеров.

Также требуется online-документация. На самом деле, книга может начаться как online-документация. Но я не думаю, что материальные книги уже вышли из моды. Их формат удобен, и цензура, фактически навязываемая издателями, является полезным, хотя и несовершенным фильтром. Книжные магазины являются самым важным местом где можно узнать о новых языках.

3 Краткость

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

Хакеры любят краткость. Хакеры ленивы, так же как ленивы математики и архитекторы-модернисты: они ненавидят всё лишнее. Я не отойду далеко от истины, сказав, что хакер, собирающийся написать программу, решая какой язык выбрать, по крайней мере подсознательно, основывается на количестве символов, которые ему придётся напечатать. Даже если хакеры не думают именно таким образом, то создатель языка должен действовать так, как будто это было так.

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

вместо

, то хакер воспримет это как нечто среднее между оскорблением его ума и грехом против Бога.

Иногда говорят, что в Lisp стоило использовать first и rest вместо car и cdr, поскольку это сделало бы программы более простыми для чтения. Может быть в течение первой пары часов. Но хакеры могут выучить достаточно быстро, что car указывает на первый элемент списка, а cdr – на остальное. Использование first и rest обозначало бы, что пришлось бы печатать на 50% больше символов. И у них разные длины, что означает, что аргументы не будут выравнены, так как car и cdr очень часто встречаются в последовательных строках текста. Я обнаружил, что то как строки выравнены на на странице, имеет определённое значение. Я с трудом могу читать Lisp-код, когда он набран шрифтом с переменной шириной символов, и друзья говорят, что это правдиво и для других языков.

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

Каждый отдельный символ должен быть коротким. Perl и Common Lisp занимают противоположные позиции по этому вопросу. Код Perl может быть настолько плотным, что его можно перепутать со шифром, тогда как имена встроенных в Common Lisp операторов до смешного длинны. Создатели Common Lisp, видимо, полагали, что у пользователей будет текстовый редактор, который будет набирать эти имена для них. Но затраты на длинные имена заключается не только в затратах на то, чтобы их напечатать, но и в затратах на их чтение, и в затратах на место, которое они занимают на вашем экране.

4 Hackability

Одна вещь для хакеров важней даже краткости: возможность делать то, что ты хочешь. Поразительное количество усилий было приложено в течении истории языков программирования для того, чтобы не дать программистам делать то, что считается неправильным. Это опасно самонадеянное намеренье. Как разработчик языка программирования может знать, что потребуется программисту? Я считаю, что разработчикам языка стоит полагать, что целевой пользователь будет гением, которому придётся делать вещи, которые они не могли предугадать, а не ламер, которого нужно защищать от самого себя. Ламер, так или иначе, но прострелит себе ногу. Ты можешь спасти его от обращения к переменной в другом пакете, но ты не сможешь спасти его от написания плохо продуманной программы, решающей неправильную задачу, и требующей вечности на реализацию.

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

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

В Common Lisp мне часто хотелось пройтись по всем полям структуры – для того, чтобы вычистит ссылки на удалённый объект, например, или найти не инициированное поле. Я знаю, что под поверхностью структуры это просто векторы. Но, несмотря на это, я не могу написать общую функцию, которой я бы мог скормить любую структуру. Я могу получить доступ к полям только по имени, потому что это именно то для чего структуры и предназначены.

Хакеру может захотеться изменить задуманную модель раз или два в большой программе. Но возможность сделать это меняет многое. И это может быть больше чем просто вопросом решения задачи. Здесь также присутствует и некоторое удовольствие. Хакеры разделяют тайное удовольствие хирургов от копания во внутренностях, тайное удовольствие тинейджеров от выдавливания прыщей. [2] Для мальчиков, по крайней мере, некоторые виды ужасного увлекательны. Журнал Maxim публикует ежегодный том фотографий, содержащий смесь pin-up и жутких пришествий. Они знают свою аудиторию.

Исторически, Lisp давал хакерам отличную возможность делать вещи так, как им того хотелось. Полит корректность Common Lisp – это ошибочный путь развития. Ранние Lisp'ы давали тебе возможность прикасаться ко всему. Большая часть этого духа, к счастью, сохранилась в макросах. Какая восхитительная возможность произвольно изменять исходный код.

Классические макросы являются настоящими инструментами для хакера – простые, мощные и опасные. Так просто понять, что они делают: ты вызываешь функцию !!с аргументами макроса, и чтобы это не возвращало, это вставляется на место вызова макроса!!(что-то я не понял этот пассаж – you call a function on the macro's arguments, and whatever it returns gets inserted in place of the macro call ). !!Гигиенические!! (вот опять – Hygienic) макросы воплощают противоположный подход. Они пытаются защитить тебя от понимания того, что они делают. Я никогда не слышал, чтобы гигиенические макросы объяснялись одним предложением. И они являются классическим примером попыток определения того, что программистам позволено хотеть. Гигиенические макросы предназначены для того, чтобы, помимо других вещей, уберечь меня от !!захвата переменных!! (variable capture), но захват переменных – это именно то, что мне нужно в некоторых макросах.

Действительно хороший язык должен быть как чистым, так и грязным: чисто спроектированным, с маленьким ядром легко-понятных и крайне ортодоксальных операторов, но грязным в том смысле, что он позволяет хакерам делать вещи тем способом, который им нравится. C именно такой язык. Именно такими были ранние Lisp. У языка для настоящих хакеров всегда будет слегка разгульный характер.

Хороший яп должен обладать чертами, которые заставят людей, использующих фразы типа "программная инженерия" (software engineering), не одобряюще качать головами. На другом конце континуума находятся языки, наподобие Ada или Pascal, примеры пристойности, пригодной для обучения, но ни для ничего больше.

5 Одноразовые Программы

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

Одноразовая программа – это программа, которую ты быстро пишешь для некоторых ограниченных задач: программа для автоматизации задач по системному администрированию, или генерации тестовых данных для симуляции, или конвертирования данных из одного формата в другой. Удивляет в одноразовых программах то, что как же как и так многие "временные" здания построенные во многих американских университетах во время второй мировой войны, их не выбрасывают. Многие эволюционировали в настоящие программы, с настоящими возможностями и настоящими пользователями.

Мне кажется, что лучшие из больших программ начали свою жизнь именно так, а не проектировались с самого начала, как Hoover Dam. Страшно строить что-то большое с нуля. Когда люди берутся за проект, который слишком велик, они не могут справится. Проект либо захлёбывается, либо результат получается стерильным и деревянным: торговая улица, а не настоящий деловой центр, Бразилия, а не Рим, Ada, а не C.

Другим способом получить большую программу – это начать с одноразовой программы и улучшать её. Этот подход менее пугающий, и дизайн программы выигрывает от эволюции. Я думаю, что если кто-нибудь посмотрит, то выяснится, что это именно тот способ, каким большинство больших программ были разработаны. И программы, развивавшиеся таким образом, вероятно, до сих пор написаны на том языке, на котором они были первоначально написаны, так как портирование программ – редкий случай, за исключением тех случаев, когда это делается по политическим причинам. Парадоксально, но факт, если вы хотите создать язык, который будет использоваться для больших систем, тебе следует создавать язык для написания одноразовых программ, потому что именно из таких программ большие системы берут своё начало.

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

Что делает язык подходящим для написания одноразовых программ? Для начала он должен быть уже доступным. Одноразовые программы это что-то, что по вашему мнению, вы напишите за час. Так что, язык уже должен быть установлен на вашем компьютере. Это не должно быть что-то, что нужно устанавливать перед использованием. Оно уже должно быть здесь. C поставлялся вместе с операционной системой. Перл первоначально являлся инструментом для системного администрирования, и вы уже установили его.

Быть доступным означает большее чем просто быть установленным. Интерактивный язык, с интерфейсом командной строки, более доступен чем, тот язык, с которым приходится компилировать и запускать программы раздельно. Популярный язык программирования должен быть интерактивным и быстро запускаться.

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

6 Библиотеки

Конечно, крайностью в краткости это иметь уже написанную программу и просто вызвать её. И это подводит нас к тому, что, по моему мнению, будет становиться всё более и более важной чертой ЯП: библиотечные функции. Перл выигрывает потому что он обладает большой библиотекой функций для работы со строками. Этот класс библиотечных функций наиболее важен для одноразовых программ, которые пишутся для преобразования или извлечения данных. Вероятно, многие программы, написанные на Перле, начинались как пара библиотечных вызовов сведённых вместе.

Я думаю, что большая часть прорывов, которые произойдут в сфере ЯП будут иметь отношение к библиотечным функциям. Я думаю, что ЯП будущего будут располагать библиотеками, разработанными также тщательно, как и сам язык. Проектирование ЯП не будет сводится к только к тому, сделать ли твой ЯП строго или слабо типизированным, объектно-ориентированным или функциональным, или что там ещё, но прежде всего к тому как спроектировать великие библиотеки. Разработчики языков, любящие подумать о том как разработать систему типов, могут содрогнуться при мысли об этом. Это почти тоже самое как писать приложения! Слишком плохо. Языки для программистов, а библиотеки это то, в чём программисты нуждаются.

Очень трудно разработать хорошие библиотеки. Дело не только в написание кучи кода. Как только библиотека становится слишком большой, то для написания нужной функции самому иногда требует меньшего времени чем на её поиски. Библиотеки должны быть разработаны, используя маленький набор ортодоксальных операторов, так же как и сам язык. Программист должен быть способен догадаться какой библиотечный вызов сделает то, что ему требуется.

Библиотеки это то, в чём Common Lisp испытывает сильный недостаток. Имеются только рудиментарные библиотеки для манипуляции строками, и практически ничего для общения с операционной системой. Исторически, Common Lisp пытался делать вид, что операционных систем не существует. А из-за того, что ты не можешь разговаривать с операционной системой, ты навряд ли будешь способен написать серьёзную программу, используя только встроенные в Common Lisp операторы. Тебе нужно применять некоторые хаки, специфичные для реализации языка, а на практике это обычно не даёт всего того, что тебе надо. Хакеры бы были гораздо лучшего мнения о Lisp, если бы Common Lisp обладал мощными библиотеками для обработки строк и лучшей поддержкой ОС.

7 Синтаксис

Может ли язык с синтаксисом Lisp, или более точно, отсутствием синтаксиса стать популярным? Я не знаю ответа на этот вопрос. Я *думаю*, что синтаксис не является главной причиной почему Lisp не популярен на данный момент не является популярным. У КЛ есть проблемы серьёзнее чем незнакомый синтаксис. Я знаю некоторых программистов, которые комфортно себя чувствуют с префиксным синтаксисом, но всё равно используют по умолчанию Перл, потому что он обладает мощными библиотеками обработки строк и может говорить с ОС.

Существуют две возможные проблемы с префиксной нотацией: то, что программисты не знакомы с ней и то, что она недостаточно насыщена. В мире Lisp принято считать, что первая проблема является настоящей. Я не так уверен. Да, префиксная нотация заставляет обычного программиста паниковать. Но я не думаю, что мнение обычного программиста имеет значение. Языки становятся популярными или непопулярными в связи с тем, что хакеры-эксперты думают на этот счёт, и я думаю, что хакеры-эксперты способны иметь дело с префиксной нотацией. Синтаксис Перл может быть очень непонятным, но это не встало на пути у популярности Перл. Это, как ничто другое способствовало развитию культа Перл.

Размытость префиксной нотации является более серьёзной проблемой. Для хакера эксперта это действительно проблема. Никто не хочет писать (aref a x y) когда можно написать a[x,y].

8 Эффективность

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

Так что, на практике, использование хорошего профайлера является единственным способом получить быстрый код, а не, скажем, сделать язык строго-типизированным. Тебе не требуется знать тип каждого аргумента каждого вызова в программе. Что тебе нужно, так это иметь возможность указывать тип аргументов в этих бутылочных горлышках. Но главное, ты должен быть способным находить где эти бутылочные горлышки находятся.

Люди часто жалуются, что с Lisp трудно определить что именно является затратным. Это может быть правдой. Это также может быть неизбежным, если вы желаете получить очень абстрактный язык. И в любом случае я думаю, что хорошее профилирование сделает многое для решения этой проблемы: вы очень быстро узнаете, что был затратной частью.

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

Активный профайлер может быть хорошей идеей – всучить данные по быстродействию программисту вместо того, чтобы ждать пока он сам придёт и спросит. Например, редактор может подсвечивать бутылочные горлышки красным, когда программист редактирует исходный код. Другим подходом будет представление каким-нибудь образом того, что происходит в исполняющихся программах. Это будет действительно большой победой для серверных приложений, где есть множество проблем, за которыми тебе нужно следить. Активных профайлер мог бы графически показывать, что происходит в памяти в то время как программа исполняется, или даже издавать звуки для того, чтобы сообщить о том, что что-то произошло.

Звук может быть хорошим решением проблемы. В одном месте, где я работал, у нас была большая панель со циферблатами, которые показывали, что происходило с нашими веб-серверами. Стрелки двигались маленькими сервомоторами, производящими лёгкий шум, когда они крутились. Я не мог видеть доску из-за своего стола, но я обнаружил, что я мог по звуку сразу же сказать, когда на сервере возникала проблема.

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

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

Природа скорости, как она воспринимается конечным пользователем, может меняться. С увеличением числа серверных приложений, может оказаться, что всё большее число программ являются зависимыми от ввода-вывода. Быстрый ввод-вывод может окупить себя. Язык может помочь простыми, прямыми мерами на подобии простых, быстрых, форматированных функций вывода, а так же глубокими структурными изменениями наподобие кэширования и постоянных (persistent) объектов.

Пользователи заинтересованы во времени отклика. Но другим тип эффективности становится всё более и более важным: количество пользователей на один процессор, которое вы можете одновременно поддерживать. Многие интересные приложения, которые будут написаны в ближайшем будущем, будут серверными, и количество пользователей на один сервер является критическим вопросом для каждого, кто размещает подобные приложения. In the capital cost of a business offering a server-based application, this is the divisor.

В течение лет, эффективность значила не много в большинстве приложений для конечного пользователя. Разработчики могли предположить, что на столах пользователей будет находиться процессор всё более возрастающей мощности. И, в соответствие с законом Паркинсона, ПО потребляло все имеющиеся ресурсы. Это изменится с приходом серверных приложений. В этом мире ПО и будет поставляться вместе с оборудованием. Для компаний, которые предлагают серверные приложения, будет очень важно то, сколько пользователей может обслужит один сервер.

В некоторых приложениях, процессор будет ограничивающим фактором, а скорость выполнения будет иметь наибольшее значение с точки зрения оптимизации. Но часто ограничением будет объём памяти: количество пользователей будет определяться количеством памяти, которое требуется для данных каждого пользователя. Язык может помочь и в этом случае. Хорошая поддержка потоков позволит пользователям разделять одну кучу. Большим подспорьем будут постоянные (persistent) объекты, а также поддержка "ленивой загрузки" на уровне языка.

9 Время

Последний ингредиент в котором нуждается популярный язык – это время. Никто не захочет писать программы на языке, который может исчезнуть, как многие ЯП. Так что многие хакеры предпочтут подождать пару лет перед тем, как даже начинать думать о том, стоит ли его использовать.

Изобретатели удивительных новых вещей очень часто бывают удивлены, когда узнают об этом, но тебе требуется время для того, чтобы донести сообщение!! до людей. Один мой друг редко делает то, о чём его попросили в первый раз. Он знает, что люди иногда просят о вещах, которые им не нужны. Для того, чтобы исключить потерю его времени, он ждёт, чтобы его попросили сделать это в третий или четвёртый раз; к этому времени, те, кто просят, могут быть весьма раздражёнными, но, по крайней мере, они действительно хотят то, о чём они просят.

Большинство людей научились применять подобный фильтр по отношению к новшествам, о которых они слышали. Они даже не начинают уделять этому внимание до тех пор пока не услышат об этом в десятый раз. У них есть прекрасное оправдание: большинство горячего и нового чего-бы-то-ни-было оказывается простой потерей времени, и в конце концов пропадает. Отложив изучение VRML, я вообще избежал его изучения.

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

Хорошая новость заключается в том, что повторение решает эту проблему. Всё что вам нужно – это продолжать повторять свою историю и, в конце концов, люди начнут слышать. Дело не в том, что люди замечают, что вы здесь и обращают на вас внимание, а в том, что они замечают то, что вы ещё здесь.

Правдой является и то, что много времени занимает набор критической массы. Большинство технологий эволюционируют в течение длительного времени, даже после того, как они были запущены – ЯП в особенности. Ничего не может быть лучше для технологии, чем несколько лет использования только небольшим количеством early adopters. Early adopters являются изощрёнными и требовательными, и быстро выявляют оставшиеся недостатки в твоей технологии. Когда у тебя всего несколько пользователей, ты можешь быть в тесном контакте со всеми ними. И early adopters прощают тебя, когда ты улучшаешь твою систему, даже если это и вызывает некоторые сбои.

Существуют два способа представить новые технологии: метод органического роста, и метод большого взрыва. Примерами метода органического роста являются "выросшие из коротких штанишек" (seat-of-the-pants) недофинансированные гаражные стартапы. Пара парней, работающих в темноте, разрабатывает некую новую технологию. Они запускают её безо всякого маркетинга и, в начале, у них есть только несколько (фантастически преданных) пользователей. Они продолжают улучшать технологию, а в это время количество пользователей прирастает благодаря сплетням и слухам. И они уже большие ещё до того как они узнают об этом.

Примером другого подхода, метода большого взрыва, может служить поддерживаемые венчурным капиталом (VC), стартапы. Они бросаются разрабатывать продукт, запускают его с огромной рекламной кампанией, и сразу же (они надеются) заполучают большую пользовательскую базу.

В основном, гаражные ребята завидуют ребятам Большого Взрыва. Ребята Большого Взрыва гладкие, уверенные и VC уважает их. Они могут позволить всё самое лучшее, а ПР кампании, окружающие запуск, делают их знаменитостями, в качестве побочного эффекта. Ребята Органического роста, сидя в своих гаражах, чувствуют себя бедными и ни кем не любимыми. Но всё же, я думаю, что они часто ошибаются жалея себя. Кажется, что Органический Рост порождает лучшие технологии и более богатых основателей, чем метод Большого Взрыва. Если вы посмотрите на доминирующие сегодня технологии, то вы увидите, что большинство из них развивались органически.

Этот шаблон применим не только к компаниям. Ты также обнаружишь его и в спонсируемых исследованиях. Multics и Common Lisp были проектами Большого Взрыва, а Unix и MacLisp были проектами Органического Роста.

10 Перепланировка

"Лучший способ писать – это переписывать", написал E. B. White. Каждый хороший писатель знает это, и это хорошо для ПО. Наиболее важная часть планирования – это перепланировка. ЯП, в особенности, перепланируются не достаточно.

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

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

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

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

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

Хорошо всё то, что помогает вам поддерживать цикл перепланировки. Можно снова и снова переписывать прозу, пока ты не будешь счастлив от того, что у тебя получилось. Но ПО, как правило, не перепланируется в достаточной степени. У прозы есть читатели, а у ПО – *пользователи*. Если писатель перепишет очерк, то люди, читавшие его старую версию, вряд ли будут жаловаться на то, что ход их мыслей был нарушен вновь введёнными несовместимостями.

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

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

Это происходит даже в случае если комитет состоит из двух человек. Особенно часто это происходит в случае с интерфейсами между частями ПО, написанными двумя различными людьми. Для того, чтобы изменить интерфейс сразу оба должны согласиться изменить его. И поэтому интерфейсы обычно вообще не меняются, что является проблемой, так как интерфейсы – это наиболее ad hoc части любой системы.

Одним из решений здесь может быть проектирование систем таким образом, чтобы интерфейсы были горизонтальными, а не вертикальными - так, чтобы модули всегда были вертикально сложенными пластами абстракции. Тогда интерфейс, как правило, будет принадлежать одному из них. Нижний из двух уровней будет либо языком, на котором написан верхний, в этом случае нижний уровень будет владеть интерфейсом, либо он будет ведомым, в этом случае интерфейс может быть продиктован верхним уровнем.

11 Lisp

Всё это ведёт к тому, что для нового Lisp'а надежда есть. Есть надежда для любого языка, который даёт хакерам то, что они хотят, включая Lisp. Я думаю, что мы сделали ошибку думая, что хакеры отвернулись от Lisp'а из-за его необычности. Эта успокаивающая иллюзия может не дать нам увидеть настоящую проблему с Lisp, или, по крайней мере, Common Lisp, заключающуюся в том, что его обламывает делать то, что хакеры хотят делать. Языку хакеров требуются мощные библиотеки и что-нибудь, что можно хакнуть. У КЛ нет ни того, ни другого. Язык хакеров краток и пригоден к хаку. А КЛ нет.

Хорошая новость заключается в том, что Lisp сам по себе не отстой, а КЛ – отстой. Если мы сможем разработать новый Lisp, который будет настоящим хакерским языком, то, как мне кажется, хакеры будут его использовать. Они будут использовать любой язык, который делает своё дело. Всё что мы должны сделать – это обеспечить Lisp делает какую-нибудь важную работу лучше чем другие языки.

История предлагает воодушевляющие примеры. С течением времени, успешные новые языки заимствуют всё больше и больше особенностей Lisp. Осталось не так много того, что вы можете скопировать, до того как язык который вы создали превратится в Lisp. Последний горячий язык, Питон, разбавил Lisp инфиксным синтаксисом и отсутствием макросов. Новый Lisp будет естественным шагом в этом направлении.

Иногда я думаю, что называть его улучшенной версией Питона будет хорошим маркетинговым трюком. Это звучит клёвее чем Lisp. Для многих людей, Lisp – это медленный язык для ИИ с большим количеством скобок. Официальная биография Fritz Kunze старательно избегает употребления L-слова. Однако я считаю, что мы не должны бояться называть новый Lisp Lisp'ом. У многих из лучших хакеров всё ещё осталось скрытое уважение к Lisp – например у тех, кто видит 6.001 и понимает. А они являются именно теми пользователями, которых тебе нужно завоевать.

В "Как стать хакером" Эрик Реймонд ("How to Become a Hacker," Eric Raymond) описывает Lisp как что-то подобное Латыни или Греческому – язык, который тебе следует выучить в качестве упражнения для интеллекта, даже если ты не будешь его использовать:

Если бы я не знал Lisp, чтение этого отрывка заставило бы меня задаться некоторыми вопросами. Язык, который сделает меня лучшим программистом, если это означает хоть что-то, то это означает, что этот язык должен лучше подходить для программирования. И это именно то, что говорит Эрик.

Я думаю, что пока эта идея крутится по близости, хакеры будут достаточно восприимчивы к новому Lisp'у, даже если он будет называться Lisp'ом. Но этот Lisp должен быть хакерским языком, как классические Lisp'ы 1970-ых. Он должен быть насыщенным, простым и пригодным к хаку. И он должен обладать мощными библиотеками позволяющими хакерам делать то, что они хотят делать.

Говоря о библиотеках, то, по моему мнению, нам есть где развернуться для того, чтобы побить Перл и Питон на их собственной территории. Многие из новых приложений которые должны быть написаны в ближайшие годы будут серверными приложениями. Нет причин по которым Lisp не должен обладать такими же хорошими библиотеками по обработке строк как Перл, и если этот новый Lisp будет обладать мощными библиотеками для серверных приложений, он сможет стать очень популярным. Хорошие хакеры не отворачивают носы от нового инструмента, который позволит им решать трудные проблемы несколькими вызовами библиотечных функций. Помни, хакеры ленивы.

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

Серверные приложения также дают ответ на вопрос о том, что именно будет хакаться с использованием этого нового Lisp'а. Не повредит сделать Lisp более подходящим в качестве языка скриптов для Unix. (Сложно будет сделать его ещё менее подходящим.) Но я думаю, что лучше всего будет следовать примеру Tcl, и поставлять этот Lisp вместе с готовой системой для поддержки серверных приложений. Lisp, из-за своей природы естественно подходит для серверных приложений. Lexical closures provide a way to get the effect of subroutines when the ui is just a series of web pages. S-выражения легко вписываются в html, а макросы хороши для его генерации. Есть потребность в лучших инструментах для написания серверных приложений, и есть потребность в новом Lisp'е, и они будут прекрасно работать сообща/вместе.

12 Язык-Мечта

Подводя итог, опишем язык мечты для хакеров. Язык-мечта прекрасен, чист и краток. Он обладает интерактивным интерфейсом, который быстро загружается. Ты можешь писать программы для решения обычных задач используя очень мало кода. Практически весь код, который ты пишешь, является специфическим для твоего приложения. Всё остальное должно быть уже сделано за тебя.

Синтаксис языка должен быть как можно более кратким. Тебе не должно требоваться печатать ненужный символ, или даже часто использовать клавишу Шифт.

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

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

Язык обладает маленьким ядром, и мощными, крайне ортодоксальными библиотеками, разработанные с такой же тщательностью, что и ядро языка. Все библиотеки хорошо работают вместе; всё в языке подходит как части в сложной фото-камере. Ничего не объявлено устаревшим или оставлено для совместимости. Исходный код всех библиотек доступен сразу. Легко общаться с ОС и приложениями написанными на других языках.

Язык состоит из нескольких слоёв. Высоко-уровневые абстракции прозрачно строятся из низко-уровневых абстракций, к которым ты можешь получить доступ, если захочешь.

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


Примечания

[1] Макросы, очень похожие на современное представление о них, были предложены Тимоти Хартом (Timothy Hart) в 1964 году, через два года после того как Lisp 1.5 был выпущен. Изначально, недоставало способов избежать variable capture и multiple evaluation; Hart's examples are subject to both.

[2] В "When the Air Hits Your Brain", нейрохирург Франк Вертосик (Frank Vertosick) приводит разговор в котором его chief resident, Гари, говорит о различие между хирургами и терапевтами ("вшами"):

Мне Трудно думать об lumbar disc herniations как о чём-то сочном (кроме как буквально). Но всё же, я думаю, что знаю, что они имеют в виду. Мне часто приходилось ловить больших сочных жуков(bug – жук). Непрограммисту может быть трудно представить, что можно получать удовольствие от работы с жуками. Конечно, было бы лучше, если всё просто работало. И это так, с одной стороны. И всё же, в выслеживании определённых типов жуков присутствует мрачное удовлетворение.