Обновить

Комментарии 131

Линейных типов немножко не хватает. А в целом согласен.

Borrow checker — это не враг, а тот самый идеальный тимлид, который действительно учит и развивает разработчиков.

угу, например если вы хотите две мутабельные ссылки на два разных элемента массива, то он научит что так делать нельзя и разовьет ваши знания стандартной библиотеки - split_at_mut, get_disjoint_mut, iter_mut. Заодно и пакетным менеджером научит пользоваться, ведь если вы хотите взять больше двух ссылок то вам порекомендуют использовать специально написанный для этого crate - https://github.com/mcmah309/indices
Вот только нужно ли вам это развитие?

А нужно ли пытаться обойти borrow checker? Зачем из одного языка (Rust) делать другой (Кресты)?

Простите, а с каких это пор плюсы стали крестами?

Always has been

При слове Кресты возникает только одно в голове - знаменитое питерское СИЗО. Как раз два ++.

превращать - не нужно. Просто я слышал разные версии:

  • borrow checker необходимое зло

  • я научился с ним бороться и почти всегда побеждаю

  • мне пофиг на перформанс и я просто обмазываю всё Ref<Cell

  • я использую ECS/алгоритмы на массивах как раз чтобы не встречаться с ним, теперь я использую индексы вместо ссылок и могу мутировать что хочу.

но называть его учителем и тимлидом - это что-то новое. Ну и что этот тимлид говорит когда я хочу взять мутабельные ссылки на разные элементы массива?

Ну и что этот тимлид говорит когда я хочу взять мутабельные ссылки на разные элементы массива?

"Ты не должен этого хотеть" (c) Яндекс

Меня в расте всегда немного озадачивала некая "мемность" языка. Довольно часто в профильных комьюнити вижу некий легкий, саркастичный троллинг / стеб раста, смысл которого сводится к тому, что апологеты считают его решением всех бед в CS, а остальные видят его как пятое колесо в телеге. А вот подобных мемов про тот же го по моему вообще ни разу не видел.

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

Может быть мемасики говорят об интересе? Люди обычно не шутят про то, что не интересно

Го - это же тот язык, где 50% кода — конструкция
if err != nil {return err} ?

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

Го - язык, разработанный на коленке в довесок к разработанному garbage collector. Засунуть такое количество мест, где можно себе отстрелить ногу как в крестах, в язык "для дебилов" - это было гениальное решение. Моё любимое - сделать close на канале в читающей горутине сразу же вызывает панику при следующей попытке записи в этот канал - приходится прыгать вокруг и обмазываться дополнительными чтениями, каналами или AtomicBool. В расте тебе просто вернётся Result::Err, который спокойно обрабатываешь или игнорируешь и идёшь дальше.

Это к Пайку, все его решения были гениальны, но не все раскручивал Г, поэтому остальные — умерли, не родившись.

Он никогда этого не говорил, тебя уже много раз на хабре ловили на этом вранье, а все ты не успокоишься.

Меня ловили на вранье?! Мальчик, иди обратно в школу, и не высовывай нос, пока не поумнеешь.

https://www.youtube.com/watch?v=uwajp0g-bY4 — это видео, на котором он это говорит
▸ «the key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt» — это текст, если в гугле забанили.

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

наши программисты — это сотрудники Google, а не исследователи. Обычно они довольно молоды, только что окончили учёбу, вероятно изучали Java, возможно C или C++, возможно также Python. Они не в состоянии разобраться в очень изощрённом языке, но мы хотим, чтобы они создавали хорошее программное обеспечение. Поэтому язык, который мы им даём, должен быть для них простым для понимания и лёгким в освоении.

Как видишь, это "несколько" отличается от твоего вранья

Пайк пишет про молодых и безусловно таланливых людей в начале их карьеры в гугле, которым го позволяет сразу показывать высокую продуктивность, не тратя кучу времени на глубокое изучение сематинтического сложного языке типа С++, а не про "дебилов по объявлению". Единственный дебил тут это ты.

Плюсанул карму, такой запал не должен пропадать зря. Хоть посмеялся.

Плюсанул карму

Можешь и мне плюсануть заодно. )) А то политически не нейтральные участники, в нарушение устава, все баллы посрезали.

Я не подаю по субботам.

