Файл: Современные языки программирования (Краткая история языков программирования).pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 30.03.2023

Просмотров: 137

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

В 1969-1973 году появляется язык Си, оказавший существенное влияние на развитие индустрии программного обеспечения, и давший основу синтаксиса таких языков программирования, как C# и Java. Си тесно связан с операционной системой UNIX, для реализации которой он изначально разрабатывался. [3, 58][15]

В период конца 70х – начало 80х годов 20 века происходит окончательное формирование принципов объектно-ориентированного программирования (далее – ОПП). ОПП - методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса. Понятие класса стало важным шагом вперед в развитии программирования, существенно упростившим написание и отладку программного продукта. ООП идеологически произошел из структурного программирования, и сочетал лучшие его принципы с новыми концепциями: инкапсуляции (механизм языка, позволяющий ограничить доступ одних компонентов программы к другим; позволяет реализовать быструю и безопасную иерархию компонентов программ), наследования (способности объекта использовать методы производного класса, который не существует на момент создания базового), и полиморфизма (в широком смысле - способность функции обрабатывать данные разных типов; например, способности классов с одинаковой спецификацией могут иметь различную реализацию). [4, с. 43][16] Объектно-ориентированные языки программирования – как языки, изначально разрабатывавшиеся на парадигме ООП (Python, Java, Smalltalk, Ruby, Objective-C) , так и те, что в ходе своей эволюции приобрели поддержку объектно-ориентированного программирования, - являются на сегодняшний день наиболее востребованным классом языков программирования. [6, с. 340-341][17]

На современном этапе развития программирования становится популярной и другая парадигма – функциональное программирование (далее – ФП). ФП использует другой вид абстракции для вычислений: они разрабатывались с целью максимально близкой имитации математических функций. Основу ФП составляют функции, которые берут в качестве аргументов набор функций и возвращают другую. Каждый символ в ФП является неизменяемым, и как следствие, функции не имеют побочных действий. Язык, реализующий парадигму ФП в чистом ее виде, не использует ни переменные, ни операторы присваивания. Функция не может поменять значение вне своей области видимости, и тем самым повлиять на другие функции. Результат работы функции зависит только от переданных аргументов. Как следствие, языки функционального программирования имеют более легкий процесс отладки, программы можно тестировать параллельно. Модель вычислений без состояний определяет как основные преимущества, так и недостатки ФП. Р. Себеста отмечает, что ФП имеет более низкую эффективность выполнения программ по сравнению с программированием на императивном языке, но при этом, «более высокий уровень программирования, для которого требуется меньше усилий.» [4, c. 612] [18] Наиболее популярными языками, реализующими функциональное программирования, являются Haskell, Scala, Erlixir, Erlang, Elm.


Со времени создания первых ЭВМ было разработано несколько сотен языков программирования, в разной степени использовавшихся в последние полвека. [6, стр. 388][19] Многие языки переживают так называемую эволюцию - выход нескольких версий и, в ряде случаев, существенную переработку, не теряя своей популярности. Выводы о тенденциях развития языков можно сделать, обратившись к вопросу классификации языков программирования.

1.2 Способы классификации

Существует множество признаков, по которым проводят классификацию языков программирования. Большая их часть не основывается на технических свойствах, не является дихотомичной, а в некоторых случаях – подвержена субъективности при типизации. Кроме того, начиная с 80-х годов 20 века в развитии языков программирования действует тенденция к консолидации. Языки заимствуют и перерабатывают некоторые особенности друг друга, объединяют черты различных своих предшественников, при этом существует множество конфликтов между критериями разработки и оценки языка. [4, с. 45][20] Все это обусловливает факт отсутствия общепринятой строгой классификации языков программирования. Рассмотрим некоторые из способов и их несовершенства.

Выше уже упоминалась хронологическая классификация языков. Согласно этому критерию, языки подразделяют, как правило, на пять поколений. Первое поколение – языки, реализованные на аппаратном уровне. [4, с. 61][21] Второе поколение – это языки ассемблера. Третье поколение – это первые из высокоуровневых языков, условно независимые от аппаратного обеспечения. [6, с. 227][22] Четвертое поколение приходится на период с 70-х по 90-е годы 20 века, языки этого поколения ориентированы на специализированные области применения. Для них характерны операторы, позволяющие одной строкой реализовать функциональность, которую на языках третьего поколения потребовалось бы описывать многократно большим исходным кодом. Пятое поколение (встречаются, однако, классификации, ограничивающиеся четырьмя поколениями) объединяет языки и прикладные системы, позволяющие автоматически формировать результирующий текст на универсальных языках программирования

По уровню языка различают языки низкого и высокого уровня, отличие которых в близости семантики к машинному коду архитектуры процессора или к человеческому языку соответственно. Языки низкого уровня – наименее абстрактные и наиболее сложные для восприятия человеком – это языки первого и второго поколения. [6, c. 388][23] Языки третьего поколения преимущественно относят к высокому уровню, однако, к примеру, язык Си был при разработке позиционирован как высокоуровневый язык ассемблера и может быть обособленно классифицирован как язык среднего уровня. Языки четвертого поколения являются языками высокого уровня. Для языков пятого поколения иногда используется термин сверхвысокий уровень.


Различают языки императивные и декларативные. Императивные – традиционно управляемые командами; основной их концепцией является состояние машины. [3, c. 43][24] Они описывают то, как пользователь получит результат, тогда как языки более высокого уровня описывают то, что требуется в результате. Поэтому первые называют языками, ориентированными на машину, а вторые — языками, ориентированными на человека.

