pg.gimran.org

Язык через сто лет

Апрель 2003 · Все эссе

Перевод эссе Пола Грэма «Язык через сто лет». Оригинал: https://paulgraham.com/hundred.html. Машинный перевод (Gemini).

Translation of Paul Graham's essay 'The Hundred-Year Language'. Original: https://paulgraham.com/hundred.html. Machine translation (Gemini).

(Это эссе основано на вступительном докладе на конференции PyCon 2003.)

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

Об этом стоит подумать не столько потому, что нам самим доведётся использовать эти языки, сколько потому, что, если повезёт, мы будем использовать языки на пути от нынешней точки к той.

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

Похожую судьбу я предсказываю для Java. Люди иногда пишут мне: «Как вы можете говорить, что Java не станет успешным языком? Он уже успешен». И я признаю это, если мерить успех местом на полках, занятым книгами по нему (особенно отдельными увесистыми томами), или числом студентов, уверенных, что его нужно выучить ради работы. Говоря, что Java не станет успешным языком, я имею в виду нечто более конкретное: Java окажется эволюционным тупиком, как Cobol.

Это лишь догадка. Я могу ошибаться. Моя цель здесь — не принизить Java, а поднять вопрос об эволюционных деревьях и побудить людей спросить себя: где на этом дереве находится язык X? Задавать этот вопрос нужно не просто ради того, чтобы наши призраки через сто лет могли сказать «я же говорил». А потому, что держаться ближе к основным ветвям — полезная эвристика для поиска языков, на которых приятно программировать уже сейчас.

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

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

Эволюция языков отличается от эволюции видов тем, что ветви могут сходиться. Ветвь Fortran, например, похоже, сливается с потомками Algol. В теории это возможно и для видов, но вряд ли когда-либо происходило с существами крупнее клетки.

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

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

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

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

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

Как минимум, внимательно изучить ядро языка, чтобы проверить, нельзя ли выполоть какие-то аксиомы, — полезное упражнение. За свою долгую жизнь неряхи я заметил, что хлам порождает хлам, и я видел, как это происходит как в софте, так и под кроватями и по углам комнат.

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

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

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

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

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

Из чего бы ни были сделаны компьютеры через сто лет, можно с уверенностью предсказать, что они будут намного быстрее, чем сейчас. Если закон Мура продолжит работать, они станут в 74 квинтиллиона (73 786 976 294 838 206 464) раз быстрее. Такое трудно вообразить. И действительно, самый вероятный прогноз в плане скорости может состоять в том, что закон Мура перестанет действовать. Всё, что должно удваиваться каждые восемнадцать месяцев, рано или поздно непременно наткнётся на какой-то фундаментальный предел. Но мне нетрудно поверить, что компьютеры станут намного быстрее. Даже если они станут быстрее всего в жалкий миллион раз, это должно существенно изменить базовые правила для языков программирования. Помимо прочего, появится больше места для языков, которые сейчас считались бы медленными, то есть не дающими очень эффективного кода.

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

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

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

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

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

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

Бывает расточительство хорошее и дурное. Меня интересует хорошее — такое, где, тратя больше, мы можем получить более простые конструкции. Как мы воспользуемся возможностями впустую тратить такты, которые нам предоставит новое, более быстрое оборудование?

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

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

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

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

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

Меньшая привязка к реализации должна также сделать программы более гибкими. Спецификации меняются прямо в процессе написания программы, и это не просто неизбежно, но и желательно.

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

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

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

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

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

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

Есть перспективы ещё более шокирующие. Например, в том Лиспе, который Маккарти описал в 1960 году, не было чисел. Логически отдельное понятие чисел вам не нужно, потому что их можно представить как списки: целое число n можно представить списком из n элементов. Так можно заниматься математикой. Просто это будет невыносимо неэффективно.

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

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

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

Другой способ сжигать такты — разместить множество слоёв программного обеспечения между приложением и аппаратурой. Это тоже тенденция, которую мы уже наблюдаем: многие современные языки компилируются в байт-код. Билл Вудс однажды сказал мне, что, как показывает опыт, каждый уровень интерпретации снижает скорость примерно в 10 раз. За эту дополнительную цену вы покупаете гибкость.

