Язык программирования - Programming language

Исходный код для простой компьютерной программы , написанной на языке программирования Си . Серые линии - это комментарии, которые помогают объяснить программу людям на естественном языке . При компиляции и запуске он выдаст сообщение « Hello, world! ».

Язык программирования является формальным языком , содержащим набор строк , которые производят различные виды продукции машинного кода . Языки программирования - это один из видов компьютерных языков , которые используются в компьютерном программировании для реализации алгоритмов .

Большинство языков программирования состоят из инструкций для компьютеров . Существуют программируемые машины, которые используют набор конкретных инструкций , а не общие языки программирования . С начала 1800-х годов программы использовались для управления поведением таких машин, как жаккардовые ткацкие станки , музыкальные шкатулки и пианино . Программы для этих машин (например, свитки пианино) не производили различного поведения в ответ на разные входные данные или условия.

Были созданы тысячи различных языков программирования, и с каждым годом создается все больше. Многие языки программирования написаны в императивной форме (т. Е. Как последовательность операций, которые необходимо выполнить), в то время как другие языки используют декларативную форму (т. Е. Указывается желаемый результат, а не то, как его достичь).

Описание языка программирования обычно делится на два компонента: синтаксис (форма) и семантика (значение). Некоторые языки определены в документе спецификации (например, язык программирования C определен стандартом ISO ), в то время как другие языки (например, Perl ) имеют доминирующую реализацию, которая рассматривается как ссылка . Некоторые языки имеют и то, и другое, при этом основной язык определяется стандартом, а расширения, взятые из доминирующей реализации, являются общими.

Теория языков программирования - это подраздел компьютерных наук, который занимается проектированием, реализацией, анализом, характеристикой и классификацией языков программирования.

Определения

Язык программирования - это обозначение для написания программ , которые являются спецификациями вычисления или алгоритма . Некоторые авторы ограничивают термин «язык программирования» теми языками, которые могут выражать все возможные алгоритмы. Черты характера, которые часто считаются важными для того, что составляет язык программирования, включают:

Функция и цель
Язык программирования является языком , используемым для записи компьютерных программ , которая включает в себя компьютер , выполняя какое - то вычисление или алгоритм и , возможно , управлять внешними устройствами , такими как принтеры , дисководы , роботы , и так далее. Например, программы PostScript часто создаются другой программой для управления компьютерным принтером или дисплеем. В более общем плане язык программирования может описывать вычисления на некоторой, возможно, абстрактной машине. Принято считать, что полная спецификация языка программирования включает описание, возможно, идеализированное, машины или процессора для этого языка. В большинстве практических контекстов язык программирования включает компьютер; следовательно, языки программирования обычно определяются и изучаются таким образом. Языки программирования отличаются от естественных языков тем, что естественные языки используются только для взаимодействия между людьми, в то время как языки программирования также позволяют людям передавать инструкции машинам.
Абстракции
Языки программирования обычно содержат абстракции для определения и управления структурами данных или управления потоком выполнения . Практическая необходимость того, чтобы язык программирования поддерживал адекватные абстракции, выражается принципом абстракции . Этот принцип иногда формулируется как рекомендация программисту правильно использовать такие абстракции.
Выразительная сила
Теория вычисления классифицирует языки по вычислениям они способны выразить. Все полные по Тьюрингу языки могут реализовывать один и тот же набор алгоритмов . ANSI / ISO SQL-92 и Charity - это примеры языков, которые не являются полными по Тьюрингу, но их часто называют языками программирования.

Такие языки разметки, как XML , HTML или troff , которые определяют структурированные данные , обычно не считаются языками программирования. Однако языки программирования могут разделять синтаксис с языками разметки, если определена вычислительная семантика. XSLT , например, представляет собой полный язык Тьюринга, полностью использующий синтаксис XML. Более того, LaTeX , который в основном используется для структурирования документов, также содержит полное подмножество Тьюринга.

Термин компьютерный язык иногда используется как синоним языка программирования. Однако использование обоих терминов варьируется среди авторов, включая точную область применения каждого из них. Одно использование описывает языки программирования как подмножество компьютерных языков. Точно так же языки, используемые в вычислениях, которые имеют другую цель, чем выражение компьютерных программ, обычно называются компьютерными языками. Например, языки разметки иногда называют компьютерными языками, чтобы подчеркнуть, что они не предназначены для использования в программировании.