Мне тоже (

Имхо если читать между строк то именно это там и написано. Низкий уровень профессионализма, нежелание думать, требование выкатывать фичи породили вот такой подход - язык который минимизирует требования к программисту, позволяет обычному программисту написать поддерживаемй, быстрый а иногда еще и многопоточный код.

Низкий уровень профессионализма породил язык, который позволяет писать быстрый и поддерживамый код? Чего? А какие языки порождаются тогда при высоком уровне профессионализма, которые не позволяют писать быстрый и поддерживамый код?

Те которые имеют противоположные признаки из списка, которых нет в Го:

-долгая компиляция(не поддерживаемый код)

-большой выбор операторов, перегрузка операторов, долго учить язык(нужен высокий уровень профессионализма)

-выключенный автоформаттер и линтер кода

-сложная система зависимостей или линковки

-выходной файл работает через интерпретатор(медленный код)

Убрать последний пункт и всё совпадет с Растом

Я просто не понимаю этого аргумента, "го это язык для низкого уровень профессионализма, потому что на нем можно писать быстрый, надежный и легко поддерживый код" и дескать это очень плохо. Мне то казалось что возможность писать эффективный и поддеживаемый код это по сути конечная цель любого языка.

Сетевые сервисы, оркестрация, CLI-тулинг — там всё равно внешний мир ненадёжен. Упал — перезапустил, залогировал, пошёл дальше.

Для этого сложных бизнес правил не нужно, падение и дедлоки пофиг - рестарт сервиса и как новенький

Нельзя в сетевых сервисах падать от ненадёжного мира. Триста кривых клиентов пришло, процесс от них упал - и отвалились соединения ещё с миллионом. А восстанавливать их долго и дорого.

Да, а в rust ровно для этой конструкции специальный макрос try! был, а потом оператор ? сделали. И все ещё рекомендуют 2 почти стандартных библиотеки (anyhow, thiserror), чтобы в каждой функции удобно было вручную реализовывать развертывание исключений, которых в языке "нет".

Каждый из них имеет свои недостатки: у PHP — неудачная архитектура, у Ruby — медленная производительность, а у функциональных языков — нехватка библиотек и обучающих материалов.

Спасибо, поржал. Судя по тексту, раст вам известен примерно на таком же уровне, как вышеупомянутые языки.

Из десяти самых высокопроизводительных веб-фреймворков семь написаны на Rust.

А шопифай на рельсах, дальше что? И почему-то мне кажется, что один шопифай обслуживает больше трафика, чем все вместе взятые бизнесы на «семи самых производительных фреймворках».

Асинхронность в Rust хоть и является незавершённой частью языка, но не «костылём»: асинхронный Rust очень производителен и надёжен. 

Назовите хоть один сервис под хайлоадом на расте. Асинхронность в расте — несомненный костыль, который рассыпается (и будет рассыпаться всегда, by design) в кластере.

Нулевые указатели, значения, которые больше не существуют к моменту использования, и явные null-ы могут вызывать массу проблем в работе компьютерных программ.

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

В общем, мне понятны ваши восторги, но они обязаны вашему ограниченному кругозору, а не качеству раста как такового. Акторная модель, нативные абстрактные синтаксические деревья, инфраструктура метапрограмирования (макросов), защита от сбоев — вот всего лишь несколько первых пришедших на ум важнейших атрибутов современного языка. А не синтетические тесты «скорости фреймворка» и не пакетные менеджеры, которые в 2025 есть везде, и среди которых cargo — далеко не самый адекватный.

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

Кажется это принципиально невозможно, ибо общение с той же OS во многих случаях оборачивается вызовом сишных API - zed что-то там мутит с unix stream, uv - WinAPI дёргает, helix и zellij интегрируют плагины на wasm, которые могут быть на произвольном языке, что опять же - unsafe граница между языками. А так, чтобы оно никак не взаимодействовало с системой или другими языками и было сложнее калькулятора. Можно ли считать gleam продвинутым калькулятором или пойдёт под категорию?

Я не о низком уровне, который реализован авторами языка и протестирован всеми, кто язык использует.

При чем тут Gleam? Он работает на BEAM, что приносит всю кухню эрланга; добиваться отказоустойчивости можно не только запретом делать плохое (неправильный подход, которому следуют почти все) — но и буквально разрешением делать плохое с обещанием разрулить это плохое за разработчика.

Компилятор языка написан на Rust и весь рантайм к нему вроде тоже на нём - по ссылке репа, справа в сайдбаре с инфой можно посмотреть распределение языков. Считаем ли мы компилятор и рантайм языка продвинутым калькулятором или таки относим его к легитимным приложениям сложнее калькулятора?

Я не о низком уровне, который реализован авторами языка и протестирован всеми, кто язык использует.

Так и я не про unsafe в std, а ровно тот unsafe который появляется непосредственно в проекте некалькулятора.

Компилятор языка написан на Rust и весь рантайм к нему вроде тоже на нём […]

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

Ви так говорите, словно компилятор без пользователей живёт. Собственно про это и вопрос - считаем мы это как приложение проходящее обозначенный критерий или считаем, что это калькулятор, пусть и немного более замороченный. Что могло бы пройти этот критерий? Редакторы кода (zed, helix) не проходят, потому что у них есть unsafe, приложенька на каком-нибудь tauri/dioxus тоже, т.к. фреймворк содержит unsafe, но если мы считаем это допустимым в пределах библиотеки, но не собственного приложении, то внезапно критерий начнут проходить немало приложений.

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

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

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

P. P. S. Если подытожить то, что я имею в виду, одним предложением — мне глубоко претит идея запретить делать плохо (а потом, конечно, разрешить в стиле «если нельзя, но очень хочется — то можно»). Я фанат идеи разрешить делать плохо, Let It Crash, и продуманная защита от сбоев вместо запрета ошибаться.

Если подытожить то, что я имею в виду, одним предложением — мне глубоко претит идея запретить делать плохо

Собственно, для этого и существует возможность использовать иные языки. Кто-то не хочет ловить сегфолты и переполнения буфферов, кого-то устраивает и то и другое, но интересует скорость и простота разработки при большей производительности. Кого-то скорость вообще не волнует и тот пишет на каком-нибудь PHP вообще и радуется, что его ошибки заканчиваются на paamayim nekudotayim.

Не уверен, что мы говорим о одном и том же (и что мне удалось донести мысль). Все языки из примерно двух десятков, известных мне не понаслышке, — как раз запрещают делать плохо (кроме одного).

«У нас есть сегфолты, которые вас когда-нибудь обязательно ударят сзади по голове, просто избегайте их». «У нас есть рекурсия, просто помните, что хвостовой оптимизацией мы не озаботились, и карета Фибоначчи отыквится в полночь». «У нас есть die(), но вот вам триста фреймворков, чтобы жить вечно».

Армстронг однажды заявил: «программисты будут^W будем делать ошибки, мы не роботы, такова наша природа; поэтому надо просто уметь корректно восстановиться после непреднамеренной ошибки, а преднамеренные — сделать штатным управлением контроля». Так появились деревья супервизоров (которые потом криво и косо попытался архитектурно повторить кубер) и идеология Let It Crash.

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

——

За «paamayim nekudotayim» — огромное спасибо, мне раньше не попадалось.

Чтобы повалить виртуальную машину эрланга — нужно три бородатых многомудрых хакера и один Роберт Вирдинг

Или всего одного запроса который вызовет out of memory. Или очередного бага в GC

мне раньше не попадалось

его в какой-то момент зарефакторили в языке, когда евреи перестали быть основными ментейнерами. Где-то в районе php 5 кажется

Я перестал писать на похапе еще до того, как Моисей обзавелся скрижалями.

Назовите хоть один сервис под хайлоадом на расте

Pingora в cloudflare, которая держит 40 млн запросов в секунду это достаточный хайлоад или еще нет? Ηypervisor в Azure workloads? Video encoding pipeline в Discord?

Назову. Часть кода серверов Discord была переписана с Go на Rust. Гугл в помощь

«Часть кода серверов»  — это не сервис. У меня часть кода серверов на баше написана.

Вон выше действительно неплохой, хоть и очень нишевой пример — Pingora. И все равно, всё это пока выглядит как ассемблерные вставки в коде на си: вот тут автору почему-то втемяшилось написать малюсенький кусочек на другом языке. Почему?! Зачем? Откуда понятно, что тот же кусок на бейсике был бы хуже?

Не, там буквально история про сервис. Конретно - сервис уведомлений. В какой-то момент интенсивность реквестов на него превысила 1mrps и половина уведомлений перестала доходить, особенно если канал имел довольно большое количество участников - тогда под 100к человек каналы были ещё не настолько частым явлением. В итоге гошечка не справлялась с наплывом и дрочила память как полоумная туда-сюда из-за чего могла профукать вспышку и не послать уведомление. В итоге сервис переписали на Rust, чем подняли себе предел RPS, уменьшили потребление памяти к почти константному и получили стабильную доставку сообщений.

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

Спасибо.

Акторная модель, нативные абстрактные синтаксические деревья, инфраструктура метапрограмирования (макросов), защита от сбоев

Напрямую противоречит производительности:

- AST в рантайме — интерпретация, динамика, оверхед

- Макросы - если compile-time (Rust, Lisp) то ок; если runtime (Elixir hot reload) — платишь

- Акторы с супервизией - GC, копирование сообщений, планировщик сверху ОС

- Защита от сбоев (изоляция процессов) границы, проверки, избыточность

Это всё про надёжность и выразительность за счёт производительности. Erlang осознанно выбрал этот trade-off.

"Современный язык" — это чья-то повестка. Для systems programming другие атрибуты "важнейшие".

AST в рантайме

Шта? Вы хотя бы приблизительно понимаете вообще, что такое AST?

Elixir hot reload никто никогда в продакшене не использует. И макросы в эликсире всегда остаются в compile-time, даже если какой дурачок и вызывает компиляцию из времени выполнения.

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

Erlang осознанно выбрал этот trade-off.

Это чушь. Что такое «systems programming» я не знаю, но мы скоро сможем сравнить раст и эрланг напрямую, когда у меня выдастся минутка и я поведу к скамейке (bench) эрланг и мою библиотеку joerl на расте, которые занимаются буквально одним и тем же.

А существует хоть одно приложение, чуть сложнее калькулятора, в котором не используется ансейф?

Существует, великое множество

Асинхронность в расте — несомненный костыль, который рассыпается (и будет рассыпаться всегда, by design) в кластере.

Из той же оперы, что и в «расте нет параллелизма» :D

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

От акторов даже в скале отказались, лел

От акторов даже в скале отказались

Ну, если в целой скале отказались — тогда конечно, я бы вообще смертную казнь за их использование ввел. А кто отказался, кстати? А то, когда я в последний раз заглядывал в интернет, кривую реализацию scala.actors лет 15 назад действительно выбросили, но с тех пор Akka стала стандартом де-факто.

великое множество

из той же оперы

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

а главное — на хабре любят пустозвонов, с умным видом излагающих бессмысленные трюизмы, не имеющие под собой никакого обоснования.

Судя по лайкам под вашими комментариями, действительно, любят :D

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

Асинхронность в расте — несомненный костыль, который рассыпается (и будет рассыпаться всегда, by design) в кластере.

[citation needed]

Вам надо — вы и ищите, это не так сложно.

Асинхронность в Rust хоть и является незавершённой частью языка, но не «костылём»:

К сожалению - является именно костылём. Во-первых раскраска функций даёт несколько отличный синтаксис и инвалидирует работу borrow checker, позволяет писать честные асинхронные безопасные дедлоки.

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

Отдельно стоит заметить, что некоторые дизайнерские решения относительно API стандартной библиотеки также вызывают вопросы, т.к. то что в Хаскелл было сделано для всех и сразу в Rust имеет несколько полу-копипастных частных имплементаций - всякие map на Option один из таких примеров.

Всегда актуальная документация и тесты

Это в общем-то не языковая проблема. Добавить генерацию документации не слишком сложно, а вот поддерживать её актуальность - проблема. Из принципиальных фишек cargo doc есть то что сниппеты кода в документации автоматически можно тестировать, да.

Здесь и далее «крабы» — это Rust-разработчики. Это связано с «талисманом» языка: красным крабом.

Это не совсем так. Маскотом Rust является cRUSTacean - то бишь ракооборазный. Так что не только в доте раки зимуют.

Из принципиальных фишек cargo doc есть то что сниппеты кода в документации автоматически можно тестировать, да.

Принципиальных? А ничё, что в питоне доктесты появились сто лет назад, а в эликсире, и, вслед за ним, в эрланге и том же глиме — десять лет назад?

Сравниваю с классическими компилируемыми языками в нишу которых воткнулся Rust, поэтому в сравнении с ними это принципиально новая фича. C, C++, C#, D - вроде никто из них до сих пор не поддеживает доктесты, но это не точно. В каком-нибудь JS с появлением node/npm тоже могли появиться, но в природе с ними не сталкивался. Аналогичная история с python - видел только примеры автоматической генерации, но не встречал автотестов в doc комментариях. Про эрланг ничего особо не знаю, ну а ржавый gleam начал появляться видимо с появлением Rust 1.0 те самые 10 лет назад - у кого доктесты были подсмотрены - вопрос открытый.

Что такое «ржавый gleam»?

С этим языком я знаком, причем не совсем понаслышке.

Он не имеет вообще никакого отношения к расту, кроме того, что Луис на хайпе решил писать транспайлер в эрланг на расте. Ровно с таким же успехом его можно было бы написать на похапе, на баше, или вообще на связке lexx/yacc. Исполняемый код вообще ничего общего с растом не имеет — это BEAM байткод, который, к тому же, создается нативным компилятором эрланга.

на хайпе решил писать транспайлер в эрланг на расте

Собственно это я и зову ржавым кодом. Oxidation, если угодно. Результат призыва RIIR.

Сам Gleam это язык, который превращается в BEAM байткод, закономерно совместимый с другим аналогичным байткодом, который можно генерировать на Эрланге. Кажется его можно использовать не имея эрланга в качестве необходимой зависимости - то есть оно не транспайлится в Erlang по-умолчанию.

https://gleam.run/frequently-asked-questions/#what-does-gleam-compile-to

Когда я начал приносить правильные типы в BEAM, передо мной тоже стоял выбор языка, и я выбрал эрланг, чтобы не звать кучера с собой в постель: я создаю эрланговские формы и отдаю их компилятору без посредников. Да, медленнее. На этапе компиляции же, не в рантайме. А в рантайме я в теории быстрее глима, потому что правильно резолвлю типы, но это уже другая история.

Но Луис мне сильно помогал советами типа «по каким граблям ходить не нужно».

Несмотря на название, doctest не предназначен для написания документации и тестирования кода из примеров. Это просто хороший и быстрый фреймворк для тестирования, функционально аналогичный Google Test и Catch2. Для генерации документации С++ обычно использует doxygen, но ни разу не встречал плагинов к нему, который бы запускал бы юниты из документации (это не значит, что их совсем нет, это значит, что я с ними не сталкивался).

Пардон, бес названия попутал. Сам я с плюсами не сталкивался с тех пор, когда тесты вообще никто не писал.

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

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

на длинной дистанции надежнее

Надежнее, чем что именно?

на длинной дистанции надежнее

Надежнее, чем что именно?

Вот и мне стало интересно, о какой такой "длинной" дистанции использования Rust идет речь?

Servo, наверное.

Авторы языка не осилили написать проект, ради которого язык и создавался. Лучшая история успеха, как мне кажется.

Авторы языка не осилили написать проект, ради которого язык и создавался

Уточнение: проект начали писать задолго до релиза 1.0, когда в Rust ещё был сборщик мусора и зелёные потоки, которые можно было смешивать с нативными. И да, CSS-движок Stylo оттуда в итоге в Firefox перенесли.

чем на языках без borrow checker (наличие статической типизации естественно подразумевается как мастхэв).

наличие статической типизации естественно подразумевается как мастхэв

Кем подразумевается? Людьми, которые не понимают, что статическая типизация без завтипов и пруверов — это дутый, никому не нужный, пшик?

Ну например людьми, которые Глим переписали на Расте, потому что в Эрланге не хватило этой самой статической типизации =)