Самая первая версия Arc была крайним случаем такой многоуровневой медлительности с соответствующими преимуществами. Это был классический «метациклический» интерпретатор, написанный поверх Common Lisp, с явным фамильным сходством с функцией eval, определённой в исходной статье Маккарти о Лиспе. Всё это занимало всего пару сотен строк кода, так что программу было очень легко понимать и менять. Использовавшийся нами Common Lisp, CLisp, сам работает поверх интерпретатора байт-кода. Так что здесь было два уровня интерпретации, один из которых (верхний) был шокирующе неэффективным, и всё же язык был пригоден для использования. С трудом пригоден, признаю, но пригоден.

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

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

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

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

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

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

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

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

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

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

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

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

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

Кто будет проектировать языки будущего? Одной из самых захватывающих тенденций последних десяти лет стал расцвет языков с открытым исходным кодом, таких как Perl, Python и Ruby. Проектирование языков переходит в руки хакеров. Результаты пока сумбурны, но обнадеживают. Например, в Perl есть несколько поразительно новаторских идей. Многие из них поразительно плохи, но так всегда бывает при амбициозных попытках. При нынешней скорости мутаций один Бог знает, во что может развиться Perl через сто лет.

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

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

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

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

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

Какую программу хотелось бы написать? Такую, которая потребует меньше всего усилий. Вернее, не совсем так: ту, которая потребовала бы меньше всего усилий, если бы на ваши представления о программировании уже не влияли языки, к которым вы привыкли сейчас. Это влияние может быть настолько глубоким, что преодолеть его стоит огромных трудов. Казалось бы, столь ленивым существам, как мы, должно быть очевидно, как выразить программу с минимальными затратами сил. На самом же деле наши представления о возможном обычно настолько ограничены языком, на котором мы думаем, что более простые формулировки программ вызывают искреннее удивление. Их приходится открывать, к ним не приходишь сам собой.

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

На практике написание программ на воображаемом столетнем языке будет удаваться в разной степени, в зависимости от того, насколько вы близки к его ядру. Подпрограммы сортировки можно написать уже сейчас. Но сейчас было бы трудно предсказать, какие библиотеки могут понадобиться через сто лет. По-видимому, многие библиотеки будут предназначены для областей, которые пока даже не существуют. Если, например, SETI@home сработает, нам понадобятся библиотеки для общения с инопланетянами. Если, конечно, они не настолько развиты, что уже общаются на XML.

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

Если бы столетний язык был доступен сегодня, захотели бы мы писать на нём программы? Один из способов ответить на этот вопрос — оглянуться назад. Если бы сегодняшние языки программирования были доступны в 1960 году, захотел бы кто-нибудь ими пользоваться?

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

Думаю, да. У некоторых из менее одарённых воображением, в чьи представления о программе намертво впечатались артефакты ранних языков, могли бы возникнуть трудности. (Как можно манипулировать данными без адресной арифметики указателей? Как можно реализовать блок-схемы без goto?) Но я думаю, что самые толковые программисты без проблем извлекли бы максимум пользы из современных языков, появись они тогда.

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

Теперь у нас есть две идеи, совмещение которых открывает интересные возможности: (1) столетний язык в принципе можно спроектировать уже сегодня, и (2) на таком языке, существовал бы он сейчас, было бы вполне удобно программировать уже сегодня. Когда видишь эти мысли, сформулированные бок о бок, трудно не подумать: а почему бы не попытаться написать столетний язык прямо сейчас?

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

Примечания

Полагаю, Lisp Machine Lisp был первым языком, воплотившим принцип, согласно которому объявления типов (за исключением динамических переменных) были всего лишь подсказками для оптимизации и не меняли смысла корректной программы. Common Lisp, судя по всему, первым сформулировал это явно.

Спасибо Тревору Блэквеллу, Роберту Моррису и Дэну Гиффину за прочтение черновиков этой статьи, а также Гвидо ван Россуму, Джереми Хилтону и всей команде Python за приглашение выступить на PyCon.