Апрель 2003
(Это эссе взято из основного доклада на PyCon 2003).
Трудно предсказать, какой будет жизнь через сто лет. Есть только несколько вещей, о которых мы можем сказать с уверенностью. Мы знаем, что все будут ездить на летающих автомобилях, что законы о зонировании будут смягчены и позволят строить здания высотой в сотни этажей, что большую часть времени будет темно, и что все женщины будут обучены боевым искусствам. Здесь я хочу увеличить одну деталь этой картины. На каком языке программирования будет написано программное обеспечение, управляющее этими летающими автомобилями?
Об этом стоит задуматься не столько потому, что мы действительно будем использовать эти языки, сколько потому, что, если нам повезет, мы будем использовать языки на пути от этой точки к той.
Я думаю, что, как и виды, языки будут образовывать эволюционные деревья с тупиковыми ветвями. Мы уже видим, как это происходит. Cobol, при всей своей популярности, похоже, не имеет интеллектуальных потомков. Это эволюционный тупик - неандертальский язык.
Я предсказываю похожую судьбу Java. Люди иногда присылают мне письма: "Как вы можете говорить, что Java не станет успешным языком? Это уже успешный язык". И я признаю, что это так, если измерять успех по местам на полках, занятым книгами по нему (особенно отдельными книгами по нему), или по количеству студентов, которые считают, что должны его выучить, чтобы получить работу. Когда я говорю, что Java не станет успешным языком, я имею в виду нечто более конкретное: что Java окажется эволюционным тупиком, как Cobol.
Это всего лишь предположение. Я могу ошибаться. Я не хочу осуждать Java, но хочу поднять вопрос об эволюционных деревьях и заставить людей спросить, где на дереве находится язык X? Причина задать этот вопрос не только в том, чтобы наши призраки могли сказать через сто лет: "Я же вам говорил". Это потому, что держаться ближе к основным ветвям - полезная эвристика для поиска языков, на которых хорошо программировать сейчас.
В любой момент времени вы, вероятно, наиболее счастливы на основных ветвях эволюционного дерева. Даже когда неандертальцев было еще много, быть одним из них, должно быть, было отстойно. Кроманьонцы постоянно приходили, избивали вас и крали вашу еду.
Я хочу знать, какими будут языки через сто лет, только для того, чтобы знать, на какую ветвь дерева делать ставку сейчас.
Эволюция языков отличается от эволюции видов тем, что ветви могут сближаться. Ветвь Fortran, например, похоже, сливается с потомками Algol. Теоретически это возможно и для видов, но вряд ли это произошло с чем-то большим, чем клетка.
Конвергенция более вероятна для языков отчасти потому, что пространство возможностей меньше, а отчасти потому, что мутации не случайны. Разработчики языков намеренно включают идеи из других языков.
Особенно полезно для разработчиков языков думать о том, куда может привести эволюция языков программирования, потому что они могут направлять ее соответствующим образом. В этом случае "оставаться на главной ветке" становится не просто способом выбрать хороший язык. Это становится эвристикой для принятия правильных решений о разработке языка.
Любой язык программирования можно разделить на две части: некоторый набор фундаментальных операторов, которые играют роль аксиом, и остальной язык, который в принципе может быть написан в терминах этих фундаментальных операторов.
Я думаю, что фундаментальные операторы - это самый важный фактор в долгосрочном выживании языка. Остальное можно изменить. Это похоже на правило, что при покупке дома нужно в первую очередь обращать внимание на местоположение. Все остальное можно исправить позже, но местоположение исправить нельзя.
Я думаю, что важно не только, чтобы аксиомы были хорошо выбраны, но и чтобы их было немного. Математики всегда так относились к аксиомам - чем меньше, тем лучше - и я думаю, что они в чем-то правы.
По крайней мере, это должно быть полезным упражнением - внимательно изучить ядро языка, чтобы понять, есть ли там аксиомы, которые можно отсеять. За свою долгую карьеру неряхи я убедился, что хлам порождает хлам, и я видел, как это происходит в программах, а также под кроватями и в углах комнат.
У меня есть предположение, что основные ветви эволюционного древа проходят через языки, которые имеют самые маленькие, самые чистые ядра. Чем больше язык может написать сам в себе, тем лучше.
Конечно, я делаю большое допущение, задавая вопрос о том, какими будут языки программирования через сто лет. Будем ли мы вообще писать программы через сто лет? Не будем ли мы просто говорить компьютерам, что мы хотим, чтобы они делали?
Пока что в этом направлении нет большого прогресса. Я думаю, что и через сто лет люди будут указывать компьютерам, что делать, используя программы, которые мы будем считать таковыми. Возможно, будут задачи, которые мы сейчас решаем с помощью программ, а через сто лет для их решения не нужно будет писать программы, но я думаю, что программирование того типа, которым мы занимаемся сегодня, все еще будет иметь место.
Может показаться самонадеянным, что кто-то может предсказать, как будет выглядеть любая технология через сто лет. Но помните, что у нас за плечами уже почти пятьдесят лет истории. Заглянуть на сто лет вперед - вполне понятная идея, если учесть, как медленно развивались языки за последние пятьдесят лет.
Языки развиваются медленно, потому что на самом деле они не являются технологиями. Языки - это условные обозначения. Программа - это формальное описание проблемы, которую вы хотите, чтобы компьютер решил за вас. Поэтому скорость эволюции языков программирования больше похожа на скорость эволюции математической нотации, чем, скажем, транспорта или связи. Математическая нотация действительно развивается, но не такими гигантскими скачками, как технологии.
Из чего бы ни были сделаны компьютеры через сто лет, можно с уверенностью предсказать, что они будут намного быстрее, чем сейчас. Если закон Мура продолжит действовать, они будут быстрее в 74 квинтиллиона (73 786 976 294 838 206 464) раз. Это трудно себе представить. И действительно, наиболее вероятным прогнозом в области скорости может быть то, что закон Мура перестанет работать. Все, что должно удваиваться каждые восемнадцать месяцев, вероятно, в конце концов столкнется с каким-то фундаментальным пределом. Но мне нетрудно поверить, что компьютеры будут намного быстрее. Даже если в итоге они окажутся быстрее всего в миллион раз, это должно существенно изменить правила программирования. Среди прочего, появится больше места для тех языков, которые сейчас считаются медленными, то есть для языков, не дающих очень эффективного кода.
И все же некоторые приложения по-прежнему будут требовать скорости. Некоторые проблемы, которые мы хотим решить с помощью компьютеров, создаются компьютерами; например, скорость, с которой вы должны обрабатывать видеоизображения, зависит от скорости, с которой другой компьютер может их генерировать. Есть и другой класс проблем, которые по своей природе обладают неограниченной способностью поглощать циклы: рендеринг изображений, криптография, симуляция.
Если одни приложения могут быть все более неэффективными, в то время как другие продолжают требовать всей скорости, которую может обеспечить аппаратное обеспечение, более быстрые компьютеры будут означать, что языки должны охватывать все более широкий диапазон эффективности. Мы уже видим, как это происходит. Текущие реализации некоторых популярных новых языков являются шокирующе расточительными по стандартам предыдущих десятилетий.
Это происходит не только с языками программирования. Это общая историческая тенденция. По мере совершенствования технологий каждое поколение может делать вещи, которые предыдущее поколение считало бы расточительными. Люди тридцатилетней давности были бы поражены тем, как непринужденно мы совершаем междугородние телефонные звонки. Люди столетней давности были бы еще больше удивлены тем, что однажды посылка может быть доставлена из Бостона в Нью-Йорк через Мемфис.
Я уже могу сказать, что произойдет со всеми теми дополнительными циклами, которые даст нам более быстрое оборудование в ближайшие сто лет. Почти все они будут потрачены впустую.
Я учился программировать, когда компьютерные мощности были в дефиците. Я помню, как убирал все пробелы из своих программ на Basic, чтобы они поместились в память 4K TRS-80. Мысль о том, что все эти потрясающе неэффективные программы сжигают циклы, делая одно и то же снова и снова, кажется мне отвратительной. Но я думаю, что мои интуиции здесь ошибочны. Я похож на человека, который вырос в бедности и не переносит тратить деньги даже на что-то важное, например, на поход к врачу.
Некоторые виды расточительства действительно отвратительны. Внедорожники, например, были бы отвратительны, даже если бы они работали на топливе, которое никогда не кончается и не загрязняет окружающую среду. Внедорожники отвратительны, потому что они являются решением отвратительной проблемы. (Как сделать минивэны более мужественными). Но не все отходы плохи. Теперь, когда у нас есть необходимая инфраструктура, подсчет минут междугородних звонков начинает казаться ничтожным. Если у вас есть ресурсы, то элегантнее считать все телефонные разговоры одним видом, независимо от того, где находится собеседник.
Есть хорошие и плохие отходы. Меня интересуют хорошие отходы - такие, когда, потратив больше, мы можем получить более простые конструкции. Как мы воспользуемся возможностями нерационального использования циклов, которые появятся благодаря новому, более быстрому оборудованию?
Стремление к скорости настолько глубоко укоренилось в нас, в наших ничтожных компьютерах, что потребуются сознательные усилия, чтобы преодолеть его. При разработке языка мы должны сознательно искать ситуации, в которых мы можем обменять эффективность даже на минимальное повышение удобства.
Большинство структур данных существует из-за скорости. Например, во многих современных языках есть и строки, и списки. Семантически строки - это более или менее подмножество списков, в которых элементами являются символы. Так зачем же нужен отдельный тип данных? На самом деле, нет. Строки существуют только для эффективности. Но загромождать семантику языка хаками, чтобы заставить программы работать быстрее, - это отстой. Наличие строк в языке кажется случаем преждевременной оптимизации.
Если мы считаем, что ядро языка - это набор аксиом, то, конечно, противно иметь дополнительные аксиомы, которые не добавляют выразительных возможностей, просто ради эффективности. Эффективность важна, но я не думаю, что это правильный способ ее добиться.
Правильный способ решения этой проблемы, как мне кажется, состоит в том, чтобы отделить смысл программы от деталей реализации. Вместо того, чтобы иметь и списки, и строки, иметь только списки, с некоторым способом дать компилятору рекомендации по оптимизации, которые позволят ему выкладывать строки как непрерывные байты, если это необходимо.
Поскольку скорость не имеет значения в большинстве программ, вам обычно не нужно беспокоиться о такого рода микроменеджменте. Это будет становиться все более и более верным по мере того, как компьютеры будут становиться быстрее.
Если говорить меньше о реализации, то это также должно сделать программы более гибкими. Спецификации меняются в процессе написания программы, и это не только неизбежно, но и желательно.
Слово "эссе" происходит от французского глагола "essayer", что означает "пробовать". Эссе в первоначальном смысле - это то, что вы пишете, чтобы попытаться что-то понять. Это происходит и в программном обеспечении. Я думаю, что некоторые из лучших программ были эссе, в том смысле, что авторы не знали, когда начинали, что именно они пытались написать.
Lisp-хакеры уже знают о ценности гибкости в работе со структурами данных. Мы склонны писать первую версию программы так, чтобы она все делала со списками. Эти первые версии могут быть настолько шокирующе неэффективными, что требуется сознательное усилие, чтобы не думать о том, что они делают, точно так же, как, по крайней мере, для меня, поедание стейка требует сознательного усилия, чтобы не думать, откуда он взялся.
Что программисты через сто лет будут искать больше всего, так это язык, на котором можно с наименьшими усилиями создать невероятно неэффективную первую версию программы. По крайней мере, именно так мы бы описали это в современных терминах. Они скажут, что им нужен язык, на котором легко программировать.
Неэффективное программное обеспечение не является отвратительным. Отвратительным является язык, который заставляет программистов делать ненужную работу. Трата времени программистов - вот истинная неэффективность, а не трата машинного времени. Это будет становиться все более очевидным по мере того, как компьютеры будут становиться быстрее.
Я думаю, что избавление от строк - это то, о чем мы уже можем подумать. Мы сделали это в Arc, и, кажется, это победа; некоторые операции, которые было бы неудобно описывать в виде регулярных выражений, можно легко описать в виде рекурсивных функций.
Как далеко зайдет это уплощение структур данных? Я могу представить себе возможности, которые шокируют даже меня, с моим сознательно расширенным кругозором. Избавимся ли мы, например, от массивов? В конце концов, это всего лишь подмножество хэш-таблиц, где ключами являются векторы целых чисел. Заменим ли мы сами хэш-таблицы списками?
Есть даже более шокирующие перспективы, чем эта. Например, в Lisp, который Маккарти описал в 1960 году, не было чисел. С точки зрения логики, вам не нужно иметь отдельное понятие чисел, потому что вы можете представлять их в виде списков: целое число n может быть представлено как список из n элементов. Вы можете заниматься математикой таким образом. Это просто невыносимо неэффективно.
На практике никто не предлагал представлять числа в виде списков. На самом деле, статья Маккарти 1960 года в то время вообще не была предназначена для реализации. Это было теоретическое упражнение, попытка создать более элегантную альтернативу машине Тьюринга. Когда кто-то неожиданно взял эту статью и перевел ее в работающий интерпретатор Lisp, числа, конечно, не были представлены в виде списков; они были представлены в двоичном виде, как и в любом другом языке.
Может ли язык программирования зайти так далеко, чтобы избавиться от чисел как фундаментального типа данных? Я задаю этот вопрос не столько как серьезный вопрос, сколько как способ поиграть с будущим. Это похоже на гипотетический случай, когда непреодолимая сила встречает недвижимый объект - здесь невообразимо неэффективная реализация встречает невообразимо большие ресурсы. Я не вижу причин для этого. Будущее довольно длинное. Если есть что-то, что мы можем сделать, чтобы уменьшить количество аксиом в основном языке, то, похоже, это та сторона, на которую стоит сделать ставку по мере приближения t к бесконечности. Если идея все еще кажется невыносимой через сто лет, то, возможно, она не будет таковой через тысячу.
Чтобы внести ясность, я не предлагаю, чтобы все числовые вычисления производились с помощью списков. Я предлагаю, чтобы основной язык, до каких-либо дополнительных обозначений о реализации, был определен таким образом. На практике любая программа, которая хочет выполнять какие-либо математические вычисления, вероятно, будет представлять числа в двоичном формате, но это будет оптимизацией, а не частью семантики основного языка.
Еще один способ сжигать циклы - иметь много уровней программного обеспечения между приложением и аппаратным обеспечением. Это тоже тенденция, которую мы уже наблюдаем: многие современные языки компилируются в байт-код. Билл Вудс однажды сказал мне, что, как правило, каждый слой интерпретации стоит 10 раз в скорости. Эта дополнительная стоимость покупает вам гибкость.
Самая первая версия Arc была экстремальным случаем такой многоуровневой медлительности с соответствующими преимуществами. Это был классический "метациркулярный" интерпретатор, написанный поверх Common Lisp, с определенным семейным сходством с функцией eval, определенной в оригинальной статье Маккарти о Lisp. Вся эта штука состояла всего из нескольких сотен строк кода, поэтому ее было очень легко понять и изменить. Common Lisp, который мы использовали, CLisp, сам по себе работает поверх интерпретатора байт-кода. Таким образом, у нас было два уровня интерпретации, один из которых (верхний) был шокирующе неэффективным, и язык был пригоден для использования. Едва пригодный, я признаю, но пригодный.
Написание программ в виде нескольких слоев - это мощная техника даже в рамках приложений. Программирование снизу вверх означает написание программы в виде серии слоев, каждый из которых служит языком для вышележащего. Этот подход, как правило, дает более компактные и гибкие программы. Это также лучший путь к святому Граалю - возможности многократного использования. Язык по определению является многоразовым. Чем больше частей вашего приложения вы можете перенести в язык, предназначенный для написания приложений данного типа, тем большая часть вашего программного обеспечения будет многоразовой.
Каким-то образом идея многократного использования привязалась к объектно-ориентированному программированию в 1980-х годах, и никакое количество доказательств обратного, кажется, не может избавить от нее. Но хотя некоторые объектно-ориентированные программы являются многоразовыми, то, что делает их многоразовыми, - это их восходящий характер, а не объектно-ориентированность. Рассмотрим библиотеки: они многоразовые, потому что они языковые, независимо от того, написаны они в объектно-ориентированном стиле или нет.
Кстати, я не предсказываю кончину объектно-ориентированного программирования. Хотя я не думаю, что оно может многое предложить хорошим программистам, за исключением некоторых специализированных областей, оно неотразимо для крупных организаций. Объектно-ориентированное программирование предлагает устойчивый способ написания спагетти-кода. Оно позволяет вам накапливать программы в виде серии патчей. Крупные организации всегда склонны разрабатывать программное обеспечение таким образом, и я ожидаю, что через сто лет это будет так же верно, как и сегодня.
Пока мы говорим о будущем, нам лучше поговорить о параллельных вычислениях, потому что именно там, похоже, живет эта идея. То есть, когда бы вы ни говорили, параллельные вычисления кажутся чем-то, что произойдет в будущем.
Догонит ли когда-нибудь будущее? Люди говорят о параллельных вычислениях как о чем-то неизбежном уже по крайней мере 20 лет, и до сих пор это не сильно повлияло на практику программирования. Или нет? Уже сейчас разработчики чипов вынуждены думать об этом, как и люди, пытающиеся написать системное программное обеспечение для многопроцессорных компьютеров.
Настоящий вопрос заключается в том, как далеко вверх по лестнице абстракции зайдет параллелизм? Через сто лет он затронет даже прикладных программистов? Или это будет что-то, о чем думают авторы компиляторов, но что обычно незаметно в исходном коде приложений?
Одно кажется вероятным - большинство возможностей для параллелизма будет упущено. Это частный случай моего более общего предсказания о том, что большинство дополнительных компьютерных мощностей, которые мы получаем, будут потрачены впустую. Я ожидаю, что, как и в случае с потрясающей скоростью базового оборудования, параллелизм будет чем-то доступным, если вы явно попросите об этом, но обычно не используемым. Это подразумевает, что вид параллелизма, который мы будем иметь через сто лет, не будет, за исключением специальных приложений, массивным параллелизмом. Я ожидаю, что для обычных программистов это будет скорее возможность разделять процессы, которые в итоге будут выполняться параллельно.
И это, как и запрос конкретных реализаций структур данных, будет чем-то, что вы делаете довольно поздно в жизни программы, когда вы пытаетесь ее оптимизировать. Версии 1 обычно игнорируют любые преимущества, которые можно получить от параллельных вычислений, точно так же, как они игнорируют преимущества, которые можно получить от конкретных представлений данных.
За исключением специальных приложений, параллелизм не проникнет в программы, которые будут написаны через сто лет. Это было бы преждевременной оптимизацией, если бы это произошло.
Сколько языков программирования будет через сто лет? В последнее время появилось огромное количество новых языков программирования. Отчасти это объясняется тем, что более быстрое оборудование позволяет программистам находить различные компромиссы между скоростью и удобством в зависимости от конкретного приложения. Если это действительно тенденция, то аппаратное обеспечение, которое мы будем иметь через сто лет, должно только усилить ее.
И все же, возможно, через сто лет останется всего несколько широко используемых языков. Отчасти я говорю это с оптимизмом: кажется, что, если бы вы действительно хорошо поработали, вы могли бы создать язык, который идеально подходит для написания медленной версии 1, но при правильных рекомендациях компилятору по оптимизации, при необходимости, даст очень быстрый код. Итак, поскольку я оптимист, я предскажу, что, несмотря на огромный разрыв между приемлемой и максимальной эффективностью, через сто лет у программистов будут языки, способные преодолеть большую его часть.
По мере того, как этот разрыв будет увеличиваться, профилировщики будут приобретать все большее значение. Сейчас профилированию уделяется мало внимания. Многие люди все еще верят, что способ получить быстрые приложения - это написать компиляторы, которые генерируют быстрый код. По мере того как разрыв между приемлемой и максимальной производительностью увеличивается, становится все более очевидным, что способ получения быстрых приложений - это хороший проводник от одного к другому.
Когда я говорю, что языков может быть всего несколько, я не имею в виду "маленькие языки", специфичные для конкретной области. Я думаю, что такие встроенные языки - отличная идея, и я ожидаю, что они будут распространяться. Но я ожидаю, что они будут написаны под достаточно тонкой оболочкой, чтобы пользователи могли видеть под ней язык общего назначения.
Кто будет разрабатывать языки будущего? Одной из самых интересных тенденций последних десяти лет стал подъем языков с открытым исходным кодом, таких как Perl, Python и Ruby. Проектирование языков переходит в руки хакеров. Результаты пока беспорядочные, но обнадеживающие. В Perl, например, есть несколько потрясающе новых идей. Многие из них потрясающе плохи, но это всегда верно для амбициозных усилий. При нынешней скорости мутаций Бог знает, во что может превратиться Perl через сто лет.
Неправда, что те, кто не умеет делать, учат (некоторые из лучших хакеров, которых я знаю, - профессора), но правда, что есть много вещей, которые не умеют делать те, кто учит. Исследования накладывают сдерживающие кастовые ограничения. В любой научной области есть темы, над которыми можно работать, а есть те, над которыми нельзя. К сожалению, различие между приемлемыми и запрещенными темами обычно основано на том, насколько интеллектуально звучит работа при описании в научных статьях, а не на том, насколько она важна для получения хороших результатов. Крайним случаем, вероятно, является литература; люди, изучающие литературу, редко говорят что-то, что может быть полезно тем, кто ее создает.
Хотя в науке ситуация лучше, совпадение между видом работы, которую вам разрешено делать, и видом работы, которая дает хорошие языки, катастрофически мало. (Олин Шиверс красноречиво ворчал по этому поводу.) Например, типы кажутся неисчерпаемым источником исследовательских работ, несмотря на то, что статическая типизация, похоже, исключает истинные макросы - без которых, по моему мнению, ни один язык не стоит использовать.
Тенденция заключается не только в том, что языки разрабатываются как проекты с открытым исходным кодом, а не как "исследования", но и в том, что языки разрабатываются прикладными программистами, которые должны их использовать, а не авторами компиляторов. Это хорошая тенденция, и я ожидаю, что она продолжится.
В отличие от физики через сто лет, которую практически невозможно предсказать, я думаю, что в принципе возможно разработать язык сейчас, который будет интересен пользователям через сто лет.
Один из способов разработки языка - просто написать программу, которую вы хотели бы иметь возможность написать, независимо от того, существует ли компилятор, который может ее перевести, или аппаратное обеспечение, которое может ее выполнить. Когда вы это делаете, вы можете предположить, что ресурсы неограниченны. Кажется, что мы должны быть в состоянии представить неограниченные ресурсы как сегодня, так и через сто лет.
Какую программу хотелось бы написать? Любую, которая требует меньше всего работы. Только не совсем: любую, которая была бы наименее трудоемкой, если бы ваши представления о программировании не были уже под влиянием языков, к которым вы привыкли. Это влияние может быть настолько сильным, что для его преодоления требуются большие усилия. Можно подумать, что для таких ленивых существ, как мы, очевидно, как выразить программу с наименьшими усилиями. На самом деле, наши представления о возможном настолько ограничены тем языком, на котором мы думаем, что более простые формулировки программ кажутся очень удивительными. Это то, что вы должны открыть для себя, а не то, к чему вы естественно погружаетесь.
Один из полезных приемов здесь - использовать длину программы в качестве приблизительного показателя того, сколько работы по ее написанию. Не длину в символах, конечно, а длину в отдельных синтаксических элементах - по сути, размер дерева разбора. Возможно, не совсем верно, что самая короткая программа требует меньше всего работы по написанию, но это достаточно близко, чтобы лучше стремиться к твердой цели краткости, чем к нечеткой, близкой цели наименьшей работы. Тогда алгоритм разработки языка становится следующим: посмотрите на программу и спросите, есть ли способ написать ее короче?
На практике написание программ на воображаемом столетнем языке будет работать в разной степени в зависимости от того, насколько близко вы находитесь к ядру. Сортировочные рутины вы можете писать уже сейчас. Но сейчас трудно предсказать, какие библиотеки могут понадобиться через сто лет. Предположительно, многие библиотеки будут предназначены для доменов, которые еще даже не существуют. Например, если SETI@home будет работать, нам понадобятся библиотеки для общения с инопланетянами. Если, конечно, они не настолько развиты, что уже общаются на XML.
С другой стороны, я думаю, что вы можете разработать основной язык уже сегодня. На самом деле, некоторые могут утверждать, что он уже был в основном разработан в 1958 году.
Если бы язык столетней давности был доступен сегодня, захотели бы мы программировать на нем? Один из способов ответить на этот вопрос - оглянуться назад. Если бы современные языки программирования были доступны в 1960 году, захотел бы кто-нибудь их использовать?
В некотором смысле, ответ отрицательный. Современные языки предполагают наличие инфраструктуры, которой не существовало в 1960 году. Например, язык, в котором отступы имеют большое значение, такой как Python, не очень хорошо работает на принтерных терминалах. Но если отбросить эти проблемы - предположим, например, что все программы были написаны на бумаге - понравилось бы программистам 1960-х годов писать программы на языках, которые мы используем сейчас?
Думаю, да. Некоторые из менее изобретательных, у которых артефакты ранних языков были встроены в их представления о том, что такое программа, могли бы столкнуться с проблемами. (Как можно манипулировать данными, не выполняя арифметику с указателями? Как можно реализовать блок-схемы без гото?) Но я думаю, что у самых умных программистов не было бы проблем с использованием современных языков, если бы они у них были.
Если бы у нас сейчас был язык столетней давности, из него, по крайней мере, получился бы отличный псевдокод. А как насчет того, чтобы использовать его для написания программ? Поскольку столетний язык должен будет генерировать быстрый код для некоторых приложений, предположительно, он сможет генерировать код, достаточно эффективный, чтобы работать приемлемо хорошо на нашем оборудовании. Возможно, через сто лет нам придется давать больше советов по оптимизации, чем пользователям, но это все равно может быть чистым выигрышем.
Теперь у нас есть две идеи, которые, если их объединить, предлагают интересные возможности: (1) язык столетней давности, в принципе, может быть разработан сегодня, и (2) такой язык, если он существует, может быть хорошим для программирования сегодня. Когда видишь эти идеи в таком виде, трудно не подумать: почему бы не попробовать написать столетний язык сейчас?
Когда вы работаете над созданием языка, я думаю, что хорошо иметь такую цель и сознательно помнить о ней. Когда вы учитесь водить машину, один из принципов, которому вас учат, заключается в том, чтобы выравнивать автомобиль не путем совмещения капота с полосами, нарисованными на дороге, а путем прицеливания в какую-то точку вдали. Даже если вас волнует только то, что произойдет в следующих десяти футах, это правильный ответ. Я думаю, что мы можем и должны сделать то же самое с языками программирования.
Примечания
Я считаю, что Lisp Machine Lisp был первым языком, воплотившим принцип, согласно которому объявления (за исключением объявлений динамических переменных) были всего лишь советами по оптимизации и не меняли смысла корректной программы. Common Lisp, кажется, был первым, кто заявил об этом явно.