Другое использование рассматривает языки программирования как теоретические конструкции для программирования абстрактных машин , а компьютерные языки как их подмножество, которое работает на физических компьютерах, которые имеют ограниченные аппаратные ресурсы. Джон С. Рейнольдс подчеркивает, что языки формальных спецификаций являются такими же языками программирования, как и языки, предназначенные для исполнения. Он также утверждает, что текстовые и даже графические форматы ввода, которые влияют на поведение компьютера, являются языками программирования, несмотря на то, что они обычно не являются полными по Тьюрингу, и отмечает, что незнание концепций языка программирования является причиной многих недостатков форматов ввода.

История

Ранние разработки

Самые ранние компьютеры, такие как Colossus , программировались без помощи сохраненной программы , путем изменения их схем или установки банков физических средств управления.

Чуть позже программы можно было писать на машинном языке , где программист записывал каждую инструкцию в числовой форме, которую оборудование могло выполнять напрямую. Например, инструкция по сложению значения в двух ячейках памяти может состоять из 3 чисел: «код операции», который выбирает операцию «сложение», и две ячейки памяти. Программы в десятичной или двоичной форме считывались с перфокарт , бумажной ленты, магнитной ленты или включались переключателями на передней панели компьютера. Машинные языки позже были названы языками программирования первого поколения (1GL).

Следующим шагом стала разработка так называемых языков программирования второго поколения (2GL) или языков ассемблера , которые все еще были тесно связаны с архитектурой набора команд конкретного компьютера. Это сделало программу более удобочитаемой и избавило программиста от утомительных и подверженных ошибкам вычислений адресов.

Первые языки программирования высокого уровня или языки программирования третьего поколения (3GL) были написаны в 1950-х годах. Ранний язык программирования высокого уровня, чтобы быть рассчитан на компьютере был планкалкюль , разработан для немецкого Z3 от Конрада Цузе в период между 1943 и 1945 годами , однако, не был реализован до 1998 и 2000 гг.

Джон Мочли «s Сокращенный код , предложенный в 1949 году, был одним из первых языков высокого уровня , когда - либо для электронной вычислительной машины . В отличие от машинного кода , операторы Short Code представляют математические выражения в понятной форме. Однако программу приходилось транслировать в машинный код каждый раз при запуске, что делало процесс намного медленнее, чем выполнение эквивалентного машинного кода.

В университете Манчестера , Алик Глени разработал AutoCode в начале 1950 - х годов. В качестве языка программирования он использовал компилятор для автоматического преобразования языка в машинный код. Первый код и компилятор были разработаны в 1952 году для компьютера Mark 1 в Манчестерском университете и считаются первым скомпилированным языком программирования высокого уровня.

Второй автокод был разработан Р.А. Брукером для Mark 1 в 1954 году и назывался «Автокод Mark 1». Брукер также разработал автокод для Ferranti Mercury в 1950-х годах совместно с Манчестерским университетом. Версия для EDSAC 2 был разработан DF Хартли из Кембриджского университета математической лаборатории в 1961 г. Известный как EDSAC 2 AutoCode, это была прямая разработка от Mercury AutoCode адаптирована для местных условий и было отмечено , для ее оптимизации объектного кода и исходного языка- диагностика, продвинутая для того времени. Atlas Autocode - это современный, но отдельный поток разработки, который был разработан для машины Atlas 1 Манчестерского университета .

В 1954 году Джон Бэкус изобрел FORTRAN в IBM . Это был первый широко используемый язык программирования общего назначения высокого уровня, который имел функциональную реализацию, а не просто проект на бумаге. Это по-прежнему популярный язык для высокопроизводительных вычислений и используется для программ, которые оценивают и оценивают самые быстрые суперкомпьютеры в мире .

Еще один ранний язык программирования, разработанный Грейс Хоппер в США, называется FLOW-MATIC . Он был разработан для UNIVAC I в Remington Rand в период с 1955 по 1959 год. Хоппер обнаружила, что заказчики, занимающиеся обработкой бизнес-данных, не любят математическую нотацию, и в начале 1955 года она и ее команда написали спецификацию для английского языка программирования и реализовали ее. прототип. Компилятор FLOW-MATIC стал общедоступным в начале 1958 года и был практически завершен в 1959 году. FLOW-MATIC оказал большое влияние на разработку COBOL , поскольку в то время фактически использовались только он и его прямой потомок AIMACO .

Уточнение

Более широкое использование языков высокого уровня ввело требование о языках программирования низкого уровня или языках системного программирования . Эти языки в той или иной степени предоставляют возможности между языками ассемблера и языками высокого уровня. Их можно использовать для выполнения задач, требующих прямого доступа к аппаратным средствам, но при этом обеспечивая структуры управления более высокого уровня и проверку ошибок.

