Tagged: Scala

Немного жизненного сравнения языков программирования

Есть много параметров по которым можно сравнивать языки программирования. Именно как языки, а не платформы. Популярность, инструменты разработки, область применения, позиция на рынке — это важно, но интересно именно посмотреть на языки сами по себе.
Причём пофигу на их парадигмы: и на Си можно писать в ООП стиле (GTK+ например) и на Java можно делать монады.
А как они именно в жизни?

Program languages on clock
Если вам хочется узнать какой язык популярнее то крайне советую вам почитать статью В поисках самого востребованного языка программирования откуда я нагло стырил КДПВ.

Я же хочу обратить ваше внимание на такие почти субъективные параметры:

1. Набор базовых аксиом.
Есть языки которые похожи на китайский — куча иероглифов. А есть такие как английский, где всего 26 букв, зато из них можно комбинировать слова а из слов предложения.
Очевидно что чем меньше таких вот базовых символов тем проще начать обучение. Но получается больше текста, да.
С другой стороны доводить набор букв до 1 и 0 тоже бессмысленно. Тут нужно подбирать компромис. В среднем во всех языках около 15ти операторов и до десяти базовых типов.
Аксиоматичную мощность можно посчитать и вывести коэффициент. Я даже нашёл какое-то сравнение мощности языков столетней давности.
Это вполне серъёзная и слегка научная задача годная для диссертации. Тут даже и графики красивые в маткаде можно нарисовать и из Википедии накопипастить заумных терминов. По крайней мере всерьёз годик разбираться.
Но вместо этого все пишут диссеры про какую то фигню, в лучшем случае о рефакторинге или RESTе. И кстати тоже не особо мудрённое дело для диссера: метод экстрактнуть или HTTP запрос отправить. Ловите намёк 😉

2. Читабельность.
Большую часть времени программисты читают код а не пишут.
Что такое читабельность начинаешь понимать когда сравниваешь код на питоне и на перле.
Тут такая закономерность: чем высокоуровневей язык программирования, тем лучше читаемость. SQL вообще читается как обычный текст.

3. Синтаксический сахар
Для часто повторяющихся примитивных вещей. Например, в яве строки — это объекты, и по хорошему нужно их конкатенировать вызовом метода. Но чтобы облегчить людям жизнь специально добавили синтаксический сахар когда оператор + выполняет конкатенацию строк.
Но плюс работает только для строк в виде исключения: всем остальным классам переопределять операторы нельзя, чтобы не было удивления в коде.
А вот в C++, C#, Groovy и многих других языках можно делать переопределение операторов и в результате потом часто удивляешься что это за фигня такая в коде: users << new User() пока не узнаёшь что добрые молодцы добавили сахару для добавления в список.
Вообщем, тут опять таки как с языками — если в английском жёсткая грамматика и порядок слов, то в русском пиши как хочешь и синтезируй слова.
В результате иностранцы не могут понять русский.

4. Возможность выстрелить в ногу.
Лучше всего стрелять в ногу на Си: тут ты выхватываешь настоящий Segmentation fault а не унылый NPE. Делишь 1/3 и получаешь 0. Пишешь if (x = 3) и долго удивляешься почему код не работает. И через переполненный буфер хакеры тебе валят сервак.
А ещё в Си бывают приколы когда из-за оптимизирующей опции компилятора программа перестаёт работать вообще.

5. Магия.
Магия это некая фича которая позволяет делать всякие трюки не предусмотренные изначально создателями.
Очень часто мы даже не задумываемся что используем магию.
Например, директивы прекомпилятора и макросы — ими можно и вовсе перевести C++ на олбанский:

#include <iostream>
#include <locale.h>

#if !defined (_MSC_VER) || _MSC_VER < 1400
#error Wrong compiler! Use MSVS 8.0
#endif

#define НАЧЕЛ      {
#define КОНЧЕЛ     ;}
#define ТИПА       int
#define ВДРУГ      if (
#define ТАДА       )
#define НИХРИНА    else
#define ВЗАД       return
#define КАГДИЛА    (
#define ЙО         ;
#define ЖЖОШ(p,n)  for (; (p) <= (n); (p)++)

