Как сравнить языки

За карьеру программисту приходится изучать большое количество языков, зачем их столько?

Ответить на такой в общем то наивный вопрос подчас затрудняются даже опытные специалисты. Ведь действительно, языков более — менее популярных насчитывается около пяти тысяч. И чем все они отличаются? Статья задумана автором как ответ

Какая разница на сколько один язык отличается от другого: нужно и выучил. Так — да не так. Программируя на разных языках человек совершает очевидно и разные ошибки. Но зачем нужна одна и та же программа, написанная множество раз? Есть области, где ошибка недопустима. При создании ПО для атомных электростанций, химического производстве, военных роботов, медицины малейший сбой может привести к необратимым последствиям.

Поэтому поступают так:

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

Как же сравнить языки?

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

Парадигмы для сравнения

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

Способ выполнения программы

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

Интерпретаторы.

Интерпретацией называется построчный анализ, обработка и выполнение исходного кода программы или запроса. Примеры Lua[4], GNU Lisp[5] Примечание, GNU Lisp является примером мультипарадигменного по методу исполнения языка, поскольку поддерживает интерпретацию и трансляцию в язык Си.

Компиляторы

Транслируют программный код в программу, выполняемую непосредственно операционной системой. Пример С++[5], Delphi[6]. Языки подобного рода хорошо известны большинству программистов

Языки с виртуальной машиной

Транслируются в бинарный код(так называемый байт-код) который выполняется специальной программой называемой «виртуальная машина». Примеры Java[7], C#[8]. Таким образом преимущества компилируемого языка совмещаются с кроссплатформенностью, поскольку виртуальные машины существуют для всех популярных операционных систем.

Языки транслируемые в другие

Иногда дизайн базового языка программирования не устраивает разработчика ввиду различных причин. Например, JavaScript. Это же ужас! Но как перейти, если интерпретаторы других языков вытеснены из большинства браузеров? Есть выход:сделать более удобный язык и транслировать его в JavaScript, так TypeScript появился. Ещё пример GNU Lisp, он транслируется в язык Си.

Типы ООП