Prototype versions of the Gleam compiler were written in Erlang, but a switch was made to Rust as the lack of static types was making refactoring a slow and error prone process.

Ну например автор вот напрямую говорит:

If Cure’s static analysis functionality is a fighter jet then Gleam’s is a paper plane!

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

Кому-то почему-то кажется, что (цитата отттуда же, откуда ваша):

A full Rust rewrite of the prototype resulted in the removal of a lot of tech debt and bugs, and the performance boost is nice too!

А мне, наоборот, кажется (на основе собственного опыта с Cure, например), что из цитаты можно безболезненно выкинуть пару слов (и пару добавить, для ясности):

A full Rust rewrite of the prototype resulted always results in the removal of a lot of tech debt and bugs.

Производительность, разумеется, увеличилась, тут мне крыть нечем. Но это compile time производительность, с которой я готов мириться (да и типы тут ни при чем).

единственным рабочим способом является либо ансейф либо уход в излишний Rc + RefCell

Есть ещё способ: кладём всё в арену и дальше граф из индексов в этой арене.

Это все хорошо, но реализация времени жизни переменных и наследование через трейты, кривая реализация константных данных и недоделанная шаблонизация - убивают язык. Если в соло писать, то все эти проблемы можно обойти и язык становится идеален. Если в команде кто-то неудачно воткнул трейты, то использование Rust становится кошмаром.

