- BrainTools - https://www.braintools.ru -

Нужно ли «развитие» языкам программирования

TL;DR: Нет. Хорошо спроектированный язык в развитии не нуждается.

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

Более того, ниже я постараюсь уложиться в нескольких абзацев, чтобы рассказать, какие требования лично я предъявляю языку программирования в 2025 году, и почему этому «идеалу» просто некуда «развиваться».

Производительность

Нужна ли современному языку программирования общего назначения производительность? — Нет.

У нас есть си, для микроконтроллеров, зубодробительной арифметики и прочего нишевого использования. Си прекрасно справляется со своей задачей. В 99% процентах современного «приложенческого» кода — узким местом будет криворукость разработчиков, а не производительность языка. Мощности современных процессоров и объемы современной памяти [1] — нивелировали ценность алгоритмических изысков, позволяющих сбрить пару микросекунд. А там, где оно действительно надо — всё еще есть си. Удобных биндингов в си — достаточно. Там, где их по какой-то причине не хватает — можно озаботиться своим микрокомпилятором, как это сделали ребята из команды Nx — BEAM традиционно был слабоват в числах, ну вот вам компилятор [2] из нативного кода прямо в CUDA, и куда вообще хотите, с JIT’ом и быстрыми арифметичками. Шах и мат.

Более того, виртуальная машина — уже тоже не проблема. У меня много претензий к Гослингу, но это он понял идеально точно (наверняка, посоветовавшись с Гордоном Муром): виртуальная машина не сделает софт настолько медленнее, что от него придется отказаться в пользу компилятора в нативный код.

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

Повторюсь, пассаж выше (как и все незыблемые правила) — имеет и свои исключения. Но их исчезающе мало. Вспоминается соревнование [3] эликсира с хаскелем и нативным wc для подсчета пробелов в файле: коробочный параллелизм позволил автору кода практически не отстать ни от реализации на си, ни от реализации на хаскеле. И виртуальная машина не смогла этому помешать.

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

Строгая типизация

Нужна ли современному языку программирования общего назначения строгая типизация? — Нет.

Строгая типизация — это то немногое, что функциональщики смогли продать объективистам. Чёрт, да буквально всё в ФП полезнее типов, но нет, купили только это (и отчасти функции высших порядков). Знаете, в чём проблема с типами в языках типа хаскеля? — Они кастрированные, и, как следствие, — очень громоздкие (там что-то с обменом веществ случается, вроде).

Типы могут принести очень много пользы, если они «граждане первого сорта». Ни в одном более-менее распространенном языке, кроме авангарда типа Coq/Rocq [4], Agda [5] и Lean [6], и не покидающего стадию пре-альфа Idris [7], — нет зависимых типов. Строгая типизация без завтипов — детская игрушка. Но это еще не всё: поспешно втаскивая типизацию в языки, где её доселе не было, и где она — чужеродное тело, — втаскиватели понимали, что просто так аверажный разработчик в этот омут не полезет, поэтому вкатывание упростили при помощи «типа джокера» —null / any/interface{}.

В результате разработчик оказывается перед выбором: либо аккуратно выписывать все типы до седьмого колена, как в хаскеле, либо (сроки-то не резиновые) — вот тут пока тиснуть any и комментарий «// TODO FIXME HEEEEELP». Понятно, к чему это приводит. Если вы просеиваете муку, и в сите — всего-навсего одна дырка размером с кулак — остальные ячейки могут быть не толще комариного писка, хлеб выйдет комками.

Классы и объекты

Пора отвратить от себя и тех трех с половиной читателей, кто добрался до сюда, не забрызгав слюной праведной ярости [8] свой монитор.

Нужны ли современному языку программирования общего назначения классы и их экземпляры? — Нет.

Не нужны. В экземпляре класса нет ничего такого, что нельзя было бы выразить гораздо более внятно, лаконично и прозрачно — обычным словарём. В конце концов, мы же как-то обходимся джейсоном для передачи «объектов» туда-сюда? Есть очень специальные, навороченные случаи, где простого джейсона не хватает, но язык описания данных, которого хватает, — может быть выражен при помощи джейсона. Вот пример из жизни: мне потребовался обмен данными между монолитом и микросервисом, в котором были нужны sequence и счётные поля (как в XML); я просто написал библиотеку, которая пишет и читает XML в формате JSON на руби [9] и эликсире [10] — и voilà.

При этом в мире не существует данных, которые пока кому-то не удалось бы корректно сериализовать в XML.

