Язык программирования — это система обозначений для написания компьютерных программ . [1]
Языки программирования описываются с точки зрения их синтаксиса (формы) и семантики (значения), обычно определяемых формальным языком . Языки обычно предоставляют такие функции, как система типов , переменные и механизмы обработки ошибок . Для выполнения программ требуется реализация языка программирования , а именно интерпретатор или компилятор . Интерпретатор напрямую выполняет исходный код, в то время как компилятор создает исполняемую программу.
Архитектура компьютера оказала сильное влияние на дизайн языков программирования, при этом наиболее распространенный тип ( императивные языки — реализующие операции в определенном порядке) был разработан для эффективной работы на популярной архитектуре фон Неймана . Хотя ранние языки программирования были тесно связаны с оборудованием , со временем они стали более абстрагированными, чтобы скрыть детали реализации для большей простоты.
Тысячи языков программирования — часто классифицируемые как императивные, функциональные , логические или объектно-ориентированные — были разработаны для самых разных целей. Многие аспекты проектирования языков программирования предполагают компромиссы — например, обработка исключений упрощает обработку ошибок, но за счет производительности. Теория языков программирования — это подраздел компьютерной науки , который изучает проектирование, реализацию, анализ, характеристику и классификацию языков программирования.
Языки программирования отличаются от естественных языков тем, что естественные языки используются для взаимодействия между людьми, в то время как языки программирования предназначены для того, чтобы позволить людям передавать инструкции машинам. [ необходима цитата ]
Термин «язык программирования» иногда используется взаимозаменяемо с термином «язык программирования». [2] Однако использование этих терминов различается среди авторов.
В одном из вариантов использования языки программирования описываются как подмножество компьютерных языков. [3] Аналогично, термин «компьютерный язык» может использоваться в противопоставлении термину «язык программирования» для описания языков, используемых в вычислениях, но не считающихся языками программирования [ требуется ссылка ] – например, языков разметки . [4] [5] [6] Некоторые авторы ограничивают термин «язык программирования» языками, полными по Тьюрингу . [1] [7] Большинство практических языков программирования являются полными по Тьюрингу, [8] и, как таковые, эквивалентны в том, какие программы они могут вычислять.
Другое использование рассматривает языки программирования как теоретические конструкции для программирования абстрактных машин , а компьютерные языки как их подмножество, которое работает на физических компьютерах, имеющих конечные аппаратные ресурсы. [9] Джон К. Рейнольдс подчеркивает, что языки формальных спецификаций являются такими же языками программирования, как и языки, предназначенные для исполнения. Он также утверждает, что текстовые и даже графические форматы ввода, которые влияют на поведение компьютера, являются языками программирования, несмотря на то, что они обычно не являются полными по Тьюрингу, и замечает, что незнание концепций языка программирования является причиной многих недостатков в форматах ввода. [10]
Первые программируемые компьютеры были изобретены в конце 1940-х годов, а вместе с ними и первые языки программирования. [11] Самые ранние компьютеры программировались на языках программирования первого поколения (1GL), машинном языке (простые инструкции, которые могли напрямую выполняться процессором). Этот код было очень сложно отлаживать, и он не переносился между различными компьютерными системами. [12] Чтобы улучшить простоту программирования, были изобретены языки ассемблера (или языки программирования второго поколения — 2GL), отличающиеся от машинного языка, чтобы сделать программы более понятными для людей, хотя они не увеличили переносимость. [13]
Первоначально аппаратные ресурсы были редкими и дорогими, в то время как человеческие ресурсы были дешевле. Поэтому предпочтение отдавалось громоздким языкам, использование которых занимало много времени, но которые были ближе к оборудованию для более высокой эффективности. [14] Внедрение языков программирования высокого уровня ( языки программирования третьего поколения — 3GL) произвело революцию в программировании. Эти языки абстрагировались от деталей оборудования, вместо этого они были разработаны для выражения алгоритмов, которые могли бы быть более понятны людям. Например, арифметические выражения теперь могли быть записаны в символьной нотации и позже переведены в машинный код, который могло выполнять оборудование. [13] В 1957 году был изобретен Fortran (FORmula TRANslation). Часто считающийся первым компилируемым языком программирования высокого уровня, [13] [15] Fortran оставался в использовании и в двадцать первом веке. [16]
Около 1960 года были разработаны первые мэйнфреймы — универсальные компьютеры — хотя ими могли управлять только профессионалы, а стоимость была чрезвычайно высокой. Данные и инструкции вводились с помощью перфокарт , что означало, что во время работы программы нельзя было ничего вводить. Поэтому языки, разработанные в то время, рассчитаны на минимальное взаимодействие. [18] После изобретения микропроцессора компьютеры в 1970-х годах стали значительно дешевле. [19] Новые компьютеры также обеспечивали большее взаимодействие с пользователем, что поддерживалось новыми языками программирования. [20]
Lisp , реализованный в 1958 году, был первым функциональным языком программирования . [21] В отличие от Fortran, он поддерживает рекурсию и условные выражения , [22] а также ввел динамическое управление памятью в куче и автоматическую сборку мусора . [23] В течение следующих десятилетий Lisp доминировал в приложениях искусственного интеллекта . [24] В 1978 году другой функциональный язык, ML , ввел выводимые типы и полиморфные параметры . [20] [25]
После того, как ALGOL (ALGOrithmic Language) был выпущен в 1958 и 1960 годах, [26] он стал стандартом в компьютерной литературе для описания алгоритмов . Хотя его коммерческий успех был ограничен, большинство популярных императивных языков, включая C , Pascal , Ada , C++ , Java и C# , напрямую или косвенно произошли от ALGOL 60. [27] [16] Среди его нововведений, принятых более поздними языками программирования, были большая переносимость и первое использование контекстно - свободной грамматики BNF . [28] Simula , первый язык, поддерживающий объектно-ориентированное программирование (включая подтипы , динамическую диспетчеризацию и наследование ), также произошел от ALGOL и достиг коммерческого успеха. [29] C, еще один потомок ALGOL, сохранил популярность в двадцать первом веке. C позволяет получить доступ к низкоуровневым машинным операциям больше, чем другие современные языки. Его мощность и эффективность, достигаемые отчасти за счет гибких операций с указателями , достигаются ценой усложнения написания правильного кода. [20]
Prolog , разработанный в 1972 году, был первым языком логического программирования , взаимодействующим с компьютером с использованием формальной логической нотации. [30] [31] При логическом программировании программист указывает желаемый результат и позволяет интерпретатору решать, как его достичь. [32] [31]
В 1980-х годах изобретение персонального компьютера изменило роли, для которых использовались языки программирования. [33] Новые языки, представленные в 1980-х годах, включали C++, надмножество C, которое может компилировать программы на C, но также поддерживает классы и наследование . [34] Ada и другие новые языки ввели поддержку параллелизма . [35] Японское правительство вложило значительные средства в так называемые языки пятого поколения , которые добавили поддержку параллелизма к конструкциям логического программирования, но эти языки уступили другим языкам, поддерживающим параллелизм. [36] [37]
Из-за быстрого роста Интернета и Всемирной паутины в 1990-х годах были введены новые языки программирования для поддержки веб-страниц и сетей . [38] Java , основанный на C++ и разработанный для повышения переносимости между системами и безопасности, пользовался большим успехом, поскольку эти функции необходимы для многих интернет-приложений. [39] [40] Другим развитием стали динамически типизированные языки сценариев — Python , JavaScript , PHP и Ruby — разработанные для быстрого создания небольших программ, которые координируют существующие приложения . Благодаря их интеграции с HTML они также использовались для создания веб-страниц, размещенных на серверах . [41] [42]
В 2000-х годах наблюдался спад в разработке новых языков программирования, которые добились широкой популярности. [43] Одним из нововведений стало сервисно-ориентированное программирование , разработанное для эксплуатации распределенных систем , компоненты которых соединены сетью. Сервисы похожи на объекты в объектно-ориентированном программировании, но работают в отдельном процессе. [44] C# и F# перекрестно опыляли идеи императивного и функционального программирования. [45] После 2010 года несколько новых языков — Rust , Go , Swift , Zig и Carbon — конкурировали за программное обеспечение, критически важное к производительности, для которого исторически использовался C. [46] Большинство новых языков программирования используют статическую типизацию , в то время как несколько новых языков используют динамическую типизацию, например Ring и Julia . [47] [48]
Некоторые из новых языков программирования классифицируются как визуальные языки программирования , такие как Scratch , LabVIEW и PWCT . Кроме того, некоторые из этих языков смешивают текстовое и визуальное программирование, например, Ballerina . [49] [50] [51] [52] Кроме того, эта тенденция привела к разработке проектов, которые помогают в разработке новых VPL, например, Blockly от Google . [53] Многие игровые движки, такие как Unreal и Unity, также добавили поддержку визуального скриптинга. [54] [55]
Каждый язык программирования включает в себя основные элементы для описания данных и операций или преобразований, применяемых к ним, таких как сложение двух чисел или выбор элемента из коллекции. Эти элементы управляются синтаксическими и семантическими правилами, которые определяют их структуру и значение соответственно.
Поверхностная форма языка программирования известна как его синтаксис . Большинство языков программирования являются чисто текстовыми; они используют последовательности текста, включающие слова, числа и знаки препинания, во многом как письменные естественные языки. С другой стороны, некоторые языки программирования являются графическими , использующими визуальные отношения между символами для указания программы.
Синтаксис языка описывает возможные комбинации символов, которые формируют синтаксически правильную программу. Значение, придаваемое комбинации символов, обрабатывается семантикой ( формальной или жестко закодированной в эталонной реализации ). Поскольку большинство языков являются текстовыми, в этой статье обсуждается текстовый синтаксис.
Синтаксис языка программирования обычно определяется с помощью комбинации регулярных выражений (для лексической структуры) и формы Бэкуса–Наура (для грамматической структуры). Ниже приведена простая грамматика, основанная на Lisp :
выражение ::= атом | списокатом ::= число | символчисло ::= [+-]?['0'-'9']+символ ::= ['A'-'Z''a'-'z'].*список ::= '(' выражение* ')'
Эта грамматика определяет следующее:
Ниже приведены примеры правильно сформированных последовательностей токенов в этой грамматике: 12345
, ()
и (a b c232 (1))
.
Не все синтаксически правильные программы являются семантически правильными. Многие синтаксически правильные программы, тем не менее, неправильно сформированы согласно правилам языка; и могут (в зависимости от спецификации языка и надежности реализации) привести к ошибке при переводе или выполнении. В некоторых случаях такие программы могут демонстрировать неопределенное поведение . Даже если программа хорошо определена в языке, она все равно может иметь значение, которое не подразумевалось тем, кто ее написал.
Если использовать в качестве примера естественный язык , то может оказаться невозможным приписать значение грамматически правильному предложению или предложение может оказаться ложным:
Следующий фрагмент кода на языке C синтаксически корректен, но выполняет операции, которые семантически не определены (операция *p >> 4
не имеет смысла для значения, имеющего сложный тип, и p->im
не определена, поскольку значением p
является нулевой указатель ):
комплекс * p = NULL ; комплекс abs_p = sqrt ( * p >> 4 + p -> im );
Если бы объявление типа в первой строке было опущено, программа вызвала бы ошибку на неопределенной переменной p
во время компиляции. Однако программа все равно была бы синтаксически правильной, поскольку объявления типа предоставляют только семантическую информацию.
Грамматику, необходимую для указания языка программирования, можно классифицировать по ее положению в иерархии Хомского . Синтаксис большинства языков программирования можно указать с помощью грамматики типа 2, т. е. они являются контекстно-свободными грамматиками . [56] Некоторые языки, включая Perl и Lisp, содержат конструкции, которые позволяют выполняться во время фазы синтаксического анализа. Языки, которые имеют конструкции, которые позволяют программисту изменять поведение синтаксического анализатора, делают синтаксический анализ неразрешимой проблемой и, как правило, стирают различие между синтаксическим анализом и выполнением. [57] В отличие от макросистемы Lisp и блоков Perl BEGIN
, которые могут содержать общие вычисления, макросы C являются просто заменами строк и не требуют выполнения кода. [58]
Термин семантика относится к значению языков, а не к их форме (синтаксису).
Статическая семантика определяет ограничения на структуру допустимых текстов, которые трудно или невозможно выразить в стандартных синтаксических формализмах. [1] [ неудачная проверка ] Для компилируемых языков статическая семантика по сути включает те семантические правила, которые можно проверить во время компиляции. Примеры включают проверку того, что каждый идентификатор объявлен до его использования (в языках, требующих таких объявлений) или что метки на плечах оператора case являются различными. [59] Многие важные ограничения этого типа, такие как проверка того, что идентификаторы используются в соответствующем контексте (например, не добавляют целое число к имени функции) или что вызовы подпрограмм имеют соответствующее количество и тип аргументов, можно реализовать, определив их как правила в логике, называемой системой типов . Другие формы статического анализа , такие как анализ потока данных , также могут быть частью статической семантики. Такие языки программирования, как Java и C#, имеют анализ определенного присваивания , форму анализа потока данных, как часть их соответствующей статической семантики.
После того, как данные были указаны, машина должна быть проинструктирована о выполнении операций над данными. Например, семантика может определять стратегию, с помощью которой выражения оцениваются в значения, или способ, которым управляющие структуры условно выполняют операторы . Динамическая семантика (также известная как семантика выполнения ) языка определяет, как и когда различные конструкции языка должны производить поведение программы. Существует много способов определения семантики выполнения. Естественный язык часто используется для указания семантики выполнения языков, обычно используемых на практике. Значительное количество академических исследований посвящено формальной семантике языков программирования , что позволяет указывать семантику выполнения формальным образом. Результаты из этой области исследований нашли ограниченное применение в проектировании и реализации языков программирования за пределами академической среды.
Тип данных — это набор допустимых значений и операций, которые могут быть выполнены с этими значениями. [60] Система типов каждого языка программирования определяет, какие типы данных существуют, тип выражения и как эквивалентность типов и совместимость типов функционируют в языке. [61]
Согласно теории типов , язык полностью типизирован, если спецификация каждой операции определяет типы данных, к которым эта операция применима. [62] Напротив, нетипизированный язык, такой как большинство языков ассемблера , позволяет выполнять любую операцию над любыми данными, обычно последовательностями битов различной длины. [62] На практике, хотя немногие языки полностью типизированы, большинство предлагают некоторую степень типизации. [62]
Поскольку разные типы (например, целые и числа с плавающей точкой ) представляют значения по-разному, могут возникнуть неожиданные результаты, если один тип используется, когда ожидается другой. Проверка типов отметит эту ошибку, обычно во время компиляции (проверка типов во время выполнения более затратна). [63] При строгой типизации ошибки типов всегда можно обнаружить, если только переменные явно не приведены к другому типу. Слабая типизация происходит, когда языки допускают неявное приведение типов — например, для включения операций между переменными разных типов без явного преобразования типа программистом. Чем больше случаев, в которых разрешено это приведение типов , тем меньше ошибок типов можно обнаружить. [64]
Ранние языки программирования часто поддерживали только встроенные числовые типы, такие как целые числа (со знаком и без знака) и числа с плавающей точкой (для поддержки операций с действительными числами , которые не являются целыми числами). Большинство языков программирования поддерживают несколько размеров чисел с плавающей точкой (часто называемых float и double ) и целых чисел в зависимости от размера и точности, требуемых программисту. Сохранение целого числа в типе, который слишком мал для его представления, приводит к переполнению целого числа . Наиболее распространенным способом представления отрицательных чисел со знаковыми типами является дополнение до двух , хотя также используется дополнение до единицы . [65] Другие распространенные типы включают Boolean — который либо true, либо false — и character — традиционно один байт , достаточный для представления всех символов ASCII . [66]
Массивы — это тип данных, элементы которого во многих языках должны состоять из одного типа фиксированной длины. Другие языки определяют массивы как ссылки на данные, хранящиеся в другом месте, и поддерживают элементы различных типов. [67] В зависимости от языка программирования последовательности из нескольких символов, называемые строками , могут поддерживаться как массивы символов или их собственный примитивный тип . [68] Строки могут иметь фиксированную или переменную длину, что обеспечивает большую гибкость за счет увеличения пространства для хранения и большей сложности. [69] Другие типы данных, которые могут поддерживаться, включают списки , [70] ассоциативные (неупорядоченные) массивы, доступные через ключи, [71] записи, в которых данные отображаются на имена в упорядоченной структуре, [72] и кортежи — похожие на записи, но без имен для полей данных. [73] Указатели хранят адреса памяти, обычно ссылаясь на местоположения в куче , где хранятся другие данные. [74]
Простейшим типом, определяемым пользователем, является порядковый тип , значения которого могут быть отображены на набор положительных целых чисел. [75] С середины 1980-х годов большинство языков программирования также поддерживают абстрактные типы данных , в которых представление данных и операций скрыто от пользователя , который может получить доступ только к интерфейсу . [76] Преимущества абстракции данных могут включать повышенную надежность, сниженную сложность, меньшую вероятность конфликта имен и возможность изменения базовой структуры данных без необходимости изменения клиентом своего кода. [77]
При статической типизации все выражения имеют свои типы, определенные до выполнения программы, как правило, во время компиляции. [62] Наиболее широко используемые статически типизированные языки программирования требуют, чтобы типы переменных были указаны явно. В некоторых языках типы неявны; одной из форм этого является то, что компилятор может выводить типы на основе контекста. Недостатком неявной типизации является вероятность того, что ошибки останутся незамеченными. [78] Полный вывод типов традиционно ассоциируется с функциональными языками, такими как Haskell и ML . [79]
При динамической типизации тип не прикрепляется к переменной, а только к закодированному в ней значению. Одна переменная может быть повторно использована для значения другого типа. Хотя это обеспечивает большую гибкость для программиста, это достигается ценой меньшей надежности и меньшей способности языка программирования проверять наличие ошибок. [80] Некоторые языки допускают переменные типа union , которым может быть присвоен любой тип значения, в исключение из их обычных правил статической типизации. [81]
В вычислениях несколько инструкций могут выполняться одновременно. Многие языки программирования поддерживают параллелизм на уровне инструкций и подпрограмм. [82] К двадцать первому веку дополнительная вычислительная мощность компьютеров все больше обеспечивалась использованием дополнительных процессоров, что требовало от программистов разработки программного обеспечения, которое одновременно использует несколько процессоров для достижения улучшенной производительности. [83] Интерпретируемые языки , такие как Python и Ruby, не поддерживают одновременное использование нескольких процессоров. [84] Другие языки программирования поддерживают управление данными, совместно используемыми различными потоками, путем управления порядком выполнения ключевых инструкций с помощью семафоров , управления доступом к общим данным через монитор или включения передачи сообщений между потоками. [85]
Во многих языках программирования есть обработчики исключений — раздел кода, вызываемый ошибками во время выполнения , который может справляться с ними двумя основными способами: [86]
Некоторые языки программирования поддерживают выделение блока кода для выполнения независимо от того, возникло ли исключение до достижения кода; это называется финализацией. [87]
Существует компромисс между возросшей способностью обрабатывать исключения и сниженной производительностью. [88] Например, хотя ошибки индекса массива являются обычным явлением [89], C не проверяет их из соображений производительности. [88] Хотя программисты могут писать код для перехвата пользовательских исключений, это может загромождать программу. Стандартные библиотеки в некоторых языках, таких как C, используют свои возвращаемые значения для указания исключения. [90] Некоторые языки и их компиляторы имеют возможность включать и выключать возможность обработки ошибок, как временно, так и постоянно. [91]
Одним из наиболее важных влияний на дизайн языков программирования была архитектура компьютера . Императивные языки , наиболее часто используемый тип, были разработаны для хорошей работы на архитектуре фон Неймана , наиболее распространенной архитектуре компьютеров. [92] В архитектуре фон Неймана память хранит как данные, так и инструкции, в то время как ЦП, который выполняет инструкции над данными, является отдельным, и данные должны передаваться туда и обратно к ЦП. Центральными элементами в этих языках являются переменные, присваивание и итерация , что более эффективно, чем рекурсия на этих машинах. [93]
Многие языки программирования были разработаны с нуля, изменены для удовлетворения новых потребностей и объединены с другими языками. Многие в конечном итоге вышли из употребления. [ необходима цитата ] Рождение языков программирования в 1950-х годах было стимулировано желанием создать универсальный язык программирования, подходящий для всех машин и применений, избегая необходимости писать код для разных компьютеров. [94] К началу 1960-х годов идея универсального языка была отвергнута из-за различных требований к разнообразию целей, для которых писался код. [95]
Желательные качества языков программирования включают в себя читаемость, записываемость и надежность. [96] Эти особенности могут снизить стоимость обучения программистов языку, количество времени, необходимое для написания и поддержки программ на языке, стоимость компиляции кода и повысить производительность во время выполнения. [97]
Проектирование языков программирования часто подразумевает компромиссы. [107] Например, функции, повышающие надежность, обычно достигаются за счет производительности. [108] Повышение выразительности за счет большого количества операторов упрощает написание кода, но достигается за счет удобочитаемости. [108]
Программирование на естественном языке было предложено как способ устранения необходимости в специализированном языке для программирования. Однако эта цель остается далекой, и ее преимущества открыты для обсуждения. Эдсгер В. Дейкстра занял позицию, что использование формального языка необходимо для предотвращения введения бессмысленных конструкций. [109] Алан Перлис также пренебрежительно отнесся к этой идее. [110]
Спецификация языка программирования — это артефакт, который пользователи языка и разработчики могут использовать для согласования того, является ли фрагмент исходного кода допустимой программой на этом языке, и если да, то каким должно быть его поведение.
Спецификация языка программирования может иметь несколько форм, включая следующие:
Реализация языка программирования — это преобразование программы в машинный код , который может быть выполнен аппаратным обеспечением. Затем машинный код может быть выполнен с помощью операционной системы . [114] Наиболее распространенной формой интерпретации в производственном коде является компилятор , который транслирует исходный код через язык промежуточного уровня в машинный код, известный как исполняемый файл . После компиляции программы она будет работать быстрее, чем при других методах реализации. [115] Некоторые компиляторы способны обеспечить дополнительную оптимизацию для уменьшения использования памяти или вычислений при запуске исполняемого файла, но при этом увеличивается время компиляции. [116]
Другой метод реализации — запуск программы с помощью интерпретатора , который переводит каждую строку программного обеспечения в машинный код непосредственно перед его выполнением. Хотя это может облегчить отладку, недостатком интерпретации является то, что она выполняется в 10–100 раз медленнее, чем скомпилированный исполняемый файл. [117] Гибридные методы интерпретации обеспечивают некоторые преимущества компиляции и некоторые преимущества интерпретации через частичную компиляцию. Одной из форм этого является компиляция «точно в срок» , при которой программное обеспечение заранее компилируется в промежуточный язык, а затем в машинный код непосредственно перед выполнением. [118]
Хотя большинство наиболее часто используемых языков программирования имеют полностью открытые спецификации и реализации, многие языки программирования существуют только как проприетарные языки программирования с реализацией, доступной только от одного поставщика, который может заявить, что такой проприетарный язык является его интеллектуальной собственностью. Проприетарные языки программирования обычно являются предметно-ориентированными языками или внутренними языками сценариев для одного продукта; некоторые проприетарные языки используются только внутри поставщика, в то время как другие доступны внешним пользователям. [ необходима цитата ]
Некоторые языки программирования существуют на границе между проприетарными и открытыми; например, корпорация Oracle заявляет права собственности на некоторые аспекты языка программирования Java , [119] а язык программирования C# компании Microsoft , который имеет открытые реализации большинства частей системы, также имеет Common Language Runtime (CLR) в качестве закрытой среды. [120]
Многие проприетарные языки широко используются, несмотря на их проприетарную природу; примеры включают MATLAB , VBScript и Wolfram Language . Некоторые языки могут переходить от закрытых к открытым; например, Erlang изначально был внутренним языком программирования Ericsson. [121]
Языки программирования с открытым исходным кодом особенно полезны для приложений открытой науки , расширяя возможности репликации и совместного использования кода. [122]
Были созданы тысячи различных языков программирования, в основном в области вычислительной техники. [123] Отдельные программные проекты обычно используют пять языков программирования или больше. [124]
Языки программирования отличаются от большинства других форм человеческого выражения тем, что они требуют большей степени точности и полноты. При использовании естественного языка для общения с другими людьми авторы и ораторы могут быть двусмысленными и делать небольшие ошибки, и все равно ожидать, что их намерение будет понято. Однако, образно говоря, компьютеры «делают именно то, что им говорят делать», и не могут «понять», какой код намеревался написать программист. Комбинация определения языка, программы и входных данных программы должна полностью определять внешнее поведение, которое происходит при выполнении программы, в пределах области управления этой программой. С другой стороны, идеи об алгоритме могут быть переданы людям без точности, необходимой для выполнения, с помощью псевдокода , который чередует естественный язык с кодом, написанным на языке программирования.
Язык программирования предоставляет структурированный механизм для определения фрагментов данных, а также операций или преобразований, которые могут быть выполнены автоматически с этими данными. Программист использует абстракции, присутствующие в языке, для представления концепций, участвующих в вычислении. Эти концепции представлены в виде набора простейших доступных элементов (называемых примитивами ). [125] Программирование — это процесс, посредством которого программисты объединяют эти примитивы для составления новых программ или адаптации существующих к новым вариантам использования или изменяющейся среде.
Программы для компьютера могут выполняться в пакетном процессе без человеческого взаимодействия, или пользователь может вводить команды в интерактивном сеансе интерпретатора . В этом случае «команды» — это просто программы, выполнение которых связано вместе. Когда язык может выполнять свои команды через интерпретатор (такой как оболочка Unix или другой интерфейс командной строки ), без компиляции, он называется скриптовым языком . [126]
Определить, какой язык программирования является наиболее широко используемым, сложно, поскольку определение использования меняется в зависимости от контекста. Один язык может занимать большее количество часов программиста, другой имеет больше строк кода, а третий может потреблять больше всего процессорного времени. Некоторые языки очень популярны для определенных видов приложений. Например, COBOL по-прежнему силен в корпоративных центрах обработки данных, часто на больших мэйнфреймах ; [127] [128] Fortran в научных и инженерных приложениях; Ada в аэрокосмических, транспортных, военных, реальных и встроенных приложениях; и C во встроенных приложениях и операционных системах. Другие языки регулярно используются для написания множества различных видов приложений.
Были предложены различные методы измерения популярности языка, каждый из которых имеет свою специфику в отношении измеряемого объекта:
Объединив и усреднив информацию с различных интернет-сайтов, stackify.com сообщил о десяти самых популярных языках программирования (в порядке убывания общей популярности): Java , C , C++ , Python , C# , JavaScript , VB.NET , R , PHP и MATLAB . [132]
По состоянию на июнь 2024 года пятью лучшими языками программирования по индексу TIOBE являются Python , C++ , C , Java и C# . TIOBE предоставляет список 100 лучших языков программирования по популярности и обновляет этот список каждый месяц. [133]
Диалект языка программирования или языка обмена данными — это (относительно небольшая) вариация или расширение языка, которое не меняет его внутреннюю природу. В таких языках, как Scheme и Forth , стандарты могут считаться недостаточными, неадекватными или незаконными разработчиками, поэтому часто они отклоняются от стандарта, создавая новый диалект . В других случаях диалект создается для использования в языке, специфичном для предметной области , часто в подмножестве. В мире Lisp большинство языков, использующих базовый синтаксис S-выражений и семантику, подобную Lisp, считаются диалектами Lisp, хотя они сильно различаются, как, скажем, Racket и Clojure . Поскольку для одного языка характерно наличие нескольких диалектов, неопытному программисту может быть довольно сложно найти нужную документацию. Язык BASIC имеет множество диалектов .
Языки программирования часто делятся на четыре основные категории: императивные , функциональные , логические и объектно-ориентированные . [134]
Хотя языки разметки не являются языками программирования, некоторые из них имеют расширения, которые поддерживают ограниченное программирование. Кроме того, существуют языки специального назначения, которые нелегко сравнивать с другими языками программирования. [138]
HTML не является языком программирования.
...это язык разметки, а не язык программирования.
На этом сайте перечислено 8512 языков.
Результаты: Мы обнаружили (a) среднее количество языков в проекте — 5 с явно доминирующим основным языком общего назначения и 5 часто используемыми типами DSL, (b) значительное влияние размера, количества коммитов и основного языка на количество языков, а также отсутствие значительного влияния возраста и количества участников, и (c) три языковые экосистемы, сгруппированные вокруг XML, Shell/Make и HTML/CSS. Выводы: Многоязычное программирование, по-видимому, распространено в проектах с открытым исходным кодом и является фактором, который необходимо учитывать при инструментировании и при оценке разработки и обслуживания таких программных систем.
{{cite web}}
: CS1 maint: multiple names: authors list (link)