Период с 1960-х до конца 1970-х годов принес развитие основных языковых парадигм, используемых в настоящее время:

Каждый из этих языков породил потомков, и большинство современных языков программирования считают, что по крайней мере один из них является своим предком.

В 1960-х и 1970-х годах также велись серьезные дискуссии о достоинствах структурного программирования и о том, следует ли разрабатывать языки программирования для его поддержки. Эдсгер Дейкстра в известном письме 1968 года, опубликованном в « Коммуникациях ACM» , утверждал, что операторы Goto должны быть исключены из всех языков программирования «более высокого уровня».

Консолидация и рост

Подборка учебников по программированию на популярных и малоизвестных языках. Это лишь некоторые из тысяч языков программирования и диалектов, которые были созданы в истории.

1980-е были годами относительной консолидации. C ++ сочетает объектно-ориентированное и системное программирование. Правительство Соединенных Штатов стандартизировало Ада , язык системного программирования, полученный на основе Паскаля и предназначенный для использования оборонными подрядчиками. В Японии и других странах были потрачены огромные суммы на исследование так называемых языков «пятого поколения», которые включали в себя конструкции логического программирования. Сообщество функциональных языков перешло к стандартизации ML и Lisp. Вместо того, чтобы изобретать новые парадигмы, все эти движения развивали идеи, изобретенные в предыдущие десятилетия.

Одной из важных тенденций в разработке языков для программирования крупномасштабных систем в 1980-е годы было повышенное внимание к использованию модулей или крупномасштабных организационных единиц кода. Modula-2 , Ada и ML разработали в 1980-х годах известные модульные системы, которые часто объединялись с общими конструкциями программирования .

Быстрый рост Интернета в середине 1990-х годов создал возможности для новых языков. Perl , изначально представлявший собой инструмент для создания сценариев Unix, впервые выпущенный в 1987 году, стал обычным явлением на динамических веб-сайтах . Java стала использоваться для программирования на стороне сервера, и виртуальные машины с байт-кодом снова стали популярными в коммерческих условиях с их обещанием « писать один раз, запускать где угодно » ( UCSD Pascal был популярен какое-то время в начале 1980-х). Эти разработки не были принципиально новыми; скорее, они были уточнением многих существующих языков и парадигм (хотя их синтаксис часто был основан на семействе языков программирования C).

Эволюция языков программирования продолжается как в промышленности, так и в исследованиях. Текущие направления включают проверку безопасности и надежности , новые виды модульности ( миксины , делегаты , аспекты ) и интеграцию с базами данных, такую ​​как LINQ от Microsoft .

Языки программирования четвертого поколения (4GL) - это языки компьютерного программирования, которые стремятся обеспечить более высокий уровень абстракции деталей внутреннего компьютерного оборудования, чем 3GL. Языки программирования пятого поколения (5GL) - это языки программирования, основанные на решении проблем с использованием ограничений, заданных программе, а не на использовании алгоритма, написанного программистом.

Элементы

Все языки программирования имеют некоторые примитивные строительные блоки для описания данных и процессов или преобразований, применяемых к ним (например, сложение двух чисел или выбор элемента из коллекции). Эти примитивы определяются синтаксическими и семантическими правилами, которые описывают их структуру и значение соответственно.

Синтаксис

Анализировать дерево из кода Python со вставкой токенизации
Подсветка синтаксиса часто используется для помощи программистам в распознавании элементов исходного кода. Вышеупомянутый язык - Python .

Поверхностная форма языка программирования известна как его синтаксис . Большинство языков программирования являются чисто текстовыми; они используют последовательности текста, включая слова, числа и знаки препинания, во многом как письменные естественные языки. С другой стороны, есть некоторые языки программирования, которые имеют более графический характер и используют визуальные отношения между символами для определения программы.

Синтаксис языка описывает возможные комбинации символов, которые образуют синтаксически правильную программу. Значение, данное комбинации символов, обрабатывается семантикой ( формальной или жестко запрограммированной в эталонной реализации ). Поскольку большинство языков являются текстовыми, в этой статье обсуждается текстовый синтаксис.

Синтаксис языка программирования обычно определяется с помощью комбинации регулярных выражений (для лексической структуры) и формы Бэкуса – Наура (для грамматической структуры). Ниже представлена ​​простая грамматика, основанная на Лиспе :

expression ::= atom | list
atom       ::= number | symbol
number     ::= [+-]?['0'-'9']+
symbol     ::= ['A'-'Z''a'-'z'].*
list       ::= '(' expression* ')'