Языки подразделяются на три основных типа: без ООП совсем(пример, язык Си), без ООП в классическом понимании, но с возможностью его эмуляции (Lua, JavaScript[10] и классические языки ООП. Пример: Java[11], C++[5], Scala[12]

Разница между языками без ООП и с эмуляцией ООП является в значительной степени условной, поэтому разница между ними определяется практикой применения.

Кроме того, есть языки с поддержкой наследования интерфейсов(Java) и множественными предками(С++, Python), а также собственные типы наследования(некоторые библиотеки поддержки ООП в LISP)

Типизация

Как известно тип данных это характеристика набора данных, которая определяет диапазон его возможных значений, список допустимых операций, а также способ хранения набора данных[13]. Типизация бывает статической(когда тип переменной или метода объявляется при объявлении класса) и динамической(тип фиксируется при инициализации). Иными словами, статическая компиляция означает, что проверка на совместимость типов выполняется на этапе компиляции/проверки ошибок, динамическая — на этапе выполнения.

Также система типов может быть слабой и сильной. Система типов называется «сильной», если она исключает возможность возникновения ошибки согласования типов времени выполнения, иными словами, обеспечивающей типобезопасность (отсутствие неконтролируемых ошибок приведения типов времени выполнения) на уровне языках[14]. Соответственно язык может поддерживать

  • Статическая(Java[11], C++[5], C#[15]), или динамическая(Python[16] PHP[17]), типизация.
  • Сильная(Java[11], Python[16]) или слабая(С[18], JavaScript[10]) типизация

Функциональное программирование

Парадигма программирования[19], в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании).

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

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

  • Наличие функционального типа: Java 8 и старше[20], TypeScript [21];
  • Наличие свёрток над данными Scala[12], Common Lisp.

Многопоточное программирование

По многопоточности языки можно разделить на четыре типа:

  • Не поддерживающие многопоточность(однако с возможностью эмуляции многопоточности, например по событиям таймера) ActionScript3; [21]
  • Поддерживающие базовые возможности многопоточности:Pascal, Java 6;
  • Развитые библиотеки работы с многопоточностью (Java 8 и старше);
  • Языки поддерживающие shared memory (Clojure). [22]

Макросы

Делим языки на поддерживающие и не поддерживающие макросы

Языки логического программирования

То есть, языки поддерживающие либо не поддерживающие процедуры логического вывода[23]

Как будем сравнивать?

Мы введем анкету и попросим программистов приписать свойству языка вес — получится бинарный вектор признаков отсортированный по средней важности, или бинарное число. Разница между языками — модуль разницы векторов.

❗️ А вот и она — проголосуйте, пожалуйста

Что почитать

  1. Comparative Studies of 10 Programming Languages within 10 Diverse Criteria. Jiang Li. Mingzhi Liu. Yuanwei Lai. Concordia University.
  2. On the problem of computer language classiаcation. I. S. Anureev, E. V. Bodin, L. V. Gorodnyaya, A. G. Marchuk, F. A. Murzin, N. V. Shilov
  3. Ranking programming languages by energy efficiency. Rui Pereiraa, Marco Coutoc, FranciscoRibeiroc, Rui Ruac, Jácome Cunhac, João PauloFernandesd, João Saraivac
  4. www.lua.org/about.html
  5. Бьёрн Страуструп. Язык программирования C++ = The C++ Programming Language
  6. Курс практического программирования в Delphi. Е. Санников
  7. A Formal Introduction to the Compilation of Java, Stephan Diehl, «Software — Practice and Experience», Vol. 28(3), pages 297–327, March 1998.
  8. Build Your Own .NET Language and Compiler Softcover reprint of the original 1st ed. Edition
  9. www.eclipse.org/xtend
  10. javascript. Шаблоны
  11. Язык программирования Java Джеймс Гослинг, Кен Арнольд
  12. Scala. Профессиональное программирование. 5-е изд Мартин Одерски
  13. Пирс. Типы в языках программирования
  14. Typeful Programming Luca Cardelli Digital Equipment Corporation, Systems Research Center. 130 Lytton Avenue, Palo Alto, CA 94301
  15. CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#. 4-е изд. Дж. Рихтер
  16. Python tutorial Guido Van Rossum
  17. PHP In Action: Objects, Design, Agility. Daginn Reiersol, Chris Shiflett, and Marcus Baker
  18. ЯЗЫК С Б.В. Керниган, Д.М. Ритчи.
  19. А. Филд П. Харрисон. Функциональное программирование
  20. Современный язык Java. Лямбда-выражения, потоки и функциональное программирование Рауль-Габриэль Урма, Алан Майкрофт, Марио Фуско
  21. ActionScript 3.0 Cookbook by Joey Lott, Darron Schall, Keith Peters Released October 2006
  22. Seven Concurrency Models in Seven Weeks: When Threads Unravel (The Pragmatic Programmers) 1st Edition by Paul Butcher
  23. Алгоритмы искусственного интеллекта на языке PROLOG Третье издание ИВАН БРАТКО
👍ПодобаєтьсяСподобалось2
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

забыл упомянуть микроконтроллеры и телефоны. там могут быть кастрированные версии языков и вобще своя атмосфера

А в чому суть, яка мета такого порівняння?

Якщо для виконання якогось проекту — будуть свої проектнозалежні метрики.

Надійність, швидкість написання, просто підтримки і т.д. — інші метрики.

Наявність чи відсутність певних інструментів у мові, таких як строга типізація — це може бути як плючм так і мінусом, в залежності з якого боку ми дивимось.
В С++, незважаючи на те, що мова строго типізована, є «auto», що дозволяє створювати для користувача ніби-то динамічну типізацію( насправді компілятор визначає оптимальний тип на етапі компіляції ).

Подібних прикладів досить багато.

В комитете C++ вообще юмористы какие-то сидят. Напридумывали кучу правил и ограничений, и тут же пути для их обхода. Есть ещё std::any для обхода статической типизации.

Как сравнить языки с точки зрения кого-чего?
Потому что можно придумать классный ЯП — только программисты не захотят его учить :)

