Библиотека сайта rus-linux.net
Будущее языков программирования
Оригинал: The Future of Computer Languages
Автор: Juliet Kemp
Дата публикации: 14 декабря 2016 г.
Перевод: А.Панин
Дата перевода: 1 февраля 2017 г.
Будущее невозможно предугадать... но в случае языков программирования мы все же можем выдвинуть некоторые предположения.
Для чего это нужно?
- Вы сможете уверенно говорить о будущем языков программирования на следующем собеседовании.
- Вы сможете выбрать новый язык программирования для последующего изучения.
- Вы узнаете об ошибках разработчиков языков программирования, допущенных в прошлом.
После рассмотрения нескольких языков программирования, которые были разработаны в течение последних 50 лет, пришло время прикоснуться к хрустальному шару и попытаться предсказать события, которые будут происходить в мире языков программирования в течение следующих 50 лет... или хотя бы следующих 20 лет. Завершат ли используемые сегодня старые языки программирования свое существование? Какие новые языки программирования захватят умы разработчиков? Какие серьезные проблемы пытаются решить современные разработчики программного обеспечения и языков программирования сегодня? И как практика программирования повлияет на изменения в мире языков программирования в будущем?
При рассмотрении истории развития языков программирования в течение последних 30-50 лет несложно заметить, что существует некое количество старых языков программирования, которые используются и по сей день. Fortran, COBOL, C, Ada и некоторые другие языки программирования все еще развиваются и в ближайшее время явно не будут находиться на грани исчезновения, хотя некоторые из них и являются менее надежными, чем другие.
Некоторые более старые языки программирования все еще используются главным образом для разработки программного обеспечения для устаревших систем (особенно мэйнфреймов), причем есть вероятность, что со временем это программное обеспечение будет переписано на более современных языках программирования. Ввиду того, что данные языки практически не развиваются, после портирования всего существующего программного обеспечения они станут попросту никому не нужными. Однако, более вероятным развитием событий является задействование современного аппаратного обеспечения (современных мэйнфреймов, а также виртуальных и облачных машин) для репликации устаревшего аппаратного обеспечения и запуска существующего кода; это гораздо проще, дешевле и безопаснее, чем переработка всего кода (с точки зрения руководства проекта).
Язык C, с другой стороны, активно используется при разработке современных программных продуктов и все еще лежит в основе большой части используемого сегодня программного обеспечения. Ни для кого не секрет, что ядро Linux разработано с использованием языка программирования C. Этот язык идеально подходит для решения ставящихся перед ним задач, поэтому очень сложно представить, что в ближайшее время какой-либо язык программирования потеснит его в сфере разработки программного обеспечения, тесно взаимодействующего с аппаратными устройствами.
Стоит ли удивляться тому, что код на языках Fortran, C и COBOL все еще успешно используется в отдельных областях? Отнюдь!
Языки программирования среднего возраста, такие, как Java, JavaScript и Python все также активно разрабатываются и используются. Методика использования данных языков программирования изменилась (о чем будет сказано ниже), но сами языки программирования уже набрали значительный вес и, скорее всего, никуда не исчезнут в течение следующих 20 лет. С другой стороны, 15 лет назад язык Perl использовался повсеместно, в то время, как сегодня он используется крайне редко; однако, на сегодняшний день язык Perl все еще используется во многих программных продуктах и позволяет решать различные задачи. (И, разумеется, рано или поздно появится интерпретатор Perl 6, который может снова изменить положение в мире языков сценариев.)
Более старые функциональные языки программирования, такие, как Scala (2001) и Haskell (1990) в последнее время обрели относительную популярность. Например, в компаниях Facebook и Google язык Haskell используется для автоматизации определенных рабочих процессов; в компаниях LinkedIn, Twitter и Tumblr для аналогичных целей используется язык Scala. Это обстоятельство ознаменовало общее повышение интереса к функциональному программированию, выразившееся в переносе идей и возможностей из функциональных языков программирования в языки программирования общего назначения (примером могут служить лямбда-выражения в Java 8). Пока не понятно, приведет ли это к воцарению функциональных языков программирования (как считают сторонники функционального программирования) или всего лишь к кратковременной популярности идей функционального программирования благодаря их реализации в рамках более популярных языков. Вполне вероятно, что по мере ознакомления разработчиков с функциональным программированием соответствующие языки программирования наберут популярность в тех сферах, где их использование позволит решать задачи наиболее оптимальным образом, но при этом другие языки и парадигмы программирования все также будут популярны в своих нишах. По сути, аналогичные тренды прослеживались и в случае других языков программирования в другие промежутки времени ввиду того, что их определенные возможности позволяли наиболее оптимально решать возникающие задачи (обратитесь к разделу "Параллельное исполнение инструкций" ниже).
Другой подход к разработке языков программирования заключается в переносе новых (или не самых новых) возможностей в существующие старые языки программирования. Все больше и больше языков программирования создается на основе виртуальной машины Java - наиболее известными из них являются Clojure, Groovy, JRuby и Jython, но существует и множество других. Это обозначает, что наметился определенный крен в сторону создания единой платформы для множества языков программирования? По сути, это неплохая идея, которая могла бы иметь практические преимущества в случае корректной реализации; она могла бы упростить упаковку и установку программного обеспечения и позволила бы программистам работать с более высокоуровневыми языками программирования, которые лучше всего подходят для решения задач из их области интересов. При этом возникает необходимость в трате ресурсов для поддержания в рабочем состоянии дополнительной виртуальной машины, но сегодня виртуальные машины (а также аналогичные механизмы) все чаше и чаще используются при реализации программных продуктов.
Неужели мэйнфреймы с исполняющимся с помощью них программным обеспечением доживают свои последние дни?
A, B, C... D?
Языки C и C++ были разработаны достаточно давно и уже доказали свою состоятельность, о чем было сказано выше. Язык D разрабатывается специалистами, имеющими опыт практического программирования на языке C++, в качестве его замены, заимствующей удачные идеи, в особенности, высокую производительность, но в то же время более удобной для разработчиков. Он не поддерживает некоторые возможности C++, но в тоже время предоставляет широкий спектр дополнительных возможностей, включая систему модульного тестирования, сборщик мусора и различные механизмы обработки массивов. Также данный язык поддерживает ассемблерные вставки, наглядно иллюстрируя утверждение о том, что он, как и языки C/C++, позволяет программисту при необходимости осуществлять доступ к низкоуровневым функциям центрального процессора. Его разработчики заявляют, что D подходит для разработки любого программного обеспечения, начиная с высокопроизводительного кода серверных приложений и заканчивая низкопроизводительными заменами сценариев.
Компиляция кода на языке D с помощью компилятора gdc. (Все эти сообщения об ошибках генерируются из-за единственного отсутствующего символа точки с запятой.) Обратите внимание на необходимость указания имени результирующего файла с помощью параметра -o
Параллельное исполнение инструкций
Параллельное исполнение инструкций является, скорее всего, самой сложной задачей, с которой сталкиваются современные программисты. Потребность в нем возникает при необходимости осуществления множества одновременных вычислений с возможным взаимодействием. Такие операции могут осуществляться как с помощью чипа с единственным ядром, так и с помощью центрального процессора с поддержкой программных потоков или нескольких центральных процессоров/машин. Ввиду того, что расчеты не должны в обязательном порядке осуществляться в параллельном режиме, а в ходе их исполнения могут запрашиваться данные (или использоваться общие ресурсы), существует множество условий, при выполнении которых соответствующий процесс будет протекать корректно, включая определенные подходы к обмену данными, резервированию памяти и планированию исполнения инструкций. Параллельное исполнение инструкций является особенно важным аспектом программирования, так как по мере развития аппаратного обеспечения становится все оптимальнее (и дешевле!) задействовать множества программных потоков/ядер центрального процессора/центральных процессоров одновременно.
Для решения описанной задачи существуют и разрабатываются различные решения и ресурсы. Язык Erlang (работа над которым была начата в далеком 1986 году) в последнее время набрал популярность в облачных высокопроизводительных вычислительных средах, в которых требуется параллельное исполнение инструкций. Erlang имеет соответствующий встроенный механизм с набором примитивов для создания процессов и осуществления межпроцессного взаимодействия; эти процессы формируют базовую структуру программы на Erlang. Erlang также позволяет обойти стороной проблему работы с изменяемыми разделяемыми данными и блокировкой доступа к ним путем принудительного использования механизма отправки сообщений без какой-либо возможности использования разделяемых данных. Это обозначает, что каждый процесс имеет набор собственных данных состояния, причем процессы изменяют состояние в зависимости от своего поведения или от данных из полученных от других процессов сообщений, а не от данных из разделяемой структуры, к которой имеет доступ каждый из процессов. (При использования разделяемых структур данных обычно возникает необходимость в использовании блокировок доступа к ним со стороны отдельных процессов; а в случае некорректного завершения одного из процессов, удерживающего блокировку, другие процессы не смогут получить доступ к разделяемой структуре данных.) При этом Erlang является и функциональным языком программирования, разработанным с прицелом на высокую масштабируемость, доступность и минимальные простои инфраструктуры. Это объясняется его происхождением, связанным с индустрией телекоммуникаций; данная индустрия попросту не допускает значительных простоев инфраструктуры. Подобная особенность делает рассматриваемый язык программирования отличным выбором для реализации современных сетевых и коммуникационных сервисов (Erlang используется в инфраструктуре мессенджера WhatsApp). Виртуальная машина Erlang осуществляет планирование исполнения и балансировку нагрузки, избавляя программиста от необходимости самостоятельной реализации соответствующих механизмов.
Программа Hello World на языке Erlang. Сохраните код в файле и исполните его с помощью командной оболочки Erlang
Другой технологией для параллельного исполнения инструкций является язык CUDA (или его свободный аналог OpenCL), который позволяет задействовать вычислительные ядра (GPU) современных графических карт в то время, когда они не используются для обработки графики и могут осуществлять параллельные вычисления. Данная технология позволяет с успехом решать ряд специфических задач и популярна в академических кругах. По сути, CUDA позволяет преобразовывать данные в структуры, используемые для представления графики и использовать вычислительные ядра графической карты для их обработки и анализа, ведь эти ядра оптимизированы для работы с графикой.
Языки Perl 6 и Clojure также нередко рекомендуются в качестве инструментов для решения проблем параллельного исполнения инструкций. Язык Clojure (вариант языка Lisp) был изначально предназначен для "упрощения проектирования и реализации алгоритмов, связанных с параллельным исполнением инструкций" и позволяет генерировать байткод для виртуальной машины Java. Perl 6 также позволяет значительно упростить разработку подобных алгоритмов благодаря возможностям динамического языка программирования. Однако, никому пока не известна точная дата выпуска стабильной версии интерпретатора Perl 6 (или хотя бы финальная версия соответствующего стандарта).
Новый язык программирования Go от компании Google (представленный общественности в 2009 году) изначально проектировался с поддержкой механизма параллельного исполнения инструкций, хотя главной целью его разработчиков было создание языка программирования с читаемым кодом, который "был бы достаточно простым для полного понимания любым программистом". Go является компилируемым языком со статической типизацией, предназначенным для системного программирования. (В этом году разработчики получили возможность использования данного языка для разработки приложений для мобильных устройств и смартфонов, что еще раз подчеркивает важность разработки программного обеспечения для мобильных платформ.) Код на языке Go должен быть кратким и читаемым, причем, как и в коде на языке Swift (о котором будет сказано ниже), в нем должны использоваться интерфейсы и встраивание типов для реализации механизмов виртуального или не виртуального наследования. Гибкость, высокая скорость разработки и своеобразная простота рассматриваемого языка программирования являются его важными особенностями.
Это режим "песочницы" языка Swift в OS X, причем код расположен слева, результаты его исполнения - справа, а всплывающая подсказка с результатом исполнения определенной инструкции - прямо под этой инструкцией. Данный режим не доступен в Linux (возможно, лишь временно), хотя компилятор языка Swift может быть загружен с веб-сайта swift.org
Большие данные
Возрастающая актуальность "больших данных" обуславливает популярность языка R (статистического языка программирования, разработанного в 1997 году), который на сегодняшний день используется в таких компаниях, как Google, Facebook и New York Times. Однако, данный язык не достаточно производителен для обработки действительно больших объемов данных и больше подходит для создания прототипов, чем рабочих моделей программных проектов. О применимости Matlab (вычислительный язык программирования), активно используемого в научных кругах для обработки любых объемов данных, все еще нет единого мнения. Недавние значительные оптимизации математических и статистических библиотек языка Python вполне могут сделать этот язык приемлемым инструментом для решения вычислительных задач. Проекты IPython и NumPy (созданные с целью сделать язык Python конкурентом Matlab в плане вычислительных задач) неплохо подходят для создания несложных проектов, при этом сообщество Python-разработчиков предоставляет в ваше распоряжение большое количество других интересных тулкитов. Разумеется, среда Matlab все еще активно используется в определенных сферах, хотя и является достаточно дорогим программным продуктом с закрытым исходным кодом. Как в Matlab, так и в R имеются пакеты для организации параллельного исполнения инструкций.
Язык Julia очень похож на язык Python, но при этом имеет гораздо более высокую производительность. Он разрабатывался специально для решения академических задач, связанных с дроблением чисел с поддержкой мощных механизмов параллельного исполнения инструкций и сетевого взаимодействия, а также интерфейсов для библиотек на языках Fortran и C. При учете сложности некоторых длящихся неделями академических вычислений, более высокая производительность языка Julia обретает особую важность (затрата на расчет 1 секунды вместо 4 не выглядит, как существенная оптимизация; затрата на другой расчет недели вместо четырех недель, очевидно, выглядит как таковая). Язык Julia является очень быстрым и в теории более масштабируемым, чем Python, при этом его так же просто выучить; но стоит помнить и о том, что сообщество разработчиков данного языка еще не достаточно развито, поэтому он не имеет большого количества библиотек и тулкитов для создания конкуренции языкам Python и R.
Разработка веб-приложений и приложений для мобильных платформ
Еще одной проблемой современного программирования является разработка веб-приложений и приложений для мобильных платформ. Все больше и больше программного обеспечения исполняется силами веб-браузеров (самым ярким подтверждением данного утверждения является операционная система ChromeOS), что делает JavaScript и другие языки для разработки веб-приложений особенно актуальными.
На сегодняшний день JSON является наиболее популярным форматом обмена данными, поддерживаемым с помощью библиотек для всех актуальных языков программирования, а веб-сервисы используют технологию REST, хотя всего 10 лет назад повсеместно использовались формат XML и технология SOAP. Остается лишь задать вопрос: "Будем ли мы по прошествии еще 10 лет считать JSON и REST устаревшими технологиями?" Технологии веб-разработки все также стремительно развиваются, поэтому данная сфера в любом случае претерпит кардинальные изменения в ближайшем будущем.
Важность разработки приложений для мобильных платформ обуславливает актуальность языка программирования Java в ближайшем будущем, так как платформа Android (использующая свою собственную версию Java) занимает доминирующую позицию на рынке смартфонов и планшетов. Другую большую долю этого рынка занимает, разумеется, платформа iOS от компании Apple; исходя из этого, новый язык Swift от компании Apple, пришедший на смену языку Objective C, является одним из самых актуальных языков программирования на сегодняшний день.
Язык Swift был представлен общественности в середине 2014 года, он очень быстро развивается, причем в текущее время код его компилятора открыт под свободной лицензией. В соответствии с заявлением представителей из компании Apple, это "язык для протоколо-ориентированного программирования". В Swift протоколы являются практически тем же самым, что и интерфейсы в других языках программирования; при этом в Swift вместо создания классов и подклассов рекомендуется создавать протоколы, а затем - типы и структуры, которые будут использовать их. Протоколы могут расширяться с помощью наборов стандартных поведений. Это делает язык Swift крайне гибким в особенности из-за того, что типу без каких-либо проблем может ставиться в соответствие сразу множество протоколов, в то время, как множественное наследование классов в доступных языках программирования либо не реализовано, либо максимально затруднено. Протоколы также могут использоваться не только для работы с типами классов. Имеется возможность простого расширения возможностей существующих протоколов с помощью ключевого слова extension, в результате чего все функции протокола будут доступны также в рамках вашего расширения.
Крайне удобной особенностью рассматриваемой технологии является возможность совместного использования языков Swift и Objective C в рамках одного приложения, которая максимально упрощает переход к использованию нового языка. Также данная технология позволяет использовать интерактивный режим разработки, а именно, режим "песочницы" в интегрированной среде разработки, который позволяет разработчику без труда тестировать фрагменты кода. (Данная возможность также предназначена для начинающих разработчиков, изучающих язык.) При этом у разработчиков есть стимулы к переходу на Swift, а именно, большая рыночная доля программного обеспечения для iOS/OS X и низкий порог вхождения. Если вы лишь начинаете свое путешествие по вселенной Apple, вам стоит использовать Swift вместо Objective C, а если вы являетесь опытным разработчиком на Objective C, вам также будет полезно изучить Swift.
Swift демонстрирует несколько идей современного программирования - вынесение на первый план гибкости и скорости разработки, а также создание интерактивных окружений для разработки и автоматической оптимизации кода (в подобных окружениях компилятор выводит сообщения с описаниями методик оптимизации кода).
Интернет вещей
Интернет вещей является новой концепцией, которая у всех на слуху, при этом ее развитие сложно предугадать. Некоторые из вариантов применения данной концепции являются очевидно бессмысленными (классическим примером является "умный холодильник"), но в то же время данная концепция актуальна хотя бы из-за того, что затрагивает множество базовых аспектов программирования. Скорее всего, любого знакомого с ней человека не будет покидать ожидание ее кардинального изменения в ближайшем будущем, под которое впоследствии подстроятся языки, и, возможно, практики программирования. Может быть, развитие 3D-печати приведет к необходимости создания компиляторов для компиляции объектов, а не кода? И как же это будет выглядеть?
Разработка кода: обучение и практика
На сегодняшний день начинающим программистам доступно гораздо больше ресурсов, чем когда-либо в прошлом. Проекты Raspberry Pi и Scratch позволяют использовать различные методики обучения программированию, включая методики для обучения детей (это относится главным образом к Scratch). Проекты Robots Dash и Dot также предназначены для ознакомления детей с основами программирования с последующим переходом к изучению более сложных приемов программирования и алгоритмов. В данном случае процесс разработки заключается в решении очевидных задач с помощью кода. Новое поколение разработчиков программного обеспечения, получившее знания в процессе работы с данными проектами, вполне может перевести языки программирования и сам процесс программирования на новые рельсы.
Задачи для разработчиков также начинают изменяться. Смещение фокуса в сторону облачных платформ и упрощение процесса обмена кодом обуславливают возможность работы над проектами отдельных команд со всех уголков света, члены которых крайне редко встречаются друг с другом в реальной жизни. Облачные платформы позволяют создавать приложения, абсолютно не зная системных администраторов, которые ответственны за их развертывание и управление ими, хотя раньше подобные задачи могли решаться вашими силами. При этом следует помнить о том, что сегодня актуальнее разрабатывать приложения, работающие на ваших серверах, чем оправлять установочные диски клиентам для установки приложений на их системы.
Повышение степени автоматизации позволяет программистам выделять больше времени для работы над решением важных задач. Наличие библиотек, фреймворков, API и плагинов позволяет в большинстве случаев комбинировать существующие программные компоненты, а не разрабатывать их с нуля; кроме того, использование этих программных компонентов позволяет сконцентрировать внимание на реализации логики работы приложений и избежать множества ошибок, выявленных в процессе тестирования популярных библиотек и фреймворков широким кругом их пользователей. Очевидная в последние годы популярность языка Python в какой-то мере связана с расширением номенклатуры его библиотек, которое значительно упрощает повторное использование кода в новых сценариях. Проблемы могут возникать лишь в случае одновременного использования нескольких конкурирующих фреймворков; выбор подходящего фреймворка не всегда является простой задачей, а наличие множества подобных программных компонентов сокращает выгоду от их использования ввиду уменьшения пользовательской базы каждого из них.
Интегрированные среды разработки и их различные расширения позволяют генерировать код, что особенно полезно при использовании языков программирования, требующих наличия больших объемов шаблонного кода. Примером является язык JavaScript, имеющий такие дополнения, как CoffeeScript и Less.js, которые упрощают процесс разработки сценариев с задействованием сложных таблиц каскадных стилей.
Автоматизированное тестирование, разработка через тестирование, push-on-green и другие аналогичные практики также позволяют в случае корректного использования создавать более краткий и надежный код, сокращая затраты времени на на исправления ошибок после развертывания приложений. Улучшения в системах контроля версий, реализации хуков для запуска автоматизированных тестов и другие подобные возможности, разумеется, отличают современный процесс разработки программного обеспечения от соответствующего процесса 10 лет назад (и делают просто неузнаваемым по сравнению с соответствующим процессом 30 лет назад).
Далекое будущее
Закон Мура замедляет свое действие? Может быть это означает, что через некоторое время произойдет какое-то переломное событие, аналогичное замене транзисторов на интегральные схемы (на которые, в свою очередь были заменены вакуумные лампы)? Рэмонд Курцвейл отстаивает подобную точку зрения и считает самой вероятной заменой нанолампы. (Он также считает, что в будущем вычислительные мощности будут расти по экспоненте, что в итоге приведет к созданию множества устройств, работающих на основе принципа технологической сингулярности, с которым, на мой взгляд, пока еще рано разбираться.) Перенастраиваемое аппаратное обеспечение является еще одной популярной концепцией будущего, которая начинает реализовываться в ограниченных масштабах уже сегодня. Выпуск нового аппаратного обеспечения обычно приводит к созданию нового программного обеспечения, поэтому без информации о том, как оно будет работать (если оно вообще будет выпущено) практически невозможно сделать предположения о каких-либо функциях программного обеспечения будущего.
Однако, если оглянуться на 40 лет назад, можно без труда заметить, что аппаратное обеспечение претерпело значительные изменения, а программное обеспечение изменялось вместе с ним, но при этом мы все еще имеем дело с некоторыми языками программирования, которые были популярны в то время. Если воспользоваться грубой экстраполяцией, можно сделать вывод о том, что мы будем использовать некоторые из актуальных на сегодняшний день языков программирования в течение следующих 40 лет. Вместе с изменениями практик программирования обычно меняются и сами языки программирования. Так, современный язык Fortran немного отличается от оригинального языка Fortran, а версия языка Java 8 ушла очень далеко от версии языка Java 1.
Фундаментальная проблема языков программирования заключается в отсутствии универсального языка, который имел бы все возможности, необходимые каждому из программистов, ведь некоторые из возможностей могут быть не совместимы друг с другом. Именно поэтому все теории об "единственном универсальном языке программирования" являются несостоятельными изначально. (При этом многие языки программирования позволяют генерировать байткод для одной виртуальной машины, который может впоследствии исполняться и с помощью других совместимых виртуальных машин.) У нас всегда было множество языков программирования для решения различных задач и мы всегда могли использовать различные парадигмы в зависимости от сложившихся условий. Наибольший интерес в данном случае представляют постепенно появляющиеся новые задачи и методики их решения современными программистами с помощью новых и старых языков программирования.