Классификация языков программирования

Варианты классификации:

  • По парадигме (декларативные, императивные, структурированные и т.п.)
  • По системе типов (динамические, статические, сильно- и слаботипизированные, нетипизированные и т.п.)
  • По уровню абстракции (высокого, низкого уровня)
  • По модели исполнения (компилируемые, интерпретируемые)
  • По “поколению”

По системе типов

Наиболее категоричное – типизированные и нетипизированные.

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

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

  • по моменту проверки типов
  • по строгости этой проверки

По моменту проверки типов

Статически типизированные языки
типы всех выражений точно определены до выполнения программы, обычно проверяются при компиляции. Например, C++, C#, Java, Haskell, F#.
Динамически типизированные языки
производят проверку типов на этапе выполнения. Иначе говоря, типы связаны со значением при выполнении, а не с текстовым выражением. Не требуют указания типов выражений. Например, Lisp, Perl, Python, JavaScript и Ruby.

Языки со статической типизацией

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

требуют явного указания типов. К ним относятся, например, C, C++, C#, Java.

Типовыводящие языки

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

По строгости типизации

Слабо типизированные языки

неявно конвертируют один тип в другой, скажем, строки в числа и наоборот. Это может быть удобно в некоторых случаях, однако многие программные ошибки могут быть пропущены. Усложняется отладка. Например Perl, JavaScript, C.

Сильно типизированные языки

не позволяют неявную конверсию, и требуют явной. Дают сильные гарантии типобезопасности, но код может становиться крайне многословным. Например C++, Java, Haskell.

По уровню абстракции

Сильно зависит от современных представлений о “высоком уровне абстракции”

  • Языки низкого уровня – это машинный код и языки ассемблера
  • остальные – в некотором смысле высокого уровня
  • многие считают C и C++ языками низкого уровня
  • Java, Python, Ruby и т.п. общепринято считаются языками высокого уровня.

По модели исполнения

Компилируемые, транс-компилируемые или интерпретируемые.

Интерпретируемые
исполняются непосредственно, без этапа компиляции.
Напр. PHP, Perl, Bash, Python, JavaScript
Компилируемые
исходные коды компилируются, т.е. переводятся в исполнимую форму до выполнения.
Напр: С, С++, Algol, Fortran, Haskell;
В байт-код: Python, Java
Транс-компилируемые
транслируются в другой язык.
Напр. C++ (исторически, в C), Haskell (исторически, в С), Fortran (иногда, в С), Fay (в JavaScript)

Классификация по “поколению”

Поколение – несколько условная характеристика, которая в значительной мере связана с историей появления современных языков программирования.

Языки первого поколения (1GL)
машинные языки
Языки второго поколения (2GL)
языки ассемблера
Языки третьего поколения (3GL)
Более абстрактные, чем 2GL. Снимают заботу о непринципиальных деталях с плеч программиста.
Fortran, ALGOL и COBOL – первые 3GL
C, C++, Java, BASIC и Pascal – можно назвать 3GL
в общем случае подразумевает только структурную парадигму
Языки четвертого поколения (4GL)

Определение несколько расплывчато. Ещё более высокий уровень абстракции.

Узкая область применения
Напр., FoxPro, LabView G, SQL, Simulink
Есть мнение, что 4GL ⊂ DSL (domain specific language)
Языки пятого поколения

попытка разработать класс языков, которые “пишут программы сами”

Напр. Prolog, OPS5, Mercury
широкого практического применения не нашли

Парадигмы программирования

Теорема Бёма-Якопини

Любая вычислимая функция может быть представлена комбинацией трёх управляющих структур:

  • Последовательности
  • Ветвления
  • Итерации