На сегодняшнем этапе программисты часто уже сами не решают что им учить а что нет, в коммерческом смысле. За что платят то и будеш учить. Иногда им просто на откуп это отдают. Как правило это способ технологической конкуренции и решение о технологи принимают аж на уровне CTO и CEO. Учить надо не одного человека а целые команды, это решение которое является определяющими для IT бизнеса. Если кто-то начнет проект скажем на Jancy или Pixilang — как им быстро найти замену или добавить в людей в команду и т.д. ? Возможно лет 15 тому у рядовых программистов было много большая свобода выбора в этом отношении, но и то уже все было весьма бюрократично. IT бизнес существовал давно именно как отдельный тип бизнеса и довольно давно.

Провокационная тема. Что значит сравнить языки ? Какой язык программирования лучше подходит для решения конкретной задачи автоматизации ? Тогда нужен список критериев за — против, c одной стороны и с другой между языками программирования, у кого в числах выйдет лучше тот и победил. Бенчмарки это часто соревнования не языков а компиляторов с них и программистов написавших программу. Ну а в целом — коровий больше и вкуснее свинного.

перед знаком вопроса не надо ставить пробел

перед знаком вопроса не надо ставить пробел

Перше слово в реченні треба починати з великої букви. Речення завжди закінчується крапкою.

Как правило или парадигмой, поддерживаемыми синтаксисом парадигмами из коробки, или просто синтаксисом. Скажем python — типичный императивный интерпретируемый язык программирования, с типичным же для интерпретируемых языков автоматическим управлением памятью. Как и большинство других подобных языков поддерживает все парадигмы кроме логической, впрочем и логическую тоже можно реализовать используя имеющиеся механизмы. Но и Java и C# и скажем PHP или Ruby хоть и обладают другим синтаксисом, тем не менее дают все тоже самое. В коммерческом смысле имеет значение вообще другое — какие задачи автоматизации (бизнес домен) обычно решаются специалистами в направлении с помощью того или иного языка программирования. Скажем когда ищут Java программиста, чаше всего имеется в виду специалист по разработке корпоративных приложений для поддержки бизнеса, хотя технически на Java можно писать любое прикладное программное обеспечение, скажем компилятор компиляторов — ANTLR. Аналогично Python — специалисты по электронному маркетингу, в частности средствами обработки больших массивов данных машинного обучения и искусственных нейронных сетей. C++ — сразу много направлений, разработка системного и управляющего ПО для встраиваемые устройств, разработка 3D графики и видео-игр, разработка высоко-нагруженных сервисов массового обслуживания, разработка прикладного desktop ПО и т.д. JavaScript/TypeScript — разработка web пользовательского интерфейса и т.д. и т.п. Сам по себе язык программирования по существу вторичен — но определяет экосистему.

Интерпретатора Lua — не существует, Lua в основном транслируется в байт-код. Файлы с байт-кодом можно использовать вместо скриптов, чтобы сократить время на прекомпиляцию. Ещё есть jit-компилятор Lua. Что касается интерпретаторов, то для современных популярных языков такой подход вообще не используется. Что касается ООП, то в Lua не эмуляция ООП, а это называется прототипное ООП.

Але дуже часто LUA використовують як вбудовану в інші платформи мову і там VM.
Я наприклад зараз юзаю на проекті github.com/yuin/gopher-lua

Я тоже использую этот проект для скриптования в Go-программах.

JavaScript — чистейщий интерпретатор :) Вообще нигде не сказано как интерпретатор должен интерпретировать, переводить исходный код в машинный строка за строкой по ходу выполнения как Basic, или все сразу в машинный с оптимизацией при запуске программы на выполнение как скажем V8 или в фоновом потоке участками которые будут выполнены в ближайшее время в just in time и т.д. Lua кстати тоже интерпретируемый :) Подход Oberon, Java,C#.NET и Swift/LLVM вместе с C/C++ под .NET и LLVM — гибридный. По сути виртуальная машина делает линковку, предварительно скомпилированного исходного кода — что естественно в разы быстрее при выполнении но дольше в разработке т.к. программист должен тратить время на компиляцию с оптимизациями. Но преобразование промежуточного представления в конечный машинный код целевой платформы делается клиентской машиной.

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