#define БАЗАР      std::cout << 
#define СЛЫШЬ      << 
#define СТОЙ       system ("echo. & pause");
#define БЛИН       _wsetlocale (LC_ALL, L"Russian_Russia.ACP");

#define ВРОДЕ      try 
#define ИБАНУЦЦО   throw
#define АПСТЕНУ    catch (const char* __чё__)

#define ПРЕВЕД     ТИПА main КАГДИЛА ТАДА
#define МЕДВЕД     ВЗАД 0; КОНЧЕЛ

ТИПА КРУТО КАГДИЛА ТИПА фигня ТАДА
    НАЧЕЛ
    БАЗАР "ВАЩЕ " ЙО
    ВДРУГ фигня == 8 ТАДА ИБАНУЦЦО "мля! " ЙО
    ВЗАД 0
    КОНЧЕЛ

ПРЕВЕД
    НАЧЕЛ
    БЛИН

    ВРОДЕ НАЧЕЛ

    ТИПА фишка = 0 ЙО

    ЖЖОШ (фишка, 10)
        НАЧЕЛ
        БАЗАР фишка СЛЫШЬ " "; 
        ВДРУГ фишка >= 5 ТАДА КРУТО (фишка) ЙО
        КОНЧЕЛ

    КОНЧЕЛ АПСТЕНУ НАЧЕЛ
        БАЗАР "ИБАНУЦЦО invoked: " СЛЫШЬ __чё__;
    КОНЧЕЛ

    СТОЙ
    МЕДВЕД

Теперь давайте сравним языки по этим критериям:
Си
1. Минимальный базовый набор аксиом: В Си всё просто: вот функции, вот структуры, вот указатели, в атаку! Труъ сишники, типа Торвальдса, смотрят на плюсников как на позеров.
2. Читабельность: в Си она низкая i++, j—, for (;;) но сильно выручает что набор минимален.
3. Синтаксический сахар: квадратные скобочки [] для массивов (можно обойтись указателем) и строковые литералы.
4. В ногу вы просто стреляете: выходите за рамки буферов, забываете подчистить память, в результате имеете настоящий Segmentation fault.
5. Как это не удивительно без магии в Си не сделать ни шагу. Магия в Си — это директивы прекомпилятора. На них делается всё: инклдюды, константы, DSL’ы.

Си++
1. Тут уже появляются объекты, но с ними ещё куча свистелок и перделок по числу которых плюсы впереди планеты всей. Вообще появляется ощущение что плюсы тестовый полигон для всех всех концепций программирования.
2. Читабельность почти никакая. Местами спасает только Си-подобный синтаксис.
3. Сахарка хватает: даже хелоу ворлд начинается с переопределённого оператора << для cout.
4. Стреляем в ногу из пулемёта. Классика жанра — множественное наследование.
5. Магия достигается через шаблоны STL и Boost.

Ява
1. Тут просто взяли Си++ и убрали всё лишнее. В результате всё просто: вот класс, вот методы, создаёшь объект и дергаешь методы, если что-то пошло не так кидаешь исключение, «шо не йасно?».
Но всё равно перестарались: вложенные классы, статические методы, примитивные типы. Когда начинаешь готовится к сертификации OSCJP внезапно понимаешь что Явы ты не знаешь.
2. Синтаксис вполне уже читабельный, если не обращать внимание на реликты после Си. По сути lingva franca из-за чего её любят использовать в учебниках.
3. Если знаешь все приколы Си то в ногу стрельнуть уже довольно сложно. Разве что Out of memory или Null pointer exception. Собственно поэтому на Яве и написали кучу энтерпрайзного софта.
4. Магия постигается с помощью аннотаций, которые вообще то не должны влиять на программу. Но по факту по следам аннотаций потом курочат байт код до неузнаваемости.

