Гиллель Уэйн*, разработчик и консультант по формальной верификации, обратил внимание на статью «20 наиболее значимых языков программирования в истории», которую сам автор называет «нелепой, только что придуманной таблицей». По мнению Уэйна, эта характеристика вполне справедлива: автор таблицы называет Go «наиболее значимым», но не включает в список ALGOL, Smalltalk или ML. И не учитывает Pascal, потому что тот «почти мёртв». Абсурд! Это противоречит всей сути понятия «значимость в истории».
Так давайте обсудим некоторые «почти мёртвые» языки и причины их важности.
Дисклеймер: Да, не все из этих языков мертвы и забыты. Ведь большинство людей слышали о Smalltalk, правда? Также, скорее всего, в этой статье полно ошибок, ведь их легко допустить, когда вы анализируете 60-летнюю историю компьютерных вычислений. Не стесняйтесь возражать, если что-то заметите!
Дисклеймер 2: Да, некоторые из упомянутых здесь языков были «первыми изобретёнными», а другие — «первыми популярными». История — это сложно!
*Обращаем ваше внимание, что позиция автора может не всегда совпадать с мнением МойОфис.
Определение влияния
Небольшое предисловие о том, что стоит понимать под «влиянием». Простой факт того, что X был первым языком с функцией Z, не означает, что X действительно оказал влияние на Z. Несмотря на то что Absys, возможно, стал первым языком логического программирования, его большая часть строится на разработанном независимо Prolog. В конечном итоге есть только один точный показатель того, повлиял ли X на Y: цитирование. Что означает один из следующих вариантов:
Y ссылается на X в своем справочном руководстве
Y ссылается на статью, которая цитирует X
Автор Y заявляет: «На нас повлиял X»
Цитирование происходит по цепочке. Иногда в руководстве по языку Q упоминается документ R, который в свою очередь называет источником вдохновения статью S, где говорится о заимствовании идей из языка T. Таким образом, мы понимаем, что T оказал влияние на Q, даже если цепочка довольно длинная. Следовательно, для поиска нужной информации требуется изучить большое количество источников. Чтобы ускорить процесс, мы определяем область поиска с помощью эвристики.
Одним из эффективных методов является изучение сходств языков программирования. Крайне редко языки самостоятельно приходят к одинаковому синтаксису. Так что если два языка имеют схожий синтаксис, вероятно, один из них повлиял на другой. Например: даже не зная о проектных решениях Матца, мы понимаем, что на Ruby оказал влияние Smalltalk, так как оба языка используют метод select
для фильтрации списка. Это не решающее доказательство. Возможно, разработка Матца независима, или же и на Ruby, и на Smalltalk повлиял один и тот же предшественник. Но оно дает нам точку отсчёта для начала поиска.
Языки
COBOL
Происхождение: CODASYL, 1960. COBOL сформировался в результате разделения разработки для бизнеса и науки. Тогда промышленные языки высокого уровня применялись либо для инженерных расчетов, либо для работы с данными. Все инженеры выбрали FORTRAN, в то время как в бизнес-сфере царил хаос из COMTRAN, FLOW-MATIC и других, поэтому Министерство обороны собрало комитет для создания единого универсального бизнес-языка. И им стал COBOL.
Он был одним из четырёх «родительских» языков, вместе с ALGOL, FORTRAN и LISP. Сегодня мы считаем его заурядным, но когда-то он был самым популярным языком в мире. На нём до сих пор работают многие из поддерживаемых бизнес-систем.
Значение: Синтаксис и семантика COBOL редко встречаются в современных вычислениях. Самым значительным нововведением COBOL является концепция структуры данных. В FORTRAN и ALGOL единственной доступной структурой данных был статический массив. Однако в COBOL можно было загружать структурированные файлы с иерархическими данными, которые автоматически преобразовывались в соответствующие переменные. Это стало предвестником современных структур данных.
Причина упадка: Сыграли два основных фактора. Первый: COBOL не перекликался с другими проектами PLT. На COBOL разрабатывали очень немногие. А значит, что вторые и третьи поколения языков, основанные на уроках своих предшественников, его почти не использовали. Это связано не столько с проблемами самого COBOL, сколько с результатом пренебрежительного отношения академического сообщества к процессу его создания. Организация CODASYL была коммерческой и, очевидно, не заслуживала внимания. К тому же, COBOL чрезвычайно сложен даже по меркам современных языков. Компиляторы COBOL отставали от своих современников на микро- и миникомпьютерах, что позволило другим языкам развиться и в конечном итоге выйти вперёд.
ALGOL
Происхождение: Комитет ALGOL, 1960 год. ALGOL-58 был выпущен на два года ранее, но быстро устарел, поэтому здесь я их объединяю. Комитет стремился создать хороший язык для исследования алгоритмов. Иными словами, ALGOL представлял собой формализованный «псевдокод».
Среди четырёх основных языков наиболее «мёртвым» является ALGOL; все ещё знают о LISP, COBOL до сих пор поддерживает множество старых систем, а большинство научных пакетов используют FORTRAN. Но я знаю множество программистов, которые даже не слышали об ALGOL. Может показаться, что это наименее важный из основных языков, но на самом деле наоборот. Из четырёх языков только LISP близок к ALGOL по своей всепроникающей значимости.
Значение: Итак, лексическая область действия, структурное программирование, вложенные функции, формальные спецификации языка, семантика вызова по имени, грамматики БНФ, блочные комментарии... ALGOL глубоко затронул каждый современный язык.
Причина упадка: ALGOL был языком для исследований, а не коммерческим инструментом. Он создавался для анализа алгоритмов. В спецификации не было указано ни одного инструмента для ввода-вывода, из-за чего, по сути, его невозможно использовать в реальности. Разумеется, можно было создать расширение для компилятора, но с тем же успехом можно было бы добавлять и прочую функциональность.
Именно так люди и поступили. В 1960-70-х годах было разработано множество языков, похожих на ALGOL, которые расширяли его возможности за счёт ввода-вывода и дополнительных структур данных. Сюда входят JOVIAL, SIMULA, CLU и CPL. Созданные позднее языки основывались на этих расширениях, а не на самом ALGOL. Мы называем C «подобным ALGOL», но на самом деле он подобен BCPL, который подобен CPL, который подобен ALGOL. ALGOL похоронили его потомки.
Впоследствии авторы попытались модернизировать его до ALGOL-68, который кардинально отличался от ALGOL-60 и не имел такого же влияния. Развивать направление ALGOL-60 продолжил Паскаль Никлауса Вирта.
APL
Происхождение: Кен Айверсон, 1962 год. Сначала это была рукописная нотация для записи математических действий с массивами, но затем IBM использовала её как язык программирования. В качестве языка APL сосредоточился на обработке массивов, предоставляя возможность сжато управлять большими блоками чисел.
Если вы уже слышали о APL, то, вероятно, помните его как «тот странный язык с символами». Одним из самых знаменитых фрагментов кода является реализация игры «Жизнь»:
Для его написания требовалась вот такая специализированная клавиатура:
Тем не менее, APL стал популярен на мейнфреймах, так как для работы требовал очень мало оперативной памяти.
Значение: Обработка массивов. В эпоху, когда сложение двух списков чисел подразумевало использование map или цикла, APL предложил идею оперирования над всем массивом одновременно. Вот пример:
Это стало настоящим прорывом в научном сообществе. Большая часть прикладной математики сводится к операциям над большими матрицами. Получение внешних произведений становится невероятно простым, когда можно просто взять внешнее произведение с помощью ∘.f!
Нововведение APL привело к созданию R, numpy, pandas, Matlab и т.д. Также есть прямые наследники APL: J, Dyalog, K, Q. Они не столь успешны, но активно используются в финансовом секторе.
Причина упадка: очевидно, проблема в клавиатурах. Если нет возможности писать код на ASCII, много написать и не получится. Иверсон решил эту проблему в J, где вместо различных символов используются диграфы. Вместо ≠ используется ~:. Но это случилось в 1990 году, довольно поздно для популяризации радикально нового стиля программирования.
Менее заметная проблема заключается в том, что APL и J работали только с однородными данными. Нельзя хранить строки и числа в одной структуре данных (если не использовать ячейки, что уже совсем другая история), а работа со строками обычно превращается в кошмар. Так что никаких датафреймов, что исключает большую часть современной науки о данных.
Дополнительная информация: Notation as a Tool of Thought
BASIC
Происхождение: Джон Кемени, 1964 г. Изначально это был упрощённый аналог FORTRAN, созданный для помощи в использовании компьютеров людям, не связанным с инженерией.
BASIC по-настоящему расцвёл в эпоху микрокомпьютеров. Первые из них не обладали достаточным объёмом памяти для компиляции программ на «полноценных» языках программирования, в то время как упрощённый компилятор BASIC можно было уместить примерно в 2 килобайта. Он стал общепринятым языком начинающих программистов. Если вы занимались программированием дома в 1970-х, то, вероятнее всего, писали на BASIC на микрокомпьютере.
Значение: BASIC стал первым языком с интерпретатором в режиме реального времени (Dartmouth Time Sharing System), опередив APL на год. А поскольку система APL была доступна только для клиентов IBM, долгое время выбор стоял между BASIC и ничем.
BASIC привнёс программирование в быт, особенно среди детей. Многие программисты 80-х и 90-х годов, в будущем ставшие влиятельными специалистами, впервые освоили программирование именно на BASIC. Множество корпоративных систем также были написаны на BASIC, что, вероятно, поспособствовало скорому упадку Cobol.
У BASIC есть еще одно интересное применение: инструменты Office. В конечном итоге Microsoft превратила BASIC в Visual Basic, который использовался как язык макросов Office. Затем это распространилось на OpenOffice и LibreOffice, укрепив позиции BASIC в конкретной области. Недавно он уступил позиции JavaScript и теперь считается устаревшим языком написания макросов.
Причина упадка: BASIC воспринимали как «второстепенный» язык. Его могли использовать дети или владельцы малого бизнеса, но настоящие программисты предпочитали настоящие языки. Когда производители смогли производить недорогие микрокомпьютеры с более чем 16 Кбайт оперативной памяти, то разработчики стали отказываться от BASIC в пользу языков типа Pascal и C.
BASIC некоторое время продолжал существовать как язык для обучения детей, но, кажется, затем освободил и эту нишу.
PL/I
Происхождение: IBM, 1966 год. В работе IBM применялись два языка: FORTRAN для ученых и COMTRAN для бизнесменов. Столкнувшись с конкуренцией COBOL и стремясь упростить системы, компания попыталась создать язык, который был бы полезен как для инженерных, так и для бизнес-целей. В результате получился своего рода суперсет двух языков с множеством дополнительных функций сверху. Теперь все могли использовать один и тот же язык, а IBM зарабатывала гораздо больше денег! Урааааааа
Значение: Авторы ALGOL-68 иронически называли PL/I устаревшим языком. Но все достижения ALGOL-68 в PL/I были реализованы раньше и лучше. Хотя COBOL первым получил структурированные данные, PL/I впервые реализовал их как тип данных. В COBOL чтение пользователя с именем приводило к появлению двух глобальных переменных — user
и name
. В PL/I это была бы одна переменная с полем user.name
. PL/I стал первым языком высокого уровня, в котором появились указатели для прямого управления памятью, константы и перегрузка функций.
Многие из этих концепций были внедрены в современное программирование через язык C, являющийся сочетанием BCPL и PL/I. Синтаксис комментариев в C также взят из PL/I.
Причина упадка: программисты FORTRAN считали его слишком похожим на COBOL, а программисты COBOL — на FORTRAN. IBM попыталась предложить в качестве альтернативы двум распространённым языкам один, значительно более сложный. Также успеху не способствовало то, что они были единственными разработчиками компилятора — это вызывало недоверие из-за зависимости от одного производителя. Когда IBM наконец преуспела в решении этих проблем, мир компьютерных технологий уже перешёл к эре микрокомпьютеров, где PL/I уступил BASIC.
Дополнительная информация: The Choice of PL/I
SIMULA 67
Происхождение: Оле Даль и Кристен Нюгаард, 1967 год. Они модифицировали ALGOL для моделирования симуляций. Сначала разработали SIMULA I, имевший специализированный синтаксис для моделирования и выполнения задач. SIMULA I нашел применение на ранних этапах, но оба автора были недовольны «специализированностью» языка и большим количеством дублирующего кода в моделях. Они стремились создать более универсальную систему для описания объектов в целом, а не только для моделирования.
Концепция заключалась в том, что пользователи могли задавать новые типы, называемые «классами», с полиморфным разрешением функций. А затем — создавать функции моделирования как частный случай объектной системы, что упрощало бы настройку того, как все это работает, в соответствии с их конкретными потребностями.
Значение: Несмотря на то, что SIMULA не был первым «истинным» языком ООП, он стал первым языком с полноценными объектами и заложил основу, на которой строились последующие языки. В том числе разделение на классы и объекты, подклассы, виртуальные методы и защищённые атрибуты. Он стал источником вдохновения для большинства академических исследований в области объектов после 1967 года. Как CLU, так и ML указывали SIMULA в качестве источника основного влияния. Бьёрн Страуструп написал докторскую диссертацию по SIMULA, в конечном итоге многие идеи SIMULA были внедрены в язык C++.
Причина упадка: В докторской диссертации Страуструп заявил, что SIMULA слишком медленный для использования в больших масштабах. Медленный в духе «Удачи с выполнением задач, если не используете мейнфрейм». Стоит отметить, что Smalltalk-80, который развил эти идеи дальше, имел преимущество в виде дополнительных 13 лет действия закона Мура. И даже Smalltalk часто критиковали за излишнюю медлительность. Идеи, которые были в SIMULA, начали внедрять в более простые быстрые языки.
Pascal
Происхождение: Никлаус Вирт, 1970 год. Создан, чтобы сохранить суть ALGOL-60 после того, как ALGOL-68 показался Вирту слишком сложным. Сперва стал известен как язык «введения в computer science», и к началу 80-х годов стал вторым по популярности языком на досках объявлений о работе Usenet. Вирт рассматривал всё семейство — Pascal, Modula и Oberon — как единую концепцию языка.
Значение: Pascal не представил ни одной совершенно новой идеи. Это был намеренно консервативный язык, который стремился собрать и объединить в своих рамках лучшее из прошедшего десятилетия. Pascal вынес синтаксис ALGOL за пределы академического мира, и синтаксис присваивания ALGOL, :=, стал известен как «стиль Pascal». С этого момента большинство языковых особенностей, напоминающих ALGOL, скорее всего, были вдохновлены не им, а Pascal.
Хотя сам Pascal не был особенно инновационным, его разновидности такими были. Вирт также стал пионером концепции «пошагового улучшения» как метода написания совершенного программного обеспечения. В конечном итоге это привело к созданию Modula, который популяризовал модули первого класса, и Euclid — первого формального языка верификации, используемого на практике.
Причина упадка: В отличие от большинства других языков в списке, у Pascal не было серьезных структурных препятствий или сильного конкурента. Да, он конкурировал с C, но всё равно успешно существовал долгое время. Обычно говорят об эссе Why Pascal is not my favorite language («Почему Pascal не мой любимый язык»), но это слишком простой ответ, а история гораздо сложнее. Также довольно высокие места в рейтингах TIOBE и PYPA до сих пор занимает Delphi, так что Pascal не настолько мёртв, как тот же SIMULA. Точный же анализ упадка Pascal занял бы больше места, чем остальная часть данного эссе.
Дополнительная информация: Pascal and its Successors
CLU
Происхождение: Барбара Лисков, 1975 г. Лисков хотела поэкспериментировать с абстрактными типами данных. Вот и всё. Вот в чем суть CLU.
Значение: CLU, возможно, самый влиятельный язык, о котором никто не слышал. Итераторы? CLU. Абстрактные типы данных? CLU. Дженерики? CLU. Проверяемые исключения? CLU.
Существуют расхождения в терминологии, и может быть не совсем очевидно, что все это исходит именно от CLU, и тем не менее. Каждая языковая спецификация следующего десятилетия будет ссылаться на CLU. CLU сделал многое.
Причина упадка: CLU был демонстрационным языком; Лисков хотела, чтобы люди приняли ее идеи, а не конкретный язык. Так и случилось: почти каждый современный язык чем-то обязан CLU. Завершив работу над CLU, Лисков перешла к Argus, который должен был продемонстрировать идеи о параллелизме. Он не получил такого же признания, и в нём еще много нераскрытого.
Дополнительная информация: A History of CLU
ML
Происхождение: Робин Милнер, 1976 г. Милнер разрабатывал LCF Prover, одну из первых систем автоматического доказательства теорем. Если вы составили доказательство в правильном формате, LCF мог проверить его корректность. Чтобы помочь в написании доказательств, Милнер создал метаязык, основанный на надежных математических формализмах, что в то время означало строгие статические типы и функции высшего порядка. В конце концов ML был стандартизирован как Standard ML.
Значение: ML можно считать самым старым «алгебраическим языком программирования». С ML связывают очень многое: алгебраические типы данных, модули, типизированное функциональное программирование. Удивительно, но он не был первым во всех этих аспектах! Первый ML разрабатывался только для LCF и не являлся языком общего назначения, поэтому не обладал многими из этих функций. Когда люди начали делать его более универсальным, то стали внедрять идеи из других исследовательских языков. Однако, одна очень важная идея зародилась именно в ML: вывод типов. ML стал первым статически-типизированным языком, где не требовалось указывать типы, поскольку компилятор определял их самостоятельно. Это проложило путь типизированного функционального программирования за пределы академической среды и в производство.
ML также существенно повлиял на современные системы доказательства теорем. Языки программирования для Isabelle, CVC3 и Coq основаны на ML. Многие аспекты теории типов были основаны на ML, хотя в последние годы в области функционального программирования все больше признания получает Haskell.
Smalltalk
Происхождение: Алан Кэй, 1972, 1976 и 1980 гг. Smalltalk-72 стал первым, Smalltalk-76 представил миру концепцию «объектно-ориентированного программирования», а Smalltalk-80 получил широкое распространение.
Smalltalk не был первым языком с объектами, но стал первым «объектно-ориентированным». Разница в том, что в Simula объекты дополняли примитивы, такие как числа и булевые значения, в то время как в Smalltalk даже булевые значения были объектами. Если хотите узнать больше, я кое-что написал здесь.
Значение: Иногда кажется, что Smalltalk — это «истинный» язык ООП, а такие языки как Java и Python — нет, но это не верно. ООП, как и любая другая парадигма, является продуктом множества различных влияний. Но язык определенно популяризовал саму идею. Если вы откроете любую книгу по общей теории ООП из середины 80-х или начала 90-х, она будет на Smalltalk. Кто-то переведёт свои примеры на C++, некоторые — на другие языки, но все будут использовать Smalltalk.
Smalltalk также популяризовал идею о объектах как о передаваемых данных, что привело к появлению CORBA, и вдохновил создание модели Actor.
Причина упадка: Общепринято считать, что Smalltalk проиграл из-за распространения C++. Но это не правда. У Smalltalk действительно были некоторые проблемы, в частности, сложность взаимодействия с другими инструментами и низкая производительность. Но даже в 1990-е годы Smalltalk использовался активно, и многие предполагали, что он станет доминирующим языком в бизнесе.
А потом появился Java.
Smalltalk не стал единственной жертвой «Java-покалипсиса»: Java также отодвинул на задний план Eiffel, Ada95 и почти все остальное в мире ООП. Интересный вопрос не в том, почему Smalltalk умер, а почему C++ остался в живых. Я полагаю, потому что C++ был лучше совместим с C, что облегчало его интеграцию в существующие системы.
***
Это лишь малая часть важных и почти умерших языков. Я не затрагивал ALPHARD, ALTRAN, Argus, Automath, BCPL, COMTRAN, CPL, Eiffel, FLOW-MATIC, HOPE, Hypercard, ISWIM, JOVIAL, MacSyma, Mesa, Miranda, Multics Shell, PLANNER, SMP, Sketchpad или SNOBOL. Каждый из них внёс свой уникальный вклад в современное программирование. История — это сложно.
Большинство влиятельных языков так и не стали популярными. Немногие использовали хотя бы один из них. Но каждый из них вдохновил людей, которые в свою очередь вдохновили других; так ДНК забытых языков появляется спустя десятилетия после их забвения. Существует также бесчисленное количество языков, идеи которых так и не были реализованы. «Энциклопедия языков программирования» насчитывает более 8000 языков. Многие из них содержали идеи, которые в дальнейшем не нашли развития. Представьте, сколько бы мы упустили, если бы никто не узнал о SIMULA или Лисков не представила бы CLU!
Вот почему мне так нравится изучать историю. Понимать, что мы потеряли, и находить это снова.
Благодарю Миикку Коскинена, Кевлина Хенни, Эрика Фишера и Леви Пирсона за их корректировки и отзывы.