Слоны в комнате
Учитывая богатый спектр языков программирования, которые развивались за последние полвека, и в целом успешный способ, которым языки возникли или развивались, чтобы справляться с технологическими изменениями, мы отмечаем три странных факта:
-
C остается чрезвычайно популярным языком, несмотря на его недостатки (раздел 5.1),
-
что языки с динамической типизацией являются одними из самых популярных языков программирования, несмотря на десятилетия достижений в системах статических типов
(раздел 5.2),
-
и что, несмотря на рост многоядерной обработки, поддержка параллелизма является лоскутной работой во всех современных языках (раздел 5.3).
На первый взгляд, это противоречит нашему «выбору наиболее подходящего» тезиса, и, возможно, мы, компьютерные ученые,
даже немного смущены состоянием реального мира. Мы вернем этот вопрос в разд. 6,
где мы обсуждаем роль времени и инерции в эволюции.
5.1 Популярность C
Если оставить в стороне наследие, мы считаем, что язык C имеет две основные сильные стороны: его основные функции просты и обеспечивают высокую производительность. Цена за производительность заключается в том, что практически не предоставляется никаких гарантий надежности или безопасности. Ошибочная программа на С может вести себя непредсказуемым образом и быть уязвимой для атак.
Некоторые из наиболее известных уязвимостей программного обеспечения последних лет, в том числе ошибка Heartbleed [http://heartbleed.com/],
возникают из-за основных ошибок в программах на C, и все еще прилагаются значительные усилия для написания и развертывания
«дезинфицирующих» инструментов для поиска дефектов в коде C, таких как AddressSanitizer и MemorySanitizer от Google [https://github.com/google/sanitizers].
Кроме того, несмотря на простое ядро, семантика C далеко не проста, если учитывать множество неопределенных и определяемых реализацией поведений,
описанных в спецификации языка. Действительно, спустя десятилетия с момента появления языка на ведущих конференциях по языку
программирования все еще принимаются статьи, в которых делается попытка строго определить семантику C [15,29], и последние модели
программирования для многоядерных и графических процессоров, таких как OpenCL и Metal, имеют на основе их ускоритель языков программирования на C.
Учитывая, что большая часть кода, написанного сегодня, не нуждается в оптимальном выполнении, и, учитывая достижения в таких технологиях, как компиляция точно в срок, которые во многих случаях позволяют управляемым языкам достигать производительности, сравнимой с C, мы спрашиваем: почему C останется таким популярным, и будет ли эта тенденция продолжаться?
Основной причиной долговечности C является то, что он используется для разработки всех основных операционных систем и многих вспомогательных инструментов. Это также типичный язык для встраиваемого программирования, отчасти из-за небольшого объема памяти в языке, а также потому, что C обычно является первым языком, для которого становится доступным компилятор, нацеленный на новый набор команд (последний мотивируется тем, что такие компилятор необходим для компиляции операционной системы для новой целевой платформы). Помимо компиляторов, язык также хорошо поддерживается такими инструментами, как отладчики, компоновщики, профилировщики и анализаторы, которые могут влиять на выбор языка для использования.
Келл указывает на различные фундаментальные достоинства системного программирования, которые С приносит, помимо того, что он просто является стандартом де-факто [18]. Он утверждает, что «сама «небезопасность» C основана на неудачной взаимосвязи самого языка с тем, как он реализован», и приводит убедительные аргументы в пользу безопасной реализации C с достаточно высокой производительностью для потребностей системного программирования и что это возможно. Он также утверждает, что ключевым свойством C, которое приносят в жертву многие языки более высокого уровня, является его способность облегчать связь с «чужими» компонентами системы (включая как аппаратные устройства, так и код из других языков программирования). Эта гибкость в общении обязана способности связывать воедино объектные файлы, которые относятся к одному и тому же двоичному интерфейсу приложения, в использовании С памяти в качестве единой абстракции для связи. Келл приходит к выводу: «Си - далеко не святое, и я с нетерпением жду его замены - но они не должны забывать о важности общения с инопланетянами».
Короче говоря, ни один другой текущий язык не подходит к пригодности C (при измерении вместе с его симбиотической инструментальной экосистемой) для ниши системного программирования.
5.2 Рост динамически типизированных языков
Системы статического типа имеют возможность заблаговременно отсеивать большие классы программных дефектов. Кроме того, как обсуждалось в разд. 3.1, статические типы облегчают автоматизированный рефакторинг - ключ к гибким процессам разработки - и обеспечивают расширенную оптимизацию компилятора, которая может повысить производительность. Тем не менее, многие из самых популярных на сегодняшний день языков, включая JavaScript, PHP, Ruby и Python, не содержат статических типов и делают статические типы необязательными (и необычными на практике).
В случае JavaScript мы утверждаем, что его распространенность определяется сетью как платформой программирования и веб-браузерами как доминирующей средой исполнения.
Как единственный язык, поддерживаемый всеми браузерами, в некотором смысле JavaScript для браузеров является тем же, что C для Unix. В последнее время JavaScript также получил широкое распространение в разработке на стороне сервера с платформой Node.js. Основной движущей силой для этого является разум разработчиков. Многие разработчики уже знают JavaScript из-за предыдущей работы в браузере, поэтому наличие серверной среды, в которой они могут кодировать на языке, который они уже знают, позволяет им передавать многие из своих существующих навыков, не изучая Python, Ruby или PHP. С точки зрения эволюции, хотя ни один язык сам по себе не является предпочтительным в серверном мире, дополнительная совместимость JavaScript с его «симбиотическим «опытом программиста» позволила ему занять эту нишу.
Одной из причин популярности динамических языков в целом является то, что они, как правило, поставляются с отличной библиотечной поддержкой, предоставляя только правильные методы для предоставления желаемой услуги. Представление структурированных данных без схемы в статически типизированных языках, как правило, более сложное (например, какие типы использовать), но недавняя работа Petricek et al. на вывод форм для поставщиков F# является многообещающим [34].
Более фундаментальной причиной может быть «дружелюбие для новичка». Легко получить некоторый код и запустить веб-страницу с помощью JavaScript; написать простую утилиту на Python обычно проще, чем в C (где нужно бороться со строковыми манипуляциями) или в Java (где нужно решить, какие классы создавать).
Важность дружелюбия новичка не следует недооценивать. Многие люди, пишущие программное обеспечение, в наши дни не являются обученными программистами или вообще программистами. Поскольку кодирование становится навыком, необходимым для большого числа различных работ, у нас появляется все больше и больше программистов, но они могут не иметь времени или желания изучать тонкости сложных языков - они просто хотят что-то сделать. В настоящее время Python (поддерживаемый такими технологиями, как iPython Notebooks) популярен среди ученых и других, которые просто хотят быстро приступить к выполнению довольно простой вычислительной задачи. Эта категория программистов, вероятно, только будет расти в будущем, и поэтому мир будет накапливать растущее количество довольно простого программного обеспечения на языках, с которыми сравнительно легко работать неспециалистам.
Опасность, исторически иллюстрируемая использованием PHP в Facebook, состоит в том, что система, которая запускается как простая программа на динамически типизированном языке,
может выйти за пределы практической ремонтопригодности. Мы ставим под сомнение степень, в которой языки с динамической типизацией подходят для создания крупномасштабной инфраструктуры,
которая должна постоянно обслуживаться и изменяться в течение многих лет изменяющейся командой.
Язык взлома Facebook, который расширяет PHP типами таким образом, который позволяет типизировать нетипизированную кодовую базу, является одним из
примеров, когда ценную кодовую базу без статических типов переносят в типизированную форму, чтобы обеспечить более быстрое обнаружение дефектов и
лучшую читаемость и обслуживание [https://code.facebook.com/posts/264544830379293/hack-a-new-programminglanguage-for-hhvm/]. Мы также видим аналогичные тенденции в мире JavaScript, например, в инициативах TypeScript [https://github.com/Microsoft/TypeScript]
и Flow [https://github.com/facebook/flow] от Microsoft и Facebook соответственно.
Мы можем резюмировать, что различные особенности динамических языков - быстрое создание прототипов, удобство для начинающих, избегание интеллектуально здравых, но сложных систем типов - увеличивают пригодность таких языков в нишах, которые ценят эти свойства по сравнению с другими.
5.3 Лоскутная поддержка параллелизма
Как обсуждено в разд. 2.7 в разделе «Параллелизм и рост многоядерности» в последнее десятилетие появилось множество исследовательских работ и моделей промышленного программирования, помогающих писать параллельный код, который сам опирается на долгую историю целенаправленной работы (ранее нишевой) сообщества программистов параллельного исполнения.. Тем не менее, кажется, что с точки зрения обычного программиста, прогресс был ограничен. Существует широкий спектр языковых возможностей для поддержки параллелизма на разных уровнях абстракции (см. примеры в разделе 2.7), но даже для одного уровня абстракции существует множество конкурирующих вариантов, как между языками, так и внутри них. Но, несмотря на и, возможно, из-за всего этого выбора, программисту без опыта параллелизма далеко не ясно,
какой язык и механизм выбрать при желании ускорить конкретное приложение
[Определение безопасности параллельного выполнения может быть оставлено на усмотрение программиста, так как в случае параллельных потоков в Java, или может быть облегчено с помощью
поддержки инструментов или гарантируется семантикой языка (например, из-за языковой чистоты)].
Казалось бы, разумной стратегией программиста может быть запуск параллельных версий операций везде, где это безопасно, например, значение по умолчанию для ParallelStream через поток в Java, если параллельная версия небезопасна, и предоставьте системе времени выполнения решать, когда на самом деле использовать параллелизм31. Эта стратегия аналогична другим стратегиям, которые часто используются во время разработки программного обеспечения, например как предпочтение наиболее общего типа для аргумента функции, делая данные неизменяемыми, когда это возможно, и ограничивая видимость внутренних элементов модуля, если не требуется более высокая видимость.
Однако такой подход «использовать параллелизм везде, где это было бы безопасно» в настоящее время наивен и обычно приводит к снижению производительности по причинам гранулярности задач и эффектам иерархии памяти при запуске нескольких небольших потоков. Это показывает, что нам предстоит пройти долгий путь, прежде чем параллельное программирование станет по-настоящему массовым.
В настоящее время часто кажется, что многие языковые примитивы параллелизма являются наиболее подходящими для данной ниши без единой модели.
Перевод: Д.Ю.Караваев. 14.11.2019
Опубликовано: 2019.11.25, последняя правка: 2019.11.25 21:57
Отзывы
✅ 2019/11/29 15:20, MihalNik #0
В настоящее время часто кажется, что многие языковые примитивы параллелизма являются наиболее подходящими для данной ниши без единой модели Лишнее слово "наиболее"?✅ 2019/12/03 22:37, Автор сайта #1
По-моему, всё к месту. Если «наиболее» заменить на «наименее», то второе «вписывается» по стилю. Значит и первое уместно.✅ 2019/12/04 09:43, MihalNik #2
Довольно странно сочетание "многих" с "наиболее".✅ 2019/12/04 16:52, Автор сайта #3
Ой, не ищите чёрную кошку в тёмной комнате. Вот нашёл в сети примеры на эту тему: Огонь, как видимая форма процесса горения, является наиболее подходящим определением для стихии, которая понимается как вечный процесс. Н. С. Трубецкой, Курс истории древней философии Двигатели, предназначенные для локомотивной службы, должны иметь рабочую характеристику, близкую к характеристике паровозной машины, которая для автономного локомотива является наиболее подходящей. Евгений Лосев, ТЕПЛОВОЗЫ. Вехи непройденного пути✅ 2019/12/05 07:09, MihalNik #4
Ой, не ищите чёрную кошку в тёмной комнате. Ну, я вообще не могу понять того предложения.✅ 2019/12/05 07:18, MihalNik #5
Ну и какие-то странные примеры. Скорее напрашивается сравнение с "многие круги являются наиболее круглыми".✅ 2019/12/05 23:29, Автор сайта #6
Каждый пишет, как он слышит. Каждый слышит, как он дышит. Добавить свой отзыв
Написать автору можно на электронную почту mail(аt)compiler.su
|