Эта грамматика определяет следующее:

  • выражение является либо атом или список ;
  • атом является либо число или символ ;
  • номер представляет собой непрерывную последовательность из одной или более десятичных цифр, необязательно предшествует знак плюс или минус;
  • символ является буквой с нуля или более любых символов ( за исключением пробела); а также
  • список является согласованной парой скобок, с нулем или более выражений внутри него.

Ниже приведены примеры хорошо сформированных маркеров последовательностей в этой грамматике: 12345, ()и (a b c232 (1)).

Не все синтаксически правильные программы семантически правильны. Многие синтаксически правильные программы, тем не менее, плохо сформированы в соответствии с правилами языка; и может (в зависимости от спецификации языка и надежности реализации) привести к ошибке при переводе или выполнении. В некоторых случаях такие программы могут демонстрировать неопределенное поведение . Даже если программа четко определена в языке, она может иметь значение, не предназначенное для ее написания.

Используя в качестве примера естественный язык , может оказаться невозможным присвоить значение грамматически правильному предложению или предложение может быть ложным:

Следующий фрагмент языка C является синтаксически правильным, но выполняет операции, которые не определены семантически (операция *p >> 4не имеет значения для значения, имеющего сложный тип, и p->imне определена, поскольку значением pявляется нулевой указатель ):

complex *p = NULL;
complex abs_p = sqrt(*p >> 4 + p->im);

Если бы объявление типа в первой строке было опущено, программа выдала бы ошибку неопределенной переменной pво время компиляции. Однако программа все равно будет синтаксически правильной, поскольку объявления типов предоставляют только семантическую информацию.

Грамматика, необходимая для определения языка программирования, может быть классифицирована по ее положению в иерархии Хомского . Синтаксис большинства языков программирования можно указать с помощью грамматики типа 2, т. Е. Они являются контекстно-независимыми грамматиками . Некоторые языки, включая Perl и Lisp, содержат конструкции, которые позволяют выполнение на этапе синтаксического анализа. Языки, в которых есть конструкции, позволяющие программисту изменять поведение синтаксического анализатора, делают синтаксический анализ неразрешимой проблемой и обычно стирают различие между синтаксическим анализом и выполнением. В отличие от макросистемы Lisp и BEGINблоков Perl , которые могут содержать общие вычисления, макросы C представляют собой просто замену строк и не требуют выполнения кода.

Семантика

Термин « семантика» относится к значению языков, а не к их форме ( синтаксису ).

Статическая семантика

Статическая семантика определяет ограничения на структуру действительных текстов, которые трудно или невозможно выразить в стандартных синтаксических формализмах. Для скомпилированных языков статическая семантика по существу включает те семантические правила, которые можно проверить во время компиляции. Примеры включают проверку того, что каждый идентификатор объявлен до его использования (на языках, которые требуют такого объявления) или что метки на ответвлениях оператора case различны. Многие важные ограничения этого типа, такие как проверка того, что идентификаторы используются в соответствующем контексте (например, не добавляют целое число к имени функции) или что вызовы подпрограмм имеют соответствующее количество и тип аргументов, могут быть реализованы путем определения их как правил в логике, называемой системой типов . Другие формы статического анализа, такие как анализ потока данных, также могут быть частью статической семантики. Новые языки программирования, такие как Java и C #, имеют определенный анализ назначений , форму анализа потока данных, как часть их статической семантики.

Динамическая семантика

После того, как данные были указаны, машина должна быть проинструктирована о выполнении операций с данными. Например, семантика может определять стратегию, с помощью которой выражения оцениваются в значения, или способ, которым управляющие структуры условно выполняют инструкции . В Динамической семантике (также известная как исполнения семантика ) от языка определяет , как и когда различные конструкты языка должны производить программы поведения. Есть много способов определения семантики выполнения. Естественный язык часто используется для определения семантики исполнения языков, обычно используемых на практике. Значительный объем академических исследований был посвящен формальной семантике языков программирования , которая позволяет формально определять семантику выполнения. Результаты этой области исследований нашли ограниченное применение в разработке и реализации языков программирования за пределами академических кругов.

Система типов