«Классическое понимание» это очень спорный вопрос что считать классикой. Никлаус Вирт с аспирантами, выпустил Oberon в 1987 году, чем не классика? По тому алгоритму который вы описываете как я знаю можно сделать только интерпретатор с функционального языка типа LISP, или вообще ассемблера. И даже интерпретатор с BASIC чуть более старших версий уже несколько сложнее устроен, потому что не всякий язык программирования можно так в тупую интерпретировать, например из за наличия в нем операторов цикла и переходов. Нужно делать предварительный просмотр на какую-то глубину. Про оптимизацию так и вообще можно забыть при таком подходе. При этом BASIC считается классическим интерпретируемый языком программирования.

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

Інтерпритатори вмерли разом із апаратною кнопкою дебагу :-)

без ООП совсем(пример, язык Си)

Це не дуже вдалий приклад, бо деякі мажорні продукти типу ядра Linux і GTK написані на С в стилі ООП. Так, інкапсуляція розбивкою на одиниці трансляції, наслідування структур з вказівниками на функції і поліморфізм через касти void* це не дуже зручно, зате слугує непоганим бар’єром, щоб ООП не тягнули куди не слід.

Ну ООП це методологія, а значить її можна використати взагалі де завгодно. Питання тільки нащо.
Тому так — підтримка ООП у тій чи іншій мові це завжди предмет дуже палких дискусій

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

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

Це стаття для учнів старшого шкільного віку та непрофільних ПТУ? :)

А що, інженери на галерах теж не в курсі, що абсолютна більшість інтерпретаторів давно не виконують код построчно? Навіть ті інтерпретатори, що студенти пишуть так не працюють — там в найгіршому випадку будe парсінг в AST + tree walking інтерпретатор (що все одно дуже далеко від построчного виконання), а більшість «промислових» інтерпретованих мов транслюють в якийсь байткод який вже потім віртуальна машина построчно виконує (це ще не враховуючи JIT).

Виділення «трансляції в іншу мову» в цілий окремий тип мов — це теж щось дуже архаїчне. Сучасні компілятори модульні, з якої мови в яку компілювати — це тільки питання фронтенду та бекенду. І з точки зору архітектури процесу немає значення в що конкретно. Наприклад, один і той самий компілятор може компілювати як OCaml так і ReasonML, причому як в бінарник, так і в проміжний байткод в якості таргета. Чи той же LLVM згадати... Тобто в що воно там спочатку компілюється — це взагалі ніяк не характеризує саму мову програмування, це неважливе ділення.

А от про практично важливу відмінність — наявність чи відсутність GC в рантаймі, в тебе взагалі ані слова в критеріях оцінки (хоча це напряму впливає на (не)можливість застосування мови в деяких класах задач)

там в найгіршому випадку будe парсінг в AST + tree walking інтерпретатор (що все одно дуже далеко від построчного виконання)

А вот не всегда

наявність чи відсутність GC в рантаймі,

. спасибо, добавлю

В D GC можно как включить так и выключить опциями компилятора. Как D классифицировать ?

Как поддерживает опции: компилятор и байт-код транслятор

dlang.org/spec/garbage.html

D also provides the mechanisms to write code where the garbage collector is not involved. More information is provided below.

D компилирует сразу в машинный код как и Go Lang, но управление памятью гибридное, можно в ручную, можно с применением стандартного Mark-Sweep GC — а можно написать и подсунуть системе собственный алгоритм сборки мусора. В отличии от С++ билилиотек сборки мусора типа Bochem hboehm.info/gc все будет встроено прямо в язык. Хотя авторы активно это хотят выпилить из языка и сделать аналог Rust, управление временем жизни объектов в памяти как отдельный процесс в компиляции.

Нещодавно на співбесіді я дізнався, що випускники зі старших курсів поважних університетів не розуміють концепцію типу данних загалом. При чому не погані випускники, вміють зубарити, базової писати код та знають про принцип підстановки типів Барбари Лісков, що правда хто така сама Барбара — теж не знають.

Це стаття для учнів старшого шкільного віку та непрофільних ПТУ? :)

Це стаття __від__ учня старшого шкільного віку та непрофільних ПТУ (вофки кожаєва)

а также собственные типы наследования

Саме прикольне наслідування що бачив у житті це через метатаблиці у Lua

Підписатись на коментарі