Что такое у вас наследование через трейты?

А как же Haskell? 😜😎

Он прекрасен

в отличие от хаскелистов

Хаскелисты тоже нормальные попадаются. Джон Хьюз придумал лучшее, что случалось в мире тестирования, — property-based тесты (ака QuickCheck), например.

Омерзительны те хаскелисты, которые ни строчки кода на Хаскеле в продакшн не выкатили. Вон ниже под моим комментарием — уже три минуса, а ведь я просто дословно процитировал их девиз.

Still avoiding success at all costs.

Обычно я на стороне Rust, но тут несколько вопросиков появилось...

Скорость выполнения Rust-кода действительно впечатляет.

А нельзя ли тогда компилятор Rust написать на самом Rust? А то некоторые жалуются, что у них руки устают драться с коллегами игрушечными мечами верхом на офисных креслах...

развешивать нечитаемую лапшу из вложенных операторов if в связке с несколькими логическими И/ИЛИ (что часто встречается в Go, JavaScript, PHP и Java).

сопоставление по шаблону также доступно в Ruby, Python, Kotlin и C#.

Я сейчас шокирую кого-то. Но в Go и PHP есть switch. С... Спокойно, держите себя в руках. Я понимаю, такое переварить не просто. Многие вообще не в курсе. Но вот. Они есть. Даже работают. Я проверял.