Система типов определяет, как язык программирования классифицирует значения и выражения по типам , как он может управлять этими типами и как они взаимодействуют. Целью системы типов является проверка и обычно обеспечение определенного уровня корректности в программах, написанных на этом языке, путем обнаружения определенных некорректных операций. Любая разрешимая система типов предполагает компромисс: отвергая множество неправильных программ, она может также запрещать некоторые правильные, хотя и необычные программы. Чтобы обойти этот недостаток, в ряде языков есть лазейки для типов , обычно непроверенные преобразования, которые могут использоваться программистом для явного разрешения обычно запрещенных операций между разными типами. В большинстве типизированных языков система типов используется только для программ проверки типов , но ряд языков, обычно функциональных, выявляют типы , избавляя программиста от необходимости писать аннотации типов. Формальное проектирование и изучение систем типов известно как теория типов .

Типизированные и нетипизированные языки

Язык является типизированным, если спецификация каждой операции определяет типы данных, к которым эта операция применима. Например, данные, представленные символом , представляют "this text between the quotes"собой строку , и во многих языках программирования деление числа на строку не имеет смысла и не будет выполняться. Недопустимая операция может быть обнаружена при компиляции программы («статическая» проверка типа) и будет отклонена компилятором с сообщением об ошибке компиляции, или она может быть обнаружена во время работы программы («динамическая» проверка типа), в результате чего в исключении времени выполнения . Многие языки позволяют функции, называемой обработчиком исключений, обрабатывать это исключение и, например, всегда возвращать в качестве результата «-1».

Особым случаем типизированных языков являются однотипные языки. Часто это языки сценариев или разметки, такие как REXX или SGML , и они имеют только один тип данных - чаще всего символьные строки, которые используются как для символьных, так и для числовых данных.

Напротив, нетипизированный язык , такой как большинство языков ассемблера , позволяет выполнять любую операцию с любыми данными, как правило, с последовательностями битов различной длины. Нетипизированные языки высокого уровня включают BCPL , Tcl и некоторые разновидности Forth .

На практике, хотя немногие языки считаются типизированными в соответствии с теорией типов (проверка или отклонение всех операций), большинство современных языков предлагают определенную степень типизации. Многие рабочие языки предоставляют средства для обхода или подрыва системы типов, жертвуя типобезопасностью для более тонкого контроля над выполнением программы (см. Приведение типов ).

Статическая и динамическая типизация

При статической типизации типы всех выражений определяются до выполнения программы, обычно во время компиляции. Например, 1 и (2 + 2) - целочисленные выражения; они не могут быть переданы функции, которая ожидает строку, или сохранены в переменной, которая определена для хранения дат.

Статически типизированные языки могут быть явно типизированными или предполагаемыми по типу . В первом случае программист должен явно писать типы в определенных текстовых позициях (например, в объявлениях переменных ). Во втором случае компилятор выводит типы выражений и деклараций на основе контекста. Большинство основных языков со статической типизацией, таких как C ++ , C # и Java , явно типизированы. Полный вывод типов традиционно ассоциировался с менее распространенными языками, такими как Haskell и ML . Однако многие явно типизированные языки поддерживают частичный вывод типов; например, C ++ , Java и C # в определенных ограниченных случаях выводят типы. Кроме того, некоторые языки программирования позволяют автоматически преобразовывать одни типы в другие; например, int можно использовать там, где программа ожидает число с плавающей запятой.

Динамическая типизация , также называемая скрытой типизацией , определяет типобезопасность операций во время выполнения; другими словами, типы связаны со значениями времени выполнения, а не с текстовыми выражениями . Как и в случае языков с предполагаемым типом, языки с динамической типизацией не требуют от программиста написания явных аннотаций типов к выражениям. Среди прочего, это может позволить одной переменной ссылаться на значения разных типов в разных точках выполнения программы. Однако ошибки типане могут быть автоматически обнаружены до тех пор, пока на самом деле не будет выполнен фрагмент кода, что можетзатруднить отладку . Lisp , Smalltalk , Perl , Python , JavaScript и Ruby - все это примеры языков с динамической типизацией.

Слабая и сильная типизация

Слабая типизация позволяет рассматривать значение одного типа как другое, например, трактовать строку как число. Иногда это может быть полезно, но также может позволить некоторым видам программных ошибок остаться незамеченными во время компиляции и даже во время выполнения .

Строгая типизация предотвращает эти программные ошибки. Попытка выполнить операцию с неверным типом значения вызывает ошибку. Сильно типизированные языки часто называют типобезопасным или безопасной .

