Как стать автором
Обновить

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

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров4K

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Хорошая (для меня) новость заключается в том, что такой язык существует, и я на нём уже десять лет зарабатываю на еду. Акторная модель, как лучший примитив параллелизации, из известных человечеству, бесподобный паттерн-матчинг и восемь типов без возможности добавления новых — почти сорок лет назад реализовала команда разработчиков эрланга. Вероятнее всего, эти герои (Джо Армстронг и Роберт Вирдинг) не стремились поразить всех своим интеллектом, поэтому вместо интерфейса 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).

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

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

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

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

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

Теги:
Хабы:
+7
Комментарии221

Публикации

Истории

Ближайшие события

19 марта – 28 апреля
Экспедиция «Рэйдикс»
Нижний НовгородЕкатеринбургНовосибирскВладивостокИжевскКазаньТюменьУфаИркутскЧелябинскСамараХабаровскКрасноярскОмск
24 апреля
VK Go Meetup 2025
Санкт-ПетербургОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань
14 мая
LinkMeetup
Москва
5 июня
Конференция TechRec AI&HR 2025
МоскваОнлайн
20 – 22 июня
Летняя айти-тусовка Summer Merge
Ульяновская область