В языках Go и Rust любая возникающая ошибка обязана быть обработана.

Чего, правда? А Go в курсе, что он что-то обязан? Просто выкидываете значение err, не присваивая его и живёте дальше. Как получится. :)

Но в Go и PHP есть switch.

Это просто ветвление условного оператора (по сути if/else if/else). Возможность в одном блоке когда указать несколько условий — вовсе не pattern matching.

Тогда Python почему в списке нормальных языков? Его match умеет не больше switch.

Будет нечестно не сказать о том, что сопоставление по шаблону также доступно в Ruby, Python, Kotlin и C#.

А вы статью точно читали? Или просто залетели в комментарии похоливарить?

Да вроде как да. Видать чего-то не заметил. Потому что про Python ничего не написано. А для Rust примеры не сложнее того, что можно сделать в других языках. Ну, просто вот это:

Some(v) if v > 5 => println!("Больше пяти: {v}")

А в Go я типа не могу if внутрь case вставить? Ну т.е. про Rust ничего особо не показано, а про Python я теперь вообще в непонятках. Может его match мощнее, чем я думал?

Теперь моя очередь вопрос задавать: Вы свой каммент написали чисто потроллить или правда не предположили, что человек может всерьёз спрашивать?

Если вдруг вопрос забылся:

Что такого умеет match в Python, чего не умеют switch в PHP/Go? Если ничего, то имею ли я право задаться вопросом за что Python оказался в списке pattern matching языков?