Альтернативное определение для «слабо типизированного» относится к таким языкам, как Perl и JavaScript , которые допускают большое количество неявных преобразований типов. В JavaScript, например, выражение 2 * xнеявно преобразуется xв число, и это преобразование xвыполняется null, даже если это undefined,, Arrayили строка букв. Такие неявные преобразования часто полезны, но они могут маскировать ошибки программирования. Сильный и статичный в настоящее время обычно считаются ортогональными понятиями, но их использование в литературе отличается. Некоторые используют термин строго типизированный для обозначения строго, статически типизированного или, что еще более сбивает с толку, для обозначения просто статически типизированного . Таким образом, C был назван как строго типизированным, так и слабо статически типизированным.

Некоторым профессиональным программистам может показаться странным, что C может быть «слабо статически типизирован». Однако обратите внимание, что использование универсального указателя, указателя void * , действительно позволяет преобразовывать указатели в другие указатели без необходимости выполнять явное приведение. Это очень похоже на приведение массива байтов к любому типу данных в C без использования явного приведения, такого как (int)или (char).

Стандартная библиотека и система времени выполнения

Большинство языков программирования имеют связанную базовую библиотеку (иногда называемую «стандартной библиотекой», особенно если она включена как часть опубликованного стандарта языка), которая обычно предоставляется всеми реализациями языка. Базовые библиотеки обычно включают определения для часто используемых алгоритмов, структур данных и механизмов ввода и вывода.

Граница между языком и его базовой библиотекой отличается от языка к языку. В некоторых случаях разработчики языка могут рассматривать библиотеку как отдельный объект от языка. Однако основная библиотека языка часто рассматривается пользователями как часть языка, а некоторые спецификации языка даже требуют, чтобы эта библиотека была доступна во всех реализациях. В самом деле, некоторые языки спроектированы таким образом, что значения некоторых синтаксических конструкций невозможно даже описать без ссылки на базовую библиотеку. Например, в Java строковый литерал определяется как экземпляр java.lang.Stringкласса; Аналогично, в Smalltalk , анонимная функция выражение ( «блок») создает экземпляр библиотеки BlockContextкласса. И наоборот, Scheme содержит несколько согласованных подмножеств, которых достаточно для построения остальной части языка в виде библиотечных макросов, поэтому разработчики языка даже не утруждают себя вопросом, какие части языка должны быть реализованы как языковые конструкции, а какие - как части. библиотеки.

Дизайн и реализация

Языки программирования имеют общие свойства с естественными языками, связанные с их назначением в качестве средств коммуникации, имеют синтаксическую форму, отдельную от своей семантики, и демонстрируют языковые семейства родственных языков, разветвляющиеся один от другого. Но, будучи искусственными конструкциями, они также фундаментально отличаются от языков, которые эволюционировали в результате использования. Существенное отличие состоит в том, что язык программирования можно полностью описать и изучить целиком, поскольку он имеет точное и конечное определение. Напротив, естественные языки имеют изменяющиеся значения, данные их пользователями в разных сообществах. Хотя сконструированные языки также являются искусственными языками, разработанными с нуля с определенной целью, им не хватает точного и полного семантического определения, которое имеет язык программирования.

Многие языки программирования были разработаны с нуля, изменены для удовлетворения новых потребностей и объединены с другими языками. Многие в конечном итоге вышли из употребления. Хотя были попытки разработать один «универсальный» язык программирования, который бы служил всем целям, все они не получили всеобщего признания в качестве выполняющих эту роль. Потребность в разнообразных языках программирования возникает из-за разнообразия контекстов, в которых используются языки:

  • Программы варьируются от крошечных скриптов, написанных отдельными любителями, до огромных систем, написанных сотнями программистов .
  • Программисты различаются по опыту - от новичков, которым важнее всего простота, до экспертов, которым удобна значительная сложность.
  • Программы должны сочетать скорость, размер и простоту в системах от микроконтроллеров до суперкомпьютеров .
  • Программы могут быть написаны один раз и не изменяться из поколения в поколение, или они могут подвергаться постоянным изменениям.
  • У программистов могут быть разные вкусы: они могут быть привыкли обсуждать проблемы и выражать их на определенном языке.

Одной из распространенных тенденций в разработке языков программирования было добавление дополнительных возможностей для решения проблем с использованием более высокого уровня абстракции . Самые ранние языки программирования были очень тесно связаны с аппаратным обеспечением компьютера. По мере развития новых языков программирования были добавлены функции, позволяющие программистам выражать идеи, более далекие от простого перевода в базовые аппаратные инструкции. Поскольку программисты менее привязаны к сложности компьютера, их программы могут выполнять больше вычислений с меньшими усилиями со стороны программиста. Это позволяет им писать больше функций в единицу времени.