По способу реализации различают компилируемые, интерпретируемые и языки смешанной системы реализации. [4, c. 45-52][25] Примером языка чистой интерпретации может служить Лисп. Условность данной классификация заключается в том, что реализация не является присущим конкретному языку свойством, и можно говорить только о естественном для языка способе реализации, который определяется временем связывания программных элементов с их характеристиками. В частности, в языках со статической типизацией переменные и другие объекты программы связываются с типом данных на этапе компиляции, а в случае типизации динамической — на этапе выполнения, как правило — в произвольной точке программы. Некоторые свойства элементов языка, такие как значение арифметических операторов или управляющих ключевых слов, могут быть связаны уже на этапе определения языка. В других языках возможно их переназначение. Раннее связывание обычно означает большую эффективность программы, в то время как позднее — большую гибкость, ценой которого является меньшая скорость или усложнение соответствующего этапа. Для любого традиционно компилируемого языка (например, Паскаль) можно написать интерпретатор. Кроме того, большинство современных интерпретаторов не исполняют конструкции языка непосредственно, а компилируют их в некоторое высокоуровневое промежуточное представление. Большинство традиционно интерпретируемых или компилируемых языков могут реализовываться в смешанной системе. Некоторые языки, например, Java и C#, находятся между компилируемыми и интерпретируемыми: программа компилируется не в машинный язык, а в машинно-независимый код низкого уровня, байт-код. Далее байт-код выполняется виртуальной машиной. Для Java байт-код исполняется виртуальной машиной Java (Java Virtual Machine, JVM), для C# — Common Language Runtime. Подобный подход позволяет использовать плюсы как интерпретаторов, так и компиляторов. Примером языка, реализуемого смешанной системой, может служить Pearl, происходящий от интерпретируемых языков, но являющийся частично компилируемым, что позволяет обнаруживать ошибки до начала интерпретации. [4, c. 51][26]


По типу решаемых задач различают языки для решения математических (Фортран), экономических (Кобол) задач, языки для обучения (Бейсик, Паскаль), языки сетевого (Java) и системного (C, C++, C#) программирования. [4, 27-28][27] Очевидно, что данная классификация условна и большинство языков позволяет решать задачи широкого спектра. Отдельно следует упомянуть схожую классификацию языков программирования на языки фронтенд и бэкенд разработки.

По уровню риска человеческого фактора различают безопасные и небезопасные языки. Безопасным считается язык, где программы, которые могут быть приняты компилятором как правильно построенные, в динамике никогда не выйдут за рамки допустимого поведения. При этом если программа содержит ошибку, то она тем не менее не способна нарушить целостность данных и обрушиться. В опасных языках определенного вида ошибки, присущие конкретному языку, являются статистической нормой – например, ошибки неявного преобразования чисел в строки в языке Pearl [2, с. 83][28] , а также ошибки, связанные с несоответствием типов в языке Си [2, с. 66][29].

Различают языки для программирования в мелком и крупном масштабе. Различные языки программирования рассчитаны на разный исходный масштаб задачи и по-разному справляются с ростом сложности программных систем. Ключевым качеством языка, от которого зависит, как меняется трудоемкость разработки по мере наращивания системы, является абстракция. Высокая степень абстракции, допускаемая языком, значительно облегчает его использование. [4, с. 37][30]

Различают языки программирования с высоким и низким порогом вхождения и/или условной быстротой освоения. Данный фактор классификации упоминается большинством авторов при описании того или иного языка, но является предметом широких дискуссий, так как зависит не только от субъективных предпочтений, но также и от опыта конкретного программиста, опыта работы с другими языками конкретной языковой семьи (здесь уместно говорить об аналогии с изучением естественных языков), а также уровня, до которого указанное «вхождение» осуществляется. Обычно классифицируются как языки с низким порогом вхождения Си, Бейсик, Паскаль, Python, квази-языки – из-за более понятной семантики и относительно быстрого срока освоения основ языка. [10][31] К более «сложным» относят Java, Javascript, Си++, PHP. К языкам с высоким порогом вхождения относят сравнительно молодые мультипарадигмальные языки (Scala, Go) или, напротив, низкоуровневые языки – ассемблера или машинного кода.


По типу парадигмы – основной вычислительной модели, различают 4 типа языков: императивные (процедурные), функциональные (аппликативные), логические (основанные на системе правил) и объектно-ориентированные. При этом, как отмечают Пратт и Зелковиц [3, c. 45][32], объектно-ориентированная модель «является попыткой объединить лучшие свойства других моделей», такие как эффективность императивной модели (за счет возможности строить конкретные объекты данных), гибкость и надежность функциональной модели (за счет построения классов функций, которые используют ограниченный набор объектов данных). Хотя процедурные языки представляли собой первый широко используемый класс языков (Фортран, Алгол) и наиболее широко распространены и на сегодняшний день (Си, Паскаль, Ada), но концепция объектно-ориентированного программирования постепенно приобретает все большее значение и, с распространением мультипарадигмальности, большинство современных языков поддерживают реализацию ООП в том или ином виде. Таким образом, классификация языков по типу парадигмы может дополняться классификацией мультипарадигмальных языков – по числу поддерживаемых ими парадигм.

Таким образом, подавляющее большинство видов классификации является открытым для обсуждений профессионального сообщества. Однако сама возможность выделять новые признаки классификаций способствует процессу консолидации, который порождает мультипарадигмальные (иногда также встречается наименование «гибридные») языки, с возрастающей универсальностью применения. Это приводит к еще одной условной классификации языков – на более и менее популярные на сегодняшний день.

1.3 Популярные языки программирования

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

- число строк написанного кода;

- число упоминаний имени языка в поисковых запросах;

- число вакансий, требующих знания данного языка;

- число проектов на GitHub, использующих данный язык;

- число курсов программирования и тренировочных площадок, открытых для изучения языка;

- число книг и других учебных материалов (напр., видео на YouTube), посвященных языку).

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