Что такого умеет match в Python, чего не умеют switch в PHP/Go?

Я не с целью холивара, просто мимо проходил. Поскольку я не знаю, как устроен switch в PHP/Go, напишите ваш вариант такого switch на Go, например:

from dataclasses import dataclass

@dataclass(frozen=True)
class Rectangle:
    length: float
    width: float

shape = Rectangle(length=4.5, width=2.5)

# ...

match shape:
    case Rectangle(length, width=2.5):
        # Переменная length связывается со значением shape.length
        print(f"Площадь прямоугольника = { length * 2.5 }")
        # Площадь прямоугольника = 11.25

Ну вот, кто-то смог нормально ответить. switch работают примерное как в C. А это интересно, пожалуй к Python и правда стоит снять претензии.

свичи в си и матч в питоне вообще ни разу не одинаковые. В си у вас фактически проверка целочисленного значения происходит. А всё что оказывается не int к нему кастится и всё равно сравнивается как целочисленное - если enum оказались c одинаковым значением, то оно их будет считать одним и тем же. У вас не выйдет сделать в Сишном свиче одновременно сверку типа и распаковку переменных. В С++ что-то подобное только-только в свежих стандартах завезут, а в Си такого ждать не приходится вовсе. Можно конечно скрафтить какой-нибудь хитрый макрос, который будет выглядить похоже на паттерн матчинг, но там столько подводных камней всплывает, что обычно никто так не делает.

А можно вместо условия width=2.5 — заматчить условие ширина не меньше двух, или не меньше пяти, но тогда длина должна меньше единицы?

В BEAM машине это будет условие %Rectangle{l, w} when w >= 2 or w >= 5 and l < 1

Можно, уже смотрю pep-0636.

case Rectangle(length=l, width=w) if w >= 5 and l < 1:

Круто (вообще никакого сарказма, или чего там, действительно круто, так мало, кто умеет, но это должно быть супермедленно, если под if можно запихать все, что угодно; матчи по-хорошему должны резолвиться один раз).

А %Rectangle{l, w} when is_integer(l)?

Видимо так:

case Rectangle(length=l, width=w) if isinstance(l, int):

И это не супермедленно. По крайней мере, насколько я нагуглил, CPython использует для таких сравнений специальные инструкции байткода, типа MATCH_CLASS, MATCH_SEQUENCE. Т.е. это будет работать быстрее аналогичной цепочки if <условия> <условия> <условия>...

Круто. Тогда прям совсем молодцы.

Это просто ветвление условного оператора (по сути if/else if/else). Возможность в одном блоке когда указать несколько условий — вовсе не pattern matching.

Так switch это вообще не pattern matching

так а я о том же

В расте тоже нет настоящего паттерн-матчинга, если что.

Ого. А какой он там? Получается, что тогда и в Хаскеле нет настоящего паттерн-матчинга

Получается именно так.

x = 1; 1 = x — сработает? Это просто хрестоматийный и самый простой пример для проверки паттерн-матчинга.

В scala паттерн матчинг поинтереснее. С помощью unapply() можно реализовывать совсем абстрактный матчинг, например матчить строку как число (с одновременным парсингом).

А нельзя ли тогда компилятор Rust написать на самом Rust? А то некоторые жалуются, что у них руки устают драться с коллегами игрушечными мечами верхом на офисных креслах...

Основной компилятор Rust написан на Rust - rustc. Называется это self-bootstrapping, хоть и основным бэкендом все еще выступает LLVM.
Первая версия компилятора была написана на OCaml, IIRC.

Это сарказм был. Жалуется народ на низкую скорость.

Это не одно и то же, если кто-то сам написал _ вместо err, значит сам специально не хотел обрабатывать ошибку, а вот если кто-то не обкладывает функции try.. catch, на все возможные исключения, то это потому, что всего не упомнишь, а язык и ide никак не подсказывает, где надо писать try..catch, а потом это особенность яп вырастает в проблему.

Я бы сказал, что статья - хорошая работа продажника, но не скажу. Потому что не понимаю кто будет конечным бенефициаром если она таки продаст мне Rust. Поэтому просто скажу, что все штампы по поводу Rust, равно как и по другим языкам - чисто маркетинговые сказки, серьёзно такое обсуждать...