Программирование на естественном языке было предложено как способ устранить необходимость в специализированном языке программирования. Однако эта цель остается далекой, и ее преимущества открыты для обсуждения. Эдсгер В. Дейкстра занял позицию, согласно которой использование формального языка необходимо для предотвращения введения бессмысленных конструкций, и отверг программирование на естественном языке как «глупое». Алан Перлис также отверг эту идею. В структурированном английском и SQL используются гибридные подходы .

Разработчики и пользователи языка должны создать ряд артефактов, которые управляют и позволяют практиковать программирование. Наиболее важными из этих артефактов являются спецификация и реализация языка .

Технические характеристики

Спецификация языка программирования - это артефакт, который пользователи языка и разработчики могут использовать, чтобы договориться о том, является ли часть исходного кода допустимой программой на этом языке, и если да, то каким должно быть ее поведение.

Спецификация языка программирования может принимать несколько форм, включая следующие:

Реализация

Реализация языка программирования дает возможность писать программы на этом языке , и их выполнение на одном или нескольких конфигураций аппаратного и программного обеспечения. В целом, существует два подхода к реализации языка программирования: компиляция и интерпретация . Как правило, можно реализовать язык, используя любой из этих методов.

Вывод компилятора может выполняться аппаратным обеспечением или программой, называемой интерпретатором. В некоторых реализациях, использующих подход интерпретатора, нет четкой границы между компиляцией и интерпретацией. Например, некоторые реализации BASIC компилируют, а затем выполняют исходный код построчно.

Программы, которые выполняются непосредственно на оборудовании, обычно работают намного быстрее, чем те, которые интерпретируются в программном обеспечении.

Одним из методов повышения производительности интерпретируемых программ является своевременная компиляция . Здесь виртуальная машина непосредственно перед выполнением транслирует блоки байт-кода, которые будут использоваться, в машинный код для прямого выполнения на оборудовании.

Собственные языки

Хотя большинство наиболее часто используемых языков программирования имеют полностью открытые спецификации и реализации, многие языки программирования существуют только как проприетарные языки программирования с реализацией, доступной только от одного поставщика, который может утверждать, что такой проприетарный язык является их интеллектуальной собственностью. Проприетарные языки программирования, как правило, являются предметно-ориентированными языками или внутренними языками сценариев для одного продукта; некоторые проприетарные языки используются только внутри поставщика, в то время как другие доступны для внешних пользователей.

Некоторые языки программирования существуют на границе между проприетарным и открытым; например, Oracle Corporation утверждает права собственности на некоторые аспекты языка программирования Java , и Microsoft «s C # язык программирования, который имеет открытые реализации большинства частей системы, также Common Language Runtime (CLR) в замкнутой среде.

Многие проприетарные языки широко используются, несмотря на их проприетарный характер; примеры включают MATLAB , VBScript и Wolfram Language . Некоторые языки могут перейти от закрытого к открытому; например, Erlang изначально был внутренним языком программирования Эрикссон.

Использовать

Были созданы тысячи различных языков программирования, в основном в области вычислений. Отдельные программные проекты обычно используют пять или более языков программирования.

Языки программирования отличаются от большинства других форм человеческого выражения тем, что они требуют большей степени точности и полноты. При использовании естественного языка для общения с другими людьми авторы и носители-люди могут быть двусмысленными и допускать небольшие ошибки, но при этом ожидать, что их намерения будут поняты. Однако, образно говоря, компьютеры «делают именно то, что им говорят», и не могут «понять», какой код намеревался написать программист. Комбинация определения языка, программы и входных данных программы должна полностью определять внешнее поведение, которое происходит при выполнении программы в пределах области управления этой программой. С другой стороны, идеи об алгоритме могут быть переданы людям без точности, необходимой для выполнения, с помощью псевдокода , который чередует естественный язык с кодом, написанным на языке программирования.

Язык программирования предоставляет структурированный механизм для определения частей данных и операций или преобразований, которые могут выполняться автоматически с этими данными. Программист использует абстракцию представление в языке для представления понятий , участвующих в вычислениях. Эти концепции представлены как набор простейших доступных элементов (называемых примитивами ). Программирование - это процесс, с помощью которого программисты комбинируют эти примитивы для составления новых программ или адаптации существующих к новому использованию или изменяющейся среде.

Программы для компьютера могут быть выполнены в периодическом процессе без вмешательства человека, или пользователь может вводить команды в интерактивном сеансе в качестве переводчика . В этом случае «команды» - это просто программы, выполнение которых связано друг с другом. Когда язык может запускать свои команды через интерпретатор (например, оболочку Unix или другой интерфейс командной строки ) без компиляции, он называется языком сценариев .

