Добавлен: 26.05.2023
Просмотров: 64
Скачиваний: 3
СОДЕРЖАНИЕ
1 Основные этапы развития языков программирования
2 Классификация языков программирования
2.1 Машинно-ориентированные языки
2.1.2 Языки Символического Кодирования
2.2.1 Проблемно – ориентированные языки
3 Современные языки и системы программирования
Макрос одинаково может работать, как с программами, так и с данными.
2.2 Машинно-независимые языки
Машинно-независимые языки – это средство описания алгоритмов решения задач и информации, подлежащей обработке [8,10,12]. Они удобны в использовании для широкого круга пользователей и не требуют от них знания особенностей организации функционирования ЭВМ и ВС.
Подобные языки получили название высокоуровневых языков программирования. Программы, составляемые на таких языках, представляют собой последовательности операторов, структурированные согласно правилам рассматривания языка(задачи, сегменты, блоки и т.д.). Операторы языка описывают действия, которые должна выполнять система после трансляции программы на МЯ.
Т.о., командные последовательности (процедуры, подпрограммы), часто используемые в машинных программах, представлены в высокоуровневых языках отдельными операторами. Программист получил возможность не расписывать в деталях вычислительный процесс на уровне машинных команд, а сосредоточиться на основных особенностях алгоритма.
2.2.1 Проблемно – ориентированные языки
С расширением областей применения вычислительной техники возникла необходимость формализовать представление постановки и решение новых классов задач. Необходимо было создать такие языки программирования, которые, используя в данной области обозначения и терминологию, позволили бы описывать требуемые алгоритмы решения для поставленных задач, ими стали проблемно – ориентированные языки. Эти языки, языки ориентированные на решение определенных проблем, должны обеспечить программиста средствами, позволяющими коротко и четко формулировать задачу и получать результаты в требуемой форме.
Проблемных языков очень много, например:
- Фортран, Алгол – языки, созданные для решения математических задач;
- Simula, Слэнг - для моделирования;
- Лисп, Снобол – для работы со списочными структурами.
2.2.2 Универсальные языки
Универсальные языки были созданы для широкого круга задач: коммерческих, научных, моделирования и т.д. Первый универсальный язык был разработан фирмой IBM, ставший в последовательности языков Пл/1. Второй по мощности универсальный язык называется Алгол-68. Он позволяет работать с символами, разрядами, числами с фиксированной и плавающей запятой. Пл/1 имеет развитую систему операторов для управления форматами, для работы с полями переменной длины, с данными организованными в сложные структуры, и для эффективного использования каналов связи. Язык учитывает включенные во многие машины возможности прерывания и имеет соответствующие операторы. Предусмотрена возможность параллельного выполнение участков программ.
Программы в Пл/1 компилируются с помощью автоматических процедур. Язык использует многие свойства Фортрана, Алгола, Кобола. Однако он допускает не только динамическое, но и управляемое и статистическое распределения памяти.
2.2.3 Диалоговые языки
Появление новых технических возможностей поставило задачу перед системными программистами – создать программные средства, обеспечивающие оперативное взаимодействие человека с ЭВМ их назвали диалоговыми языками [10,11].
Эти работы велись в двух направлениях. Создавались специальные управляющие языки для обеспечения оперативного воздействия на прохождение задач, которые составлялись на любых раннее неразработанных (не диалоговых) языках. Разрабатывались также языки, которые кроме целей управления обеспечивали бы описание алгоритмов решения задач.
Необходимость обеспечения оперативного взаимодействия с пользователем потребовала сохранения в памяти ЭВМ копии исходной программы даже после получения объектной программы в машинных кодах. При внесении изменений в программу с использованием диалогового языка система программирования с помощью специальных таблиц устанавливает взаимосвязь структур исходной и объектной программ. Это позволяет осуществить требуемые редакционные изменения в объектной программе.
Одним из примеров диалоговых языков является Бейсик.
Бейсик использует обозначения подобные обычным математическим выражениям. Многие операторы являются упрощенными вариантами операторов языка Фортран. Поэтому этот язык позволяет решать достаточно широкий круг задач.
2.2.4 Непроцедурные языки
Непроцедурные языки составляют группу языков, описывающих организацию данных, обрабатываемых по фиксированным алгоритмам (табличные языки и генераторы отчетов), и языков связи с операционными системами.
Позволяя четко описывать как задачу, так и необходимые для её решения действия, таблицы решений дают возможность в наглядной форме определить, какие условия должны быть выполнены прежде чем переходить к какому-либо действию. Одна таблица решений, описывающая некоторую ситуацию, содержит все возможные блок-схемы реализаций алгоритмов решения.
Табличные методы легко осваиваются специалистами любых профессий.
Программы, составленные на табличном языке, удобно описывают сложные ситуации, возникающие при системном анализе.
3 Современные языки и системы программирования
3.1 Необходимость новых языков программирования
Начиная с 2000-х годов архитектура программирования начала меняться. Все больше вычислительных машин начали поставляться с несколькими процессорами, и даже отдельные процессоры имели более одного ядра. Этот сдвиг в характере вычислительного оборудования вызвал необходимость в языках программирования, которые в полной мере воспользовались новой архитектурой процессора. Языки должны были иметь возможность выполнять процессы одновременно и/или параллельно, чтобы максимизировать потенциал новых многоядерных процессоров. Параллелизм уже не был задумкой, его нужно было встроить в сам язык.
В последние годы также возрождался интерес к функциональному программированию, парадигме, которая пытается максимально устранить побочные эффекты. По сути, появление побочных эффектов оказалось проклятием в жизни современного программиста. Как правило, процесс отладки кода (один вид деятельности, который каждый программист боится) намного сложнее. В параллельной среде безопасность и неизменность данных становятся очень важными для разработчиков. Повреждения данных и / или расы должны быть предотвращены как можно больше.
И последнее, но не менее важное: современные машины продолжают расти очень мощно. Хотя в прошлом большое внимание уделялось скорости работы программ, этот фокус в последнее время угас. Вместо этого большое внимание переключилось на производительность программистов. В результате он платит за язык программирования за аккуратный и элегантный синтаксис, который легко писать и читать. Новый разработчик должен иметь возможность быстро подбирать его и работать с языком в кратчайшие сроки. Нужно иметь возможность играть с языком с самого начала с помощью интерактивного цикла, обычно известного как REPL (Read-Eval-Print Loop), без необходимости проходить через утомительные процессы настройки и компиляции.
Чтобы оставаться актуальным в новом ландшафте программирования, были предприняты большие усилия для обновления старых языков, таких как Java и C ++, в соответствии с текущим положением дел. В Java, например, в выпуске Java 8 были добавлены Lambda Expressions и API Streams , а Java 9 теперь поставляется с REPL. Многопоточность библиотеки также были включены в языки, чтобы повысить их возможности параллелизма. Основным недостатком этих «старых» языков является то, что они никогда не строились с нуля для решения возникающих проблем в современном мире программирования. Попытка модифицировать новые функции на языках также не оказалась элегантным решением. Это не оставляет нам иного выбора, кроме как охватить новые языки программирования, которые были разработаны с нуля, чтобы решить некоторые сложные проблемы в современной разработке программного обеспечения.
Из-за описанных выше факторов (и многих других, не упомянутых в этой статье) было изобретено несколько языков программирования, чтобы попытаться решить некоторые (если не все) из этих проблем. Я называю эти языки « современными », потому что все они были выпущены в течение этого столетия. Как вы скоро поймете, большинство этих новых языков имеют много общего. Синтаксис некоторых из них очень похож.
Некоторые из общих функций, которыми пользуются большинство языков:
- переменные предпочитают быть неизменяемыми по умолчанию;
- тип вывода;
- большинство из них подчеркивают безопасность типов;
- большинство из них имеют конечные типы функция возврата;
- некоторые из них предлагают более простые способы создания нескольких процессов (или потоков), которые могут выполняться одновременно;
- некоторые из них предлагают более простые способы межпроцессного взаимодействия через каналы (или аналогичные примитивы);
- большинство из них подчеркивают функциональный стиль программирования (например, сопоставление образцов и ленивая оценка);
- большинство из них предлагают REPL;
- большинство из них являются статически типизированными;
- большинство из них имеют чистый и элегантный синтаксис, без лишних помех и многословия;
Ниже приведены, пожалуй, самые «видимые» современные языки программирования:
- Scala
- Golang (Go)
- Rust
- Kotlin
- Swift
Далее приводится обзор некоторых основных особенностей каждого языка.
3.1.1 Scala
Это язык, который дебютировал в первом десятилетии этого столетия и, возможно, является одним из «самых старых» современных языков программирования. Это продукт академических кругов, разработанный Мартином Одерским во время работы в EPFL в Швейцарии. Впервые выпущенный в 2004 году, Scala сочетает в себе объектно-ориентированные и функциональные парадигмы программирования. Приложения, написанные на Scala, работают поверх JVM, поэтому они легко переносятся на несколько платформ.
Объявление простой функции в Scala выглядит следующим образом:
def factorial(x: Int): Int = {
// The body of the function goes here...
}
Функция в Scala объявляется с использованием def ключевого слова (аналогичного Python и Ruby). За этим следует имя функции, в данном случае факториал , а затем список параметров в паре круглых скобок. Заметим , что параметр, в данном случае х , следует двоеточие ( : ) , а затем его тип данных ( Int для целого числа). Если в списке имеется более одного параметра, они должны быть разделены запятой. После закрывающей скобки списка параметров функции у нас есть еще один двоеточие и Int после него. Это возвращаемый тип возвращаемой функции (более корректно называемый типом результата в Scala). Следуя типу результата функции, это знак равенства ( =) и пару фигурных скобок, которые содержат тело функции. Знак равенства может показаться немного странным для тех, кто еще не знаком с Scala, но он имеет большой смысл с математической точки зрения. Содержимое в фигурных скобках можно рассматривать как математическое выражение, которое возвращает (или дает) результат в зависимости от определенного набора входных значений. Затем результат будет привязан к тому, что находится слева от знака равенства. Другими словами, когда вызывается факторная функция, она будет «возвращать» любой результат выражения внутри фигурных фигурных скобок.
Переменные в Scala объявляются с использованием либо ключевых слов ( val или var аналогичных JavaScript). Переменные, объявленные с использованием ключевого слова val , неизменяемы и, следовательно, не переустанавливаются (это предпочтительный вариант в Scala). С другой стороны, переменные, объявленные с использованием ключевого слова var, могут быть переназначены. Если переменной присваивается начальное значение, то ее тип не обязательно должен быть объявлен явно, интерпретатор может легко «вывести» его тип из начального значения. Например:
val x = 20
В этом случае тип « x » будет считаться целым числом ( Int). Если переменная не имеет начального значения, ее тип должен быть объявлен явно, например:
var x: Int
Важно отметить, что Scala требует инициализации переменной, независимо от того, намерены ли вы ее изменять или нет. Таким образом, для случая с использованием var выше, как объявление, так и инициализация переменной могут выполняться одновременно, например:
var x: Int = 20
Главный недостаток Scala - это его крутая кривая обучения.
3.1.2 Golang (Go)
Это язык, который был создан Google для собственного внутреннего использования (Google занимается высокораспределенными системами). Go особенно интересен, потому что один из его дизайнеров ( Кен Томпсон ) - фольклорный герой в области компьютерных наук. Он является создателем почтенной операционной системы UNIX , которую он разработал в начале 1970-х годов, работая в Bell Labs. Go был объявлен в 2009 году и с тех пор был выпущен как проект с открытым исходным кодом . Дизайнеры языка указали, что одной из их мотивов было их общее разочарование со сложностью, присущей C ++.
Go часто рекламируется как « C для 21-го века ». Это скомпилированный язык (с гораздо более быстрыми временами компиляции по сравнению с C / C ++) и имеет автоматическое управление памятью с помощью сборщика мусора .
Одной из сильных сторон Go является то, как она обрабатывает параллелизм с использованием goroutines и каналов .
Простая декларация функции в Go выглядит следующим образом:
func factorial(x int) int {
// The body of the function goes here....
}
Функция в Go объявляется с использованием func ключевого слова. За этим следует имя функции и список параметров в паре круглых скобок. В этом случае факториальная функция принимает только один аргумент, целое число х . Функция также возвращает «целое число», как показано int ключевым словом после закрывающей круглой скобки списка аргументов. Тело функции заключено в пару фигурных скобок. Подобно Scala, возвращаемый тип функции появляется после имени функции ( trailing return type ), а не раньше, как в случае с C или Java.