Журнал «Компьютерра» - Журнал «Компьютерра» N 8 от 27 февраля 2007 года (Компьютерра - 676)
Диффузия идей модернистских языков в программистское сообщество происходит с двух направлений — через постепенное изменение «классицистических» языков и через появление языков абсолютно новых, которые можно назвать постмодернистскими [Мы не станем дальше углубляться в искусствоведческую метафору: определения программистского рококо, романтизма, экспрессионизма, кубизма и абстракционизма оставим в качестве развлечения для читателя] (OCaml, Python, Ruby, Scala). «Постмодернистские» языки выходят за рамки стилей и парадигм, смешивая старые и новые идеи в разных пропорциях; зачастую жертвуют концептуальной целостностью ради выразительности и поливариантности возможностей. На уровне отдельных «фраз» многие из постмодернистских языков выглядят просто и понятно любому программисту, отчего их проникновение в мэйнстрим идет куда легче, чем у «более идейных» предшественников. А тем временем и сами мэйнстримовые языки стремительно впитывают новые идеи: подобно миру искусства, в мире программирования широкое наступление постмодернизма характеризуется смешением стилей и парадигм до их полной неразделимости.
Объект исследования темы этого номера — языки программирования, которые в разное время и в разных условиях предлагались и предлагаются как альтернатива привычному, мэйнстримовому, и общепринятому; их судьба, свойства и шансы. В первой обзорной статье вкратце описывается история самого мэйнстрима — без понимания перипетий смены одного языка другим рассмотрение «альтернативы» бессмысленно. Вторая статья посвящена языкам модернистским, а третья — постмодернистским. Каждая из трех частей отслеживает развитие соответствующей ветки истории; таким образом, должна получиться некая общая картина сегодняшнего состояния дел (возможно, несколько перекошенная, и наверняка неполная).
И последнее. В соответствии с главным принципом киберпанка «будущее уже здесь, просто оно неравномерно распределено» — разные течения в программировании очень трудно разделить хронологически; первый модернистский язык программирования — Lisp — один из старейших (1958 год, из общеизвестных старше только Fortran), да и очевидно постмодернистский Perl скоро справит двадцатилетний юбилей. Поэтому деление языков программирования (и темы номера) на «классицизм», «модернизм» и «постмодернизм» происходит скорее «вдоль» истории, нежели «поперек».
С этим и начнем.
Генеральная линия: От Fortan до C#
Автор: Виктор Шепелев
Как уже было сказано, подавляющее большинство языков программирования из «настоящего мэйнстрима» ведут свою идеологическую родословную напрямую из машинного языка/ассемблера. Конечно, по этому пути они успели зайти далеко, но каждый следующий шаг был лишь логическим продолжением предыдущего.
В этом «естественном развитии» популярных языков новые концепции вводились путем постепенного «уточнения парадигмы»: новые возможности вводятся как почти «синтаксический сахар» (более краткая, удобная и понятная альтернатива существующим конструкциям, ничего принципиально не меняющая), но возникающие нюансы и вопросы и разрешение этих нюансов и вопросов приводит к формулировке новых идей [Для примера: использование именованных переменных вместо регистров и адресов памяти поднимает вопросы о типах данных; структуризация кода с помощью процедур и модулей порождает вопрос «области видимости» переменных, а также разницы между «передачей по ссылке» и «передачей по значению»; и т. п.].
Господствующая парадигма [Любим мы это слово. По большому счету, оно означает «подход», «модель построения программы или ее частей», «способ думать об архитектуре программы» — что-то в этом духе] — программирование императивное: программа — суть набор инструкций «сделай то, потом сделай это», результаты действий сохраняются и изменяются в именованных ячейках — «переменных». Отслеживая историю развития промышленного программирования, можно заметить, что все новые «победившие» языки развивали, а не опровергали эту парадигму.
Первым [Попытки «автоматизировать программирование» были и до Фортрана — «язык» A-0 для компьютера UNIVAC (1952), экспериментальный «транслятор формул», созданный в MIT (1954); но эти реализации показывали чудовищную неэффективность сгенерированного машинного кода, что породило стереотип «никакая автоматизация не сможет заменить человека-программиста, пишущего на ассемблере». Фортран этот стереотип разрушил] реально используемым высокоуровневым языком программирования стал Fortran [Имена ранних языков программирования, как правило, писались большими буквами (FORTRAN, COBOL, ALGOL, LISP…). Причина тут не в склонности к аббревиатурам (довольно вымученным, вроде FORmula TRANslator), а убогость тогдашних средств ввода/вывода, зачастую оснащенных только шрифтами с заглавными буквами. «Как правильно» писать название языка — иногда непонятно и самим авторам, пишут и так и эдак. Мы предпочли вариант, более симпатичный с типографской точки зрения (кроме случаев, когда название языка — явная аббревиатура: PL/I, PHP)] (первое описание — 1954, первая реализация — 1957). В немалой степени перво-Fortran — это «подсахаренный» ассемблер; но это был огромный шаг вперед, хотя бы в том смысле, что вычисление A+BхC можно было записать так, как понятно математику, а не как набор операций по загрузке значений в регистры и вычисления ответов в других регистрах.
Проблемы со структурой программ на Фортране (вкратце: структуры не было) привели к разработке языка Algol (1958). Судьба его весьма показательна: совместная разработка американских и европейских ученых, к которой приложили руку многие «легенды» IT; в процессе работы над Алголом были разработаны концепции структурного программирования (логические структуры для ветвления кода; разбиение программы на процедуры, положившее начало созданию библиотек кода для повторного использования, и т. п.); следующие тридцать лет Алгол будет де-факто стандартом для описания алгоритмов. При этом уклон авторов Алгола в «теорию» (эффективного компилятора нет; стандартных операторов ввода-вывода нет) привел к тому, что использование этого языка в промышленном программировании было мизерным.
Из первоязыков еще стоит упомянуть Cobol (1959), чудовищный как язык, но крайне успешный как платформа для создания бизнес-приложений. Что показательно.
Следующее десятилетие — эпоха экспериментов на ниве создания «самого лучшего языка». В широком использовании продолжают царствовать Fortran/Cobol, к ним добавляются языки класса «все-все-все-в-одном» PL/I и CPL [В этот же период созданы Lisp и Snobol, речь о которых — в следующей статье], тяжелые и для изучения, и для реализации. В районе 70-х происходит первая «большая чистка»: парк компьютеров растет лавинообразно, возникает необходимость в языках простых и практичных, которые легко выучить, легко реализовать под различные аппаратные платформы, легко писать и читать код; при этом возрастает количество «программ-ради-программ», не решающих некую бизнес-задачу, а облегчающие работу с самим компьютером.
Си вкупе с Unix; разномастные Бейсики как встраиваемые языки для первых домашних (и мелких недомашних) компьютеров; Pascal в Apple II/Apple III, чуть позже Паскали от фирмы Borland для простого написания программ под DOS, Windows — все это языки весьма простые [Basic, в частности, настолько прост, что даже структурного программирования в нем не было. Зато это давало возможность сделать крайне нетребовательную к ресурсам реализацию языка, что поспособствовало его распространению на «несерьезных» компьютерах. С ростом ресурсов этих компьютеров (и запросов программистов) структурность в Бейсике появилась (в середине 80-х)] и практичные; это, по большому счету, те языки, с которыми программирование стало действительно массовым занятием.
По мере расширения круга задач, решаемых на «простых» языках, количества повторно используемых библиотек и «времени жизни» этих библиотек стали возникать концепции более сложного структурирования кода. Самая популярная из них — объектно-ориентированное программирование; совмещение концепций «набора процедур и данных (модуля)» и «типа данных со сложной внутренней структурой» дало понятие «класса» и «объекта» [Большая часть концепций классического ООП была разработана в середине 60-х в рамках работы над языком Simula (Ole-Johan Dahl, Kristen Nygaard). Судьба его достаточно близка к судьбе Алгола: разработанные концепции были приняты и воплощены во многих успешных проектах, но сам язык использовался весьма ограниченно]. Мэйнстримовая разновидность ООП [О более радикальном наборе концепций с тем же названием — в следующей статье.9 Интересно, что другая разновидность «объектно-ориентированного C», известная под именем Objective C и зачастую воспринимаемая как забавный курьез, была языком вполне постмодернистским, смешавшим концепции классического C и модернистского Smalltalk. Распространение этого (и других «странных») языков исключительно в мире Apple весьма показательно] — естественное эволюционное развитие структурно-императивного подхода. Неудивительно, что и объектно-ориентированные языки, принятые «широкими массами», были естественным развитием все тех же C, Pascal, Basic — Visual Basic, C++ [Интересно, что другая разновидность «объектно-ориентированного C», известная под именем Objective C и зачастую воспринимаемая как забавный курьез, была языком вполне постмодернистским, смешавшим концепции классического C и модернистского Smalltalk. Распространение этого (и других «странных») языков исключительно в мире Apple весьма показательно], Object Pascal (позже Delphi).