Измерение использования языка

Определить, какой язык программирования является наиболее широко используемым, сложно, поскольку определение использования зависит от контекста. Один язык может занимать большее количество часов программиста, другой имеет больше строк кода, а третий может потреблять больше всего процессорного времени. Некоторые языки очень популярны для определенных типов приложений. Например, COBOL по-прежнему широко используется в корпоративных центрах обработки данных, часто на больших мэйнфреймах ; Fortran в научных и инженерных приложениях; Ada в аэрокосмической, транспортной, военной промышленности, приложениях реального времени и встроенных приложениях; и C во встроенных приложениях и операционных системах. Другие языки регулярно используются для написания самых разных приложений.

Были предложены различные методы измерения популярности языка, каждый из которых имеет различную предвзятость по отношению к измеряемой величине:

  • подсчет количества объявлений о вакансиях, в которых упоминается язык
  • количество проданных книг, которые учат или описывают язык
  • оценки количества существующих строк кода, написанного на этом языке, что может недооценивать языки, которые не часто встречаются в общедоступных поисках
  • количество языковых ссылок (т. е. названия языка), найденных с помощью поисковой машины в Интернете.

Комбинируя и усредняя информацию с различных интернет-сайтов, stackify.com сообщил о десяти самых популярных языках программирования (в порядке убывания общей популярности): Java , C , C ++ , Python , C # , JavaScript , VB .NET , R , PHP и MATLAB .

Диалекты, вкусы и реализации

Диалект языка программирования или язык обмена данных является (относительно небольшое) изменения или расширения языка , который не изменяет свою внутреннюю природу. С такими языками, как Scheme и Forth , разработчики могут счесть стандарты недостаточными, неадекватными или незаконными, поэтому часто они отклоняются от стандарта, создавая новый диалект . В других случаях диалект создается для использования в предметно-ориентированном языке , часто в подмножестве. В мире Лиспа большинство языков, использующих базовый синтаксис S-выражений и семантику, подобную Лиспу, считаются диалектами Лиспа, хотя они сильно различаются, как, например, Racket и Clojure . Поскольку один язык обычно имеет несколько диалектов, неопытному программисту может быть довольно сложно найти нужную документацию. Язык программирования BASIC имеет множество диалектов .

Бурный рост диалектов Форта привел к появлению поговорки: «Если вы видели один Форт ... вы видели один Форт».

Таксономии

Для языков программирования нет всеобъемлющей схемы классификации. У данного языка программирования обычно нет единого языка-предка. Языки обычно возникают путем объединения элементов нескольких языков-предшественников с новыми идеями, циркулирующими в то время. Идеи, возникшие на одном языке, распространяются в семье родственных языков, а затем внезапно перепрыгивают через семейные разрывы и появляются в совершенно другой семье.

Задача усложняется еще и тем, что языки можно классифицировать по нескольким осям. Например, Java является как объектно-ориентированным языком (потому что он поощряет объектно-ориентированную организацию), так и параллельным языком (поскольку он содержит встроенные конструкции для параллельного выполнения нескольких потоков ). Python - это объектно-ориентированный язык сценариев .

В общих чертах языки программирования делятся на парадигмы программирования и классификацию по предполагаемой области использования, при этом языки программирования общего назначения отличаются от языков программирования, специфичных для предметной области . Традиционно языки программирования рассматривались как описывающие вычисления в терминах повелительных предложений, то есть выдачу команд. Их обычно называют императивными языками программирования . Большое количество исследований в области языков программирования было направлено на стирание различия между программой как набором инструкций и программой как утверждением о желаемом ответе, что является главной особенностью декларативного программирования . Более совершенные парадигмы включают процедурное программирование , объектно-ориентированное программирование , функциональное программирование и логическое программирование ; некоторые языки являются гибридами парадигм или мультипарадигматическими. Язык ассемблера не столько парадигма , как прямая модель лежащей в основе архитектуры машины. По назначению языки программирования могут считаться языками общего назначения, языками системного программирования, языками сценариев, предметно-ориентированными языками или параллельными / распределенными языками (или их комбинацией). Некоторые языки общего назначения были разработаны в основном с образовательными целями.

Язык программирования также можно классифицировать по факторам, не связанным с парадигмой программирования. Например, большинство языков программирования используют ключевые слова английского языка , а меньшинство - нет . Другие языки могут быть классифицированы как преднамеренно эзотерические или нет.

Смотрите также

использованная литература

дальнейшее чтение

внешние ссылки