Но что, если я скажу вам, что существует почти идеальный язык?

Ну да, очевидно существует. А "почти" - почти всемогущее лингвологическое волшебство.

Это Rust.

Ну да, конечно, он входит в группу почти идеальных языков вместе с, как минимум, Go и Dart. Ну и чё?

Как вышло вот это вот поколение хайповых языков, так я написал наивный тест - числа Фибоначчи. Так посчитать, сяк, большие целые надо откуда-то взять - библиотеки пощупать, GUI да TUI прикрутить, в Termux запустить, APK собрать... ну и на язык посмотреть.

Rust ничем меня не порадовал - ни соразмерностью частей, ни окончательным решением хоть какой-то проблемы, ни особым удобством работы (Cargo по сравнению с СMake - песня, но по сравнению с Go - ровня). И не порадовал компилятором - ну не быстро, в Termux жалуется что не может какие-то ссылки создать, копировать мол приходится...

А Go соразмерностью частей порадовал, дженерики например, по скорости Go то в два раза медленнее то в два раза быстрее (это может быть модуль больших целых, поди знай), но главное - только с ним все эксперименты прошли как по маслу (иными словами, дебилы, о которых пишет выше cupraer, успешно нейтрализованы). Вторым по небесячести, к слову, был JavaScript.

А вот то, что вот эти два способа

func frp(n int, a *big.Int, b *big.Int) *big.Int {
	if n < 2 {
		return b
	}
	return frp(n-1, b, a.Add(a, b))
}

func frt(n int) (*big.Int, *big.Int) {
	if n < 2 {
		return big.NewInt(0), big.NewInt(1)
	}
	a, b := frt(n - 1)
	return b, a.Add(a, b)
}

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

В Go нужно понять - не надо всё время писать if err != nil {return err}, а в Rust - не надо плодить ссылки. Как по мне - паритет. В Go объекты не надо бездумно создавать, в Rust их не нужно бездумно копировать - паритет, особенно учитывая, что по настящему критический код всё равно попросят написать без выделения или освобождения памяти.

Так что да, в Rust всё нормально, но не до таких восторгов. А можно иначе - либо нормально, но не всё, либо над Rust трудятся зря.

Вот как эти труды описывает ИИ Гугла

Key areas of work

  • Performance: The compiler performance group is working on a roadmap to improve compilation speed, and progress has already doubled the performance over the past few years. A 2025 survey identified linking as a major bottleneck, and the default linker for the popular x86_64-unknown-linux-gnu target is switching to the faster LLD linker.

  • Refactoring and modernizing: There are ongoing projects to redesign and re-implement parts of the compiler for better semantics and to prevent bugs. One example is the need for a redesign of "unsized locals" because the current implementation lacks a proper operational semantics, making its interaction with optimizations unpredictable.

  • Team and project structure: The compiler team structure has been reorganized to better focus on specific areas, and the overall project is tracking progress towards a slate of 40 project goals, including many flagship initiatives.

  • Language and feature stabilization: Regular new versions of Rust are released (like 1.85.0, 1.88.0, and 1.90.0), which include new stable language features and improvements to Cargo, the package manager. 

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

Было бы несправедливо умолчать о недостатках Rust. Первое, что приходит на ум, — это высокий порог входа.

Гугл: «Порог входа» — это степень сложности или количество усилий, необходимых для начала деятельности в какой-либо области, например, освоения новой профессии.

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

Так что получается у rust низкий порог входа 😁 за джуном на крестах или пыхе глаз да глаз нужен, а за юным крабом смотрит компилятор

Хм, интересная мысль, заставляет задуматься. Спасибо вам.

Классический бейсик удовлетворяет обоим требованиям.

В нет нет указателей и один поток

У Haskell, получается, еще ниже!

Для меня синтаксис языка выглядит перегруженным и непохожим ни на один другой язык. Чтобы умнее было и непонятнее как будто, при этом тривиальными вещами программульки занимались. Наверное эстетика шаблонов на плюсах или еще что-то такое

непохожим ни на один другой язык.

Т.е. по вашему он не похож на ocaml/хаскель/эрланг и любой другой фунциональный язык?

Интересно было бы узнать про владение/заимствование в хаскеле/окамле

Причем тут владение и синтаксис языка?

В хаскеле оно не надо, там все иммутабельно ;)

А можете привести конкретные детали синтаксиса, которые вызывают затруднение?

Насколько понравились первые два-три предложения статьи, настолько отвратило остальное.

Когда-нибудь шили одежду на заказ? Первая примерка, возможно вторая. Все наживую. Висит, подвернуто, на нитках или булавках. На манекене портного, до показа вам, еще "страшнее". Все прекрасно понимают, что в этом никто не пойдет на улицу. Но уже видно продукт, его слабые места, где не хватает или топорщится, где "не идёт", которые также легко на булавках или мелком подправить.