Си шарп
1. Взяли яву и натащили всего нужного и ненужного в целях маркетинга. Чем структуры отличаются от классов? Зачем нужен yield? Судя по всему он и не так часто используется.
3. Опять переопределение операторов и прочий зоопарк из C++, но уже с уборщиком мусора.
2. Читабельность нормальная. Ну примерно как у Делфи (создатель один и тот же).
4. Для магии всегда придумывают целые технологии, типа LINQ.

Пайтон
1. Большой набор базовых принципов которые плохо подобраны.
2. Читабельность хорошая — издалека вообще со стихами Маяковского можно спутать.
4. Магия достигается использованием сишных либ которые всё умеют. Поэтому на питоне написано половина гуёв на линуксах.
Вообще про питон лично я ничего хорошего не могу сказать — я на нём написал с десяток скриптов и каждый раз это было отстойно. Может в нём и есть какая фишка.

Перл
2. Перл получился в процессе эволюции текстового редактора. И бесспорно имеет самый ужасный write-only синтаксис. Регулярные выражения как раз пришли из перла, что о многом говорит. Мне кажется создатели Brainfuck просто немного упростили Perl.
4. Магия перла в том что одной строчкой можно переколбасить весь текст в документе.

Руби
По сути — объектно-ориентированный Перл.
1. Синтаксис настолько засахаренный что можно получить диабет.
2. Читабельность как у перла, но выручает единообразие — главное понять концепцию.
4. Магия достигается с помощью метапрограммирования поверх динамизма. Например, если вы дёргаете метод которого нет, то можно его перехватить и всё таки выполнить. Так делают динамик файндеры, например.
Всё что в книжках по яве написано «так делать нельзя» в руби пишут «смотрите, можно даже так сделать!».

Ada
Аду создавали в рамках конкурса для армии США. Т.е. изначально попросили академиков придумать самый крутой язык программирования. За что боролись на то и напоролись.
1. Базовый набор огромен. До появления Scala это был самый богатый язык программирования.
2. При этом великолепный читабельный паскальный синтаксис.
3. Сахару достаточно.
4. Магии практически нет — всё итак уже в языке. Хотя тут я не уверен, я не так много кода видел на Аде.

Я не просто так упомянул Аду, почитайте её критику:

Хоар выразил своё сожаление тем, что «погремушки и побрякушки возобладали над фундаментальными требованиями надёжности и безопасности» и предостерёг от «армады ракет, летящих не туда из-за не обнаруженной вовремя ошибки в компиляторе Ады». Никлаус Вирт высказался более сдержанно, но тоже негативно. Он сказал: «Слишком много всего вываливается на программиста. Я не думаю, что, изучив треть Ады, можно нормально работать. Если вы не освоите всех деталей языка, то в дальнейшем можете споткнуться на них, и это приведёт к неприятным последствиям». Жан Ишбиа, руководитель группы разработчиков Ады, выразив своё «уважение и восхищение» Виртом, не согласился с ним, сказав: «Вирт верит в простые решения сложных проблем. Я не верю в такие чудеса. Сложные проблемы требуют сложных решений».

Стоит ли говорить что в результате Ада в жопе а в космос летает софт написанный на Сишечке?

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

Очень хорошо это описано в статье Андрея Платова О выборе языка программирования:

Scala даст огромный рост продуктивности по сравнению с Java (так же как C->C++). Это верно для проекта с одним автором в вакууме. Сложность, и безграничные возможности языка отразятся гемороем, который нихера не будет способствовать продуктивности. Вопрос только в том чего будет больше. Я пока не знаю, да и больших Scala проектов в мире по большому счету еще нет.

Очень советую почитать эту статью полностью, считайте её продолжением моей.

Вывод: я пришёл к такому же выводу как Андрей Платов — мы сейчас находимся во время ломки языков программирования и реально выбирать на самом деле не из чего — все текущие языки явно морально устаревшие.
Нужно совершенно новое поколение языков программирования. Да такое чтобы все текущие языки показались такой же глупой затеей как писать на перфокартах.
Но об этом я позже.

Ещё по теме

Как выбрать язык программирования

PS

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


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