Внимание [11], вопрос: если все данные прекрасно описываются типами данных, разрешенными в джейсоне (строка, число, да/нет, список (массив), мап (dictionary, JSON object), null) — зачем нам лишняя когнитивная нагрузка в виде объектов? Чем экземпляр класса User лучше кортежа {name, password}и набора функций, принимающих этот кортеж в качестве параметра вместо this?

Самое удивительное, что Гвидо был на полшишечки от этого решения, когда придумывал «специальные методы» в питоне (__<name>__), но потом неугомонный улучшайзинг всё испортил.

Ты чё, пёс, в кодах предлагаешь писать?

Нет, конечно.

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

  • паттер-матчинг; везде, где только можно, и еще немного — там, где, казалось бы, нельзя.

  • примитивы параллелизации; не асинхронности, не конкурентности — параллелизации, чтобы вжух, и оно уже параллельно обрабатывается на всех ядрах всех нод в кластере.

  • оптимизация хвостовых рекурсивных вызовов; иначе придётся переусложнять (портить) язык циклами.

Всё. Список оказался не слишком-то длинным. При наличии хорошего, продуманного сопоставления с образцом — и типы, и классы, — можно заменить тегами. Вот смотрите {:user, "Pupkin", "12345678"} — и тип налицо, и функция для работы только с сущностью, помеченной тегом :user — вырисовывается (def login({:user, name, password}), do: …).

Бесплатный полиморфизм из коробки, внятные сообщения об ошибках, возможность создавать новые типы (классы) на лету, — всё уже есть.

Нет, серьёзно, просто вдумайтесь: чтобы забить гвоздь — достаточно молотка, микроскоп не нужен!

Хорошие новости

Хорошая (для меня) новость заключается в том, что такой язык существует, и я на нём уже десять лет зарабатываю на еду. Акторная модель, как лучший примитив параллелизации, из известных человечеству, бесподобно реализованный паттерн-матчинг и восемь типов без возможности добавления новых — почти сорок лет назад реализовала команда разработчиков эрланга. Вероятнее всего, эти герои (Джо Армстронг и Роберт Вирдинг) не стремились поразить всех своим интеллектом [12], поэтому вместо интерфейса Option, реализаций Some и None и обязательного для вящего придавливания величием языка unwrap — предложили в качестве either-монады банальное окортеживание результата, удобное для паттерн-матчинга:

case File.read("file") do
  {:ok, content} -> IO.puts(content)
  {:error, error} -> IO.puts("Error: #{error}")
end

И так во всем.

Лично мне — такой код и писать и читать — проще и быстрее. И я говорю это, как человек, получавший деньги за создание UML-редактора живого языка программирования, на джаве и хаскеле, почти 25 лет назад. Поработавший с тех пор в нескольких энтерпрайзах. Написавший нативную реализацию числодробилки на расте, чтобы звать её из эрланга (это было до появления Nx).

Нигде, ни в одном другом языке, у меня не было такой непоколебимой уверенности в том, что код, который я написал, — будет работать так, как написано в спецификации. Даже в тех случаях, которые мне и в страшном сне [13] приснится не могли.

Так а что с развитием?

А куда должен развиваться язык, который уже идеально закрывает все потребности [14]? Всякие плюшки, типа быстрой арифметики и компиляции в CUDA — прекрасно добавляются сторонними библиотеками (это не AST, который сторонней библиотекой адекватно не добавить).

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

Удачного недоразвития!

Автор: cupraer

Источник [15]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/14098

URLs in this post:

[1] памяти: http://www.braintools.ru/article/4140

[2] компилятор: https://hexdocs.pm/nx

[3] соревнование: https://habr.com/ru/articles/489548/

[4] Coq/Rocq: https://rocq-prover.org/

[5] Agda: https://wiki.portal.chalmers.se/agda/pmwiki.php

[6] Lean: https://lean-lang.org/

[7] Idris: https://www.idris-lang.org/

[8] ярости: http://www.braintools.ru/article/6134

[9] руби: https://github.com/am-kantox/aston

[10] эликсире: https://hexdocs.pm/estructura/Estructura.Aston.html

[11] Внимание: http://www.braintools.ru/article/7595

[12] интеллектом: http://www.braintools.ru/article/7605

[13] сне: http://www.braintools.ru/article/9809

[14] потребности: http://www.braintools.ru/article/9534

[15] Источник: https://habr.com/ru/articles/899544/?utm_source=habrahabr&utm_medium=rss&utm_campaign=899544

www.BrainTools.ru

Рейтинг@Mail.ru
Rambler's Top100