Еще веселее выглядит конструирование более сложных продуктов. Из агрегатов, которые из узлов, а те из деталей. Промежуточные этапы выглядят как чудовищные франкенштейны.

А что же с нашим любимцем? Всё или ничего! Никого не волнует, что "портному" может быть плевать, если где-то что-то разойдется, оторвется, перекосит, упадет с ошибкой выполнения. Потому сейчас он другим занят. Не упадет, потому что то место выполняться не будет. Но будь добр запускать только в состоянии "можно выйти на улицу".

И нет, это не претензия языку. А лишь что не всё красивое, всегда полезно. Одних может привлечь, а других отвратить.

Статья на 60% сгенерироапна ИИ.

Откуда такие цифры? Может всё же на 146%?

Это хорошо, что вы не согласны только с цифрой. Я вижу, что картинки вставили сами — ИИ пока ещё не умеют так работать с хабраредактором.

По существу: переливание из пустого в порожнее - 0% уникального контента, грубые фактические ошибки, на которые были уже указания в комментариях, раздутый объём.

Через слово в круглых скобках перевод на английский кривопереведённых на русский англоязычных терминов. Готов сделать ставку — ДипСик использовался.

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

В целом ИИ пишет неплохо, но нужно в начале статьи об этом предупреждать.

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

Удивлен, что нигде этого раньше не встречал. Все только восхищаются финальными. И даже если вред упоминается, была тут серия статей про Раст в гейминге, цельная мысль так и не сформировалась.

На момент написания статьи хранилище сторонних библиотек (сайт https:://crates.io) содержит почти 207 тыс. пакетов. Конечно, не все они заслуживают добавления в проект,

Да че уж там, можно и все в проект добавить.

Можно даже написать crawler, который будет добавлять вновь появившиеся библиотеки в старые проекты.

Согласен по всем пунктам кроме borrow checker'а, null-безопасности и асинхроннсти:

fn main() {
    let s = String::from("hello"); 

    make_some_processing(s);
    // Не скомпилируется, так как функция make_some_processing
    // забрала владение над s, и здесь s уже недоступен
    println!("Processed: {s}");
} 

fn make_some_processing(some_string: String) {
    println!("{some_string}");
}

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

Про null это вообще бред, вот у нас есть некий класс который может быть нулл. В расте для такого случая предполагается сделать указатель на этот класс опциональным и проверять на None. Но если всё равно проверять на None в чём проблема блин проверить на null? Это буквально тот же самый if !class.is_none только if class != null. Изобрели костыль и ходят радостные.

Ну и про асинхронность да она есть и довольно удобная но это всё ещё заражающая асинхронность когда приходится в итоге делать асинхронным ВЕСЬ код. А ещё если открыть tfb внезапно обнаружится что самая быстрая асинхронность в этом вашем расте внезапно у библиотеки may, то есть буквально той библиотеки которая обходит все встроенные механизмы асинхронности.

в чём проблема блин проверить на null?

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

Так ещё раз, в чем проблема тогда сделать линтер который проверяет есть ли проверки на нулл? Или варнинг? Почему из за того что кто-то дебил дебил поумнее лишен возможности присвоить переменной её настоящее значение?

Согласен, можно сразу писать без багов. Непонятно, почему люди так не делают…

Оффтопик: выпускать в продакшн код, компиляция которого завершилась с ворнингами, в 2025 году — это абсолютнейший маркер непрофессионализма.

В расте без вот такой строки в CI делать вообще нечего:

cargo clippy --all-targets --all-features -- -D warnings

Есть у меня ощущение что недавно ребята из Claudflare забыли про это правило. Краем уха слышал, что там unwrap пролез в прод и вызывал панику.

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

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

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

Про null это вообще бред, вот у нас есть некий класс который может быть нулл. В расте для такого случая предполагается сделать указатель на этот класс опциональным и проверять на None. Но если всё равно проверять на None в чём проблема блин проверить на null? Это буквально тот же самый if !class.is_none только if class != null. Изобрели костыль и ходят радостные.

Фишка в том, что в Rust можно не делать Option и тогда нигде на отсутствующее значение проверять не надо. В других языках, где null есть, обычно он является допустимым значением для всех ссылочных типов, а записать тип, который null в число допустимых значений не включает, нельзя.

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

Так он и должен быть допускаемым значением для всех ссылочных типов.
Null - это 0. Вы сейчас говорите а давайте заведем специальный тип чисел который может быть чем угодно кроме нуля. Это некорректно, это логическое ограничение а не техническое. И обрабатываться оно должно как часть логики а не техники. Это мы опять решаем софт проблему хард методом.

В других языках, где null есть, обычно он является допустимым значением для всех ссылочных типов

А другие языки, в которых нет типов, или нет ссылок, или нет ни того ни другого — с ними что?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
domclick.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Dangorche