Озадаченный краб
Озадаченный краб

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

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

Wick был главной целью наших экспериментов с Rust
Wick был главной целью наших экспериментов с Rust

Спустя три года, выполнив несколько развёртываний в продакшен, написав электронную книгу и выпустив примерно сто пакетов на crates.io, я решил, что настало время поделиться своими мыслями о Rust.

Хорошее

Можно поддерживать больше меньшими усилиями

Я сильный сторонник разработки через тестирование (test-driven development). Я привык к тестированию в языках наподобие Java и JavaScript. Я начал писать тесты на Rust, как на любом другом языке, но обнаружил, что пишу тесты, которые не могут завершиться ошибкой. Достигнув момента, когда ваши тесты могут выполняться, то есть когда код на Rust компилируется, Rust уже учёл столько ошибок, что стандартные тестовые случаи становятся нерелевантными. Если вы избегаете блоков unsafe {} и подверженных панике методов наподобие .unwrap(), то начинаете с фундамента, который изначально обходит стороной множество проблем.

Агрессивность borrow checker, богатство системы типов, функциональные шаблоны и библиотеки, отсутствие «пустых» значений позволяет поддерживать больше, тратя меньше усилий на вещи наподобие тестирования. В проекте Wick я поддерживал более семидесяти тысяч строк кода с гораздо меньшим количеством тестов, чем мне бы потребовалось в других языках.

Когда необходимо писать тесты, можно легко добавлять их на лету, не задумываясь об этом. Интегрированные средства тестирования Rust позволяют практически без заминок добавлять тесты прямо рядом с кодом.

Теперь я пишу более качественный код на других языках

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

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

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

Что значит “done" не функция? Почему ты мне не сказал, что "done” может не быть функцией??
Что значит “done" не функция? Почему ты мне не сказал, что "done” может не быть функцией??

Clippy великолепен!

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

Стандартная библиотека Rust огромна. В ней сложно находить функции, о существовании которых вы догадываетесь, ведь так много функциональности распределено по множеству несвязанных типов, типажей, макросов и функций. Многие правила Clippy (например, manual_is_ascii_check) ищут распространённые шаблоны, которые лучше заменить методами или типами stdlib.

У Clippy есть сотни правил, касающихся производительности, читаемости и излишних косвенных действий. По возможности он часто подсказывает код на замену.

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

Плохое

Есть пробелы, с которыми придётся жить

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

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

В опенсорсе проблемы пограничных случаев решают или рано влившиеся в проект, или новички. Именно у них возникают пограничные случаи. Их PR совершенствуют проекты, чтобы они были лучше для следующих пользователей. Большую часть десятилетия Rust награждали титулом «самого любимого языка». У него нет проблем с привлечением новых пользователей, но это не приводит к существенному совершенствованию библиотек или инструментов. Это приводит к единичным случаям форков, обрабатывающих конкретные сценарии применения. Я тоже виновен в этом, но не из-за нехватки желания отправлять PR.

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

А может быть, это вызвано тем, что написание кода на Rust, который делает всё для всех, чрезвычайно сложно, и разработчики просто не хотят с этим связываться.

Cargo, crates.io и структурирование проектов

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

При помощи Cargo можно собирать, тестировать и использовать то, что похоже на крейт размером с модуль. Но развёртывание на crates.io — это совсем другое дело.

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

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

Дополнение: Эд Пейдж написал мне, что можно публиковаться с локальными зависимостями этапа разработки, если не включать version в Cargo.toml

Однако Cargo имеет превосходную поддержку рабочих пространств! Рабочие пространства Cargo позволяют удобнее управлять крупными проектами, чем большинство языков. Но они не решают проблему с развёртыванием. Оказалось, что можно настроить рабочие пространства десятком разных способов, но ни один из них не упрощает развёртывание.

Эта проблема проявляет себя самим количеством вспомогательных крейтов, разработанных для упрощения публикации рабочих пространств. Каждый из них работает с подмножеством конфигураций, и «единственно верный способ» настройки рабочих пространств по-прежнему ускользает от меня. При публикации Wick часто требуется больше часа сочетания ручных повторяющихся задач с инструментами, работающими лишь частично.

Async

Асинхронность введена в Rust после его появления. Она ощущается как запоздалое решение и часто становится помехой из-за ошибок, которые трудно понять и устранить. При поиске решений нужно фильтровать информацию в зависимости от сред исполнения и стилей их async. Хотите использовать async-библиотеку? Есть вероятность, что её нельзя использовать за пределами конкретной среды исполнения async.

После двух десятков лет работы с JavaScript и приличного опыта взаимодействия с Go это наиболее существенный источник головной боли в Rust. Это преодолимая проблема, но всегда следует готовиться бороться с чудовищем async, когда оно поднимает свою голову. В других языках async практически невидим.

Ужасное

Рефакторинг может быть сложным

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

Ограничений больше, чем логики
Ограничений больше, чем логики

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

Многократное дублирование простых обобщённых ID.
Многократное дублирование простых обобщённых ID.

Сложно быстро двигаться вперёд, когда для одного шага необходимо изменить 14 разных определений.

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

Вердикт

Я люблю Rust. Мне нравится то, что он может делать, и его гибкость. Я могу писать код системного уровня на том же языке, что и приложения CLI, веб-серверы и веб-клиенты. Благодаря WebAssembly я могу использовать один и тот же двоичный файл для запуска LLM в браузере, что и в командной строке. Это по-прежнему кажется мне невероятным.

Мне нравится, насколько надёжными могут быть программы на Rust. Сложно возвращаться к другим языкам, когда поймёшь, от чего тебя оберегает Rust. Я ненадолго возвращался к Go. Меня снова быстро опьянила скорость разработки. Но потом я столкнулся с паниками среды исполнения, и иллюзии разбились в прах.

Однако у Rust есть свои изъяны. Сложно искать разработчиков на нём, он медленно изучается и слишком строг для быстрых итераций. На нём сложно устранять проблемы с памятью и производительностью, особенно в асинхронном коде. Не все библиотеки хорошо справляются с безопасным кодом, а инструментарий разработки оставляет желать лучшего. Ты начинаешь с запозданием, и тебе приходится преодолевать множество препятствий. Но если ты с ними справишься, то обгонишь всех. И это «если» здесь очень важно.

Оправдал ли себя переход на Rust в нашем случае? Об этом слишком рано говорить. Мы создавали потрясающие вещи небольшой командой, но и сталкивались с серьёзными проблемами. Кроме того, у нас были технические причины для выбора Rust.

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

Комментарии (55)


  1. igorts
    27.10.2023 13:25
    +7

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


  1. i360u
    27.10.2023 13:25
    +6

    Почему ты мне не сказал, что "done” может не быть функцией??

    Так сказал же, буквально, красным по розовому.

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

    А wasm на Rust - это, конечно, здорово, но вот размер сборок... пока эта история точно не про легкий UI и область применения весьма и весьма ограничена очень специфичными задачами.


  1. nin-jin
    27.10.2023 13:25
    +6

    Что значит “done" не функция? Почему ты мне не сказал, что "done” может не быть функцией??

    a few moments later..

    После двух десятков лет работы с JavaScript и приличного опыта взаимодействия с Go это наиболее существенный источник головной боли в Rust. Это преодолимая проблема, но всегда следует готовиться бороться с чудовищем async, когда оно поднимает свою голову. В других языках async практически невидим.


    1. orekh
      27.10.2023 13:25
      +5

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


      1. EragonRussia
        27.10.2023 13:25

        Так неудачно он реализован из-за того, что был выпущен раньше времени под давлением общественности.


        1. Gorthauer87
          27.10.2023 13:25

          Ну вот там конечно если бы сразу были нормальные auto трейты, то можно было бы без этих пинов обойтись, которые мозг ломают.

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


          1. Helltraitor
            27.10.2023 13:25
            +1

            если бы сразу были нормальные auto трейты, то можно было бы без этих пинов обойтись

            Интересно стало, есть ссылки на материалы или поясните, если не сложно?


            1. AnthonyMikh
              27.10.2023 13:25

              Ну вот, например


  1. gmtd
    27.10.2023 13:25
    +10

    Благодаря WebAssembly я могу использовать один и тот же двоичный файл для запуска LLM в браузере, что и в командной строке.

    Когда-то это была коронная фишка Java, но потом она сконцентрировалась на других вещах. Интересно, повторит ли WebAssembly судьбу апплетов


    1. Fell-x27
      27.10.2023 13:25
      +21

      Не повторит, потому что не привязан к языку или платформе. wasm можно хоть на хаскеле пилить.

      Но и надо понимать, что нельзя просто скомпилить и загрузить wasm и получить рабочее приложение 1-в-1 здесь и сейчас.

      Все равно нужно прописывать биндинги и прикручивать JS-обертку для этого всего. Если нужен UI, придётся пилить его отдельно. Тоже html+css+js. Чуда нет. WASM это не про "огосподи, я теперь могу писать код на любом языке, а не только js!", нет, wasm это про "с такой-то матерью и через столько-то боли я смог прикрутить такую-то либу к своему веб-приложению, чтобы взаимодействовать с ней из JS".

      WASM - безусловно крутая штука, но он не очередной флэш или джапплеты. WASM это когда у тебя есть математическая либа на JS, сношающая матрицы за n времени, а ты можешь прикрутить к проекту ее аналог на том же расте, который будет те же матрицы сношать в 30 раз быстрее.

      При этом у WASMа нет доступа к API браузера. Ни к какому. Он не способен заменить JS. Это просто пассивный код, у которого наружу торчат уши. Но он способен улучшить ряд сценариев. Иногда - радикально.


      1. gmtd
        27.10.2023 13:25
        +2

        А, ясно. То есть аналог у Java - это JNI, мост в dll-кам грубо говоря.

        Ну тогда это да, очень специфичный случай. JS на фронте ничего не угрожает


        1. Fell-x27
          27.10.2023 13:25
          +7

          Все так, эта штука дополняет JS, а не заменяет его.


      1. GospodinKolhoznik
        27.10.2023 13:25
        +2

        wasm можно хоть на хаскеле пилить

        Для тех, кто хочет пилить веб приложения на хаскеле есть замечательный purescript. По сути хаскель, который дружит с js библиотеками и транспилируется в js код. Типизация такая строгая, что никакому typescript не снилась. Поэтому лёгкий рефакторинг и высокая надёжность кода. Ещё из плюсов алгебраические типы данных и лаконичный кавайный синтаксис. Ну а ещё, конечно, монады и всякие аппликативные функторы, ну это уже так, на любителя...


        1. MiraclePtr
          27.10.2023 13:25
          +1

          который дружит с js библиотеками и транспилируется в js код.

          У кода на любом языке, скомпилированного в WASM всё-таки эффективность (и в плане размера, и в плане производительности) будет гораздо лучше, чем у того же кода, транспилированного в JS. Для этого WASM, собственно, и придумали - зачем транспилировать код в какой-то промежуточный высокоуровневый язык, который все равно каждый раз будет заново парситься и компилироваться из него на пользовательской машине, если можно компилировать сразу в байт-код?


          1. konsoletyper
            27.10.2023 13:25
            +1

            У кода на любом языке, скомпилированного в WASM всё-таки эффективность
            (и в плане размера, и в плане производительности) будет гораздо лучше,
            чем у того же кода, транспилированного в JS.

            А вот и нет


          1. Gorthauer87
            27.10.2023 13:25
            +1

            Эти то да, но если из васма постоянно js дергать, то оно и будет работать со скоростью этого самого js.


        1. Fell-x27
          27.10.2023 13:25
          +2

          Для тех, кому нужен haskell на клиенте, именно haskell, с его либами, с его софтинами, а не haskell-like язык, раньше существовал проект Asterius, для компиляции оного в wasm как раз. Относительно недавно этот проект переехал прямо в хаскельный GHC и стал нативной частью платформы :)


      1. MiraclePtr
        27.10.2023 13:25
        +5

        Не повторит, потому что не привязан к языку или платформе

        Насколько я помню, веб-апплеты умерли всё-таки не из-за привязки к языку (язык себя отлично чувствует и по сей день) или платформе (у языка с кросс-платформенностью очень хорошо), сколько из-за того что сам механизм NPAPI-плагинов, которые использовали для запуска этих апплетов в браузере, был огромной дырой в плане безопасности и дальше так было нельзя, а всякие костыли для решения этой проблемы (типа песончиц и NaCL) появились гораздо позже


        1. gmtd
          27.10.2023 13:25

          Ну и появление AJAX и web 2.0 сделали свое дело


    1. konsoletyper
      27.10.2023 13:25
      +1

      Думаю, там была проблема не техническая, а политическая. Авторы браузеров не хотели иметь какую-то стороннюю инородную штуковину, которая подключалась через небезопасный API. Авторы браузеров так же не хотели лицензировать Java у Sun/Oracle (чтобы включить эту инородную штуковину прямо в код бразура) и впадать в зависимость. WebAssembly - это что-то схожее, но изобретённое у них, так что нет, не повторит.


      1. Fell-x27
        27.10.2023 13:25
        +1

        Да, там совокупность проблем. И основная как раз - "а на кой ляд нам поддерживать работу хреновины, которуя нам навязывает Оракл, кладя болт на безопасность и забивая на наши требования?"

        А wasm этим по умолчанию не страдает. Переживать за перспнктивы wasm можно так же как ща перспективы indexedDb, например, или webGL. Они уже есть, никому не мешают, кушать не просят.


  1. Apoheliy
    27.10.2023 13:25
    +14

    Пардонь-те, но где вы увидели здесь:

    Системное программирование

    -

    Плюс щепотка сарказма:

    Заголовок статьи:

    Мнение три года спустя: стоил ли того переход с JavaScript на Rust?

    Финал статьи:

    Об этом слишком рано говорить

    В целом, автор подтверждает рейтинг, что Rust - самый "обожаемый" язык. И походу автор подводит к тому, что нужно было оставаться на JavaScript: не такой обожаемый, зато работает.


    1. DarkEld3r
      27.10.2023 13:25

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

      Автор пишет, что у них были "технические причины" выбрать раст. Очень может быть, что в их случае JS как раз не работал.


      1. boldape
        27.10.2023 13:25
        +3

        Технические причины обычно(но не факт что в этом случае тоже) означают, что они пилят крипту, а примерно 146% крипты написано на расте и поэтому ты либо все переписываешь с нуля на жс либо остаёшься в эко системе раста.


  1. JordanCpp
    27.10.2023 13:25
    +5

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

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


  1. JordanCpp
    27.10.2023 13:25
    +5

     На нём сложно устранять проблемы с памятью и производительностью

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


    1. Gorthauer87
      27.10.2023 13:25

      С памятью то как раз легко можно иметь проблемы, сложно получить проблемы с UB


  1. stvoid
    27.10.2023 13:25
    +9

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

    Что стандартные библиотеки на go, что на питоне справлялись с этим отлично.

    Может я конечно не нашел того же в stdlib раста, но 3 года назад я пошел искать библиотеки для этого. И мне кажется я сошел с ума тогда.

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

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

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


    1. stvoid
      27.10.2023 13:25
      +3

      Дополню себя же. Мне кажется, расту нужно ещё 2-3 года, чтобы определились какие-то стандартны для интерфейсов библиотек, линтеров и т.п.

      Пока что это ЯП который очень хорош внутри, но кататься на котором не очень приятно.


      1. lebedec
        27.10.2023 13:25
        +4

        Я так же думал 3 года назад. Воз и ныне там.

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


        1. inv2004
          27.10.2023 13:25

          Поддержу по обоим пунктам.

          • Issue где в async происходил захват данных где его быть не должно - уже 5 лет открытое

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


    1. DarkEld3r
      27.10.2023 13:25
      +1

      Что стандартные библиотеки на go, что на питоне справлялись с этим отлично.

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

      Может я не совсем понял суть претензии, но кажется, что она в большей степени заключается в том, что нужной реализации не нашлось в стандартной библиотеке. Да, есть такое - автор хоть и говорит, что стандартная библиотека огромна, но я бы сказал, что она наоборот минималистична и у этого есть свои преимущества. Скажем, я помню времена когда ещё не было серде и все пользовались другой библитекой (rust-serialize или что-то в таком духе). В общем, на серде перешли не зря и если бы изначальная сериализация была в std, то это было бы печально. И так со многими другими вещами: порой кажется, что это прям совершенно базовая штука, почему бы не предоставлять её из коробки, а потом придумывают что-то получше.

      Возвращаясь к парсингу xml - что удивительного в том, что у разных библиотек разный инферфейс?


      1. stvoid
        27.10.2023 13:25
        +4

        *простите за графоманство, что-то понесло в рассуждения

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

        Возвращаясь к парсингу xml - что удивительного в том, что у разных библиотек разный инферфейс?

        Тут скорее вопрос не в удивительности, а в интуитивности, что ли. Например реализации библиотек json в питоне или go так или иначе имеют единый интерфейс, ну или на 99% совместимый. Вспоминается разве что orjson питоновский, и то только тем что он не работает со строками, что объяснено и оправдано, да и не вносит серьезных прям изменений в интерфейс, т.е. можно адаптироваться.

        Тут опять же - субъективный опыт, не охота тыкать прям в библиотеки которые я пробовал (сейчас и не вспомню точно, брал просто что-то из топа), но каждая из них реализует что-то сильно по своему. Но в моем конкретном случае нужен был потоковый парсинг, и все возможные реализации прекрасно работают когда речь идет о некой целой структуре/классе в который надо распарсить данные полностью, но если это что-то большое, что нужно парсить частично, проверяя каждое поле/значение в процессе чтения, то это становилось болезненно. Хотя казалось бы, я прошу просто хорошо написанный токенизатор, который будет мне возвращать корректно открытие/закрытие тэгов и что там внутри него навалено.

        И как бы вроде бы, сам виноват что полез в этом спустя 1-2 недели щупанья раста, но что-то слишком неудобный велосипед пока что. Типа, у меня нет предпочтений ЯП, т.к. банально приходится писать и на js (фронт и бэк), на go, python, иногда тыкать палкой в php и раст в это семейство я рассматриваю как один из инструментов для каких-то супер нагруженных задач, где мне и память беречь надо и скорость иметь, но например я могу пожертвовать сложностью и временем разработки/поддержки. Пока что я не вижу удобной и комфортной экосистемы вокруг раста, но вижу сам по себе хороший инструмент.

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

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


        1. DarkEld3r
          27.10.2023 13:25
          +1

          Да, скорее озадачивает отсутствие каких-то казалось бы базовых вещей в стандартной библиотеке.

          Для языка "общего назначения" базовые вещи - это понятие очень растяжимое. С одной стороны, удобно когда не надо искать и выбирать зависимости. С другой - у джавы так в стандарной библиотеке появились AWT и Swing, которыми, насколько я знаю, не то чтобы сильно пользуются. Опять же, когда зависимость подключается в одну строчку, то не такая это и проблема.

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

          Про разнородный интерфейс библиотек сложно рассуждать без примеров. Лично мне кажется, что штуки претендующие на фреймворки действительно могут вызывать подобные ощущения, но разве это не везде так?.. А с "обычными" библиотеками такого не замечал.


          1. lebedec
            27.10.2023 13:25
            +1

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

            Проблема серьёзнее чем кажется.

            Как только ваши требования становятся чуть кастомнее чем использование одного Rust фреймворка, проблема зависимостей становится явной:

            • статическая типизация

            • трейты для чужих структур реализовывать нельзя

            • банально конфликт общих зависимостей

            Например, мы хотим сделать геоинформационный сервис. Для этого нам понадобятся библиотеки для работы с пространственными данными, геокодированием, JSON.

            Всё перечисленные библиотеки будут работать по отдельности, но не вместе. Чтобы их использовать придется написать кучу обёрток, адаптеров, маперов. Не факт, что это реализуемо в принципе.

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

            Можно подсмотреть как это сделано, например, в мире C#. Там в стандартной библиотеке есть интерфейсы для системных и базовых вещей. Основные вендоры типа Microsoft так же поставляют набор интерфейсов, но уже на пользовательском уровне. Сторонний разработчик может реализовать эти интерфейсы, это даёт его работе большую популярность, а сообщество взамен получает интегрируемое решение.

            В Rust сейчас некоторые разработчики стараются выпускать набор интерфейсов для той области в которой работают. Но это не помогает, я думаю просто из-за человеческого фактора. Кто будет слушать каких-то там ноунеймов? Кажется что Rust очень нужен сильный покровитель, крупный вендор, на авторитет которого массовый разработчик будет реагировать, по аналогии с Microsoft или Google.


            1. Gorthauer87
              27.10.2023 13:25

              Ну как это не работает, вот есть log, есть embedded-hal. Оно не работает в общем виде, но можно договариваться на уровне какой-то предметной области


        1. Gorthauer87
          27.10.2023 13:25
          +2

          Скорее всего, проблема в том, что xml Rust программистам просто нафиг не сдался и делается он как попало, с более популярными форматами все куда более хорошо и понятно.

          А xml старый, сложный и используется больше в энтерпрайзе, где Rust не особенно то и жалуют.


        1. hapcode
          27.10.2023 13:25
          +4

          Странно. Возможно вы не нашли quick-xml. Недавно частично разбирал FB2 и никаких проблем с этим не было. Правда я толком не помню, как оно там в python или java разбирается, но должно быть похоже. Те же самые открытые-закрытые тэги в потоке событий.


          1. stvoid
            27.10.2023 13:25

            Точно не находил эту библиотеку, скорее всего ее и не было нигде в поиске, т.к. судя по репозиторию первый релиз был в конце 22 года.
            Вот тут да, сходу в примере чтения виден прекрасный интерфейс бесконечного цикла для потокового чтения.

            Спасибо большое, поставил звездочку, точно пригодится.


            1. V1tol
              27.10.2023 13:25
              +3

              quick-xml только в тегах на гитхабе существует с 2016 года, а на crates.io версии публиковались и того раньше. Или можно было взять xml-rs, который медленнее и не поддерживает асинхронщину, но появился даже ещё раньше.

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


            1. Mingun
              27.10.2023 13:25

              Первый релиз на GitHub-е был примерно тогда, так как люди попросили делать релизы; некоторые только на эти события подписаны. А так-то библиотека давняя и когда я пришел в проект, она уже была на 1-2 месте по популярности.


    1. WASD1
      27.10.2023 13:25

      Ну это же вопрос "как выбрать библиотеку для Х, если этого нет в стандартной библиотеке".

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

      Завтра захочу найти библиотеку, ну не знаю для парсинга plain-text (вроде в стандартной библиотеке такого нет). Как мне найти правильную библиотеку на Python для этого?


      1. ebt
        27.10.2023 13:25
        +1

        С академической точки зрения, парсинг даже для controlled language не самая лёгкая задача. Например, lark даст вам настраиваемые лексеры и грамматики, зато pyparsing легче отлаживать. А если речь об NLP, то вам, скорее всего, в первую очередь понадобится соответствующее железо и DL-стек — и это уже не совсем про Python.


        1. WASD1
          27.10.2023 13:25
          +2

          Я, наверное, неудачно выразился и взял слишком сложную задачу (т.е. мой запрос несравнимо сложнее чем "парсинг xml").

          Вот смотрите@stvoid жалуется, что не может выбрать правильную библиотеку на Rust (не обладая достаточным опытом).
          Но это же не Rust-специфичная проблема. Пока не набрался опыта - подобрать правильную библиотеку одна из самых больших проблем в языке вообще.

          Вот я, например, не обладаю опытом в Python, как мне выбрать библиотеку на Python (если в stdlib нет соответствующей библиотеке - тогда боле-менее понятно).


  1. pavelsc
    27.10.2023 13:25
    -4

    Очень хитрый ход, разве чтоб рабочее место себе застолбить ))

    Мощно, конечно, восхвалять язык за его негибкость, вместо того чтобы повышать свою компетенцию в написании кода на другом языке. Как-то странно, когда чел, написавший книгу (sic!), учится базовым принципам программирования от линтера. С другой стороны сейчас модно выпячивать своё невежество, но, имхо, в профессиональной среде такие каминг ауты некомильфо.


  1. Dominux
    27.10.2023 13:25

    Данные и сигнатуры функций могут иметь обобщённые типы, обобщённое время жизни и ограничения типажей

    Автор не знал про type aliases, далеко пойдет

    С тех пор мы с ещё несколькими потрясающими разработчиками создали Wick, — фреймворк приложений и среду исполнения

    Типичный джавасриптизер. Во времена существования leptos и прочих топовых аналогов, они создают что-то своё, корявое. А потом просто всё валят на язык, мол язык виноват, что он , например, не знал о type aliases


    1. Sulerad
      27.10.2023 13:25
      +3

      Автор не знал про type aliases, далеко пойдет

      Каждый impl в любом случае должен перечислить все дженерики и ограничения на них. Здесь нужны trait aliases, но они так и не стабилизированы.

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


      1. Gorthauer87
        27.10.2023 13:25
        +3

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


  1. Zara6502
    27.10.2023 13:25

    Я могу писать код системного уровня на том же языке, что и приложения CLI, веб-серверы и веб-клиенты

    а как там дела у старичка Perl? В 90-е и немного в нулевые пересекался с ним на линуксе, довольно классная штука.


    1. gatoazul
      27.10.2023 13:25
      +2

      Все в порядке. Жив и отлично трудится. Понемногу обрастает новыми модными фичами.


  1. alexdora
    27.10.2023 13:25
    +1

    Там кинули "какульку" в Go. Что какие-то паники среды и бла-бла-бла. Разрабатываю довольно высоконагруженныe ассинхронные приложения на нем, со сложными структурами. У меня таких проблем нет. Есть нюансы, есть где подумать…много иногда кода приходится писать лишнего…но чтоб так…не, такого нет.

    из всех проблем Go которые мне не нравится - бинарные деревья. Они очень медленные по скорости. В моих приложениях нужна именно скорость исполнения и это то что печалит. Но от версии к версии становится быстрее. За последние 2 года они ускорились процентов на 20-30. Но не дотчгивают до раста и c++. поэтому пришлось немного подпрыгнуть и придумать обход этого узкого места.

    ПС: прошел год, я не увидел (но и не сильно и пытался увидеть) статью где показан пример работы на Rust после которой сидишь и думаешь: «ну, да…на go сделать такое сложно или невозможно, или будет крайне медленно»

    Да, знаю что некоторые блоки у различных корпораций переписаны на Rust (тот же Cloudflare), но это не является причиной для того чтобы бежать его и учить. И всегда может возникнуть вопрос: А может C++...специалистов, фреймворков и прочего для него как грязи.


  1. Dr9vik
    27.10.2023 13:25
    -6

    "Несколько лет назад я отказался от всего и полностью сосредоточился на WebAssembly. В то время Rust имел наилучшую поддержку компиляции в WebAssembly "

    а майкрософт с его C# и Blazor вкурсах?


    1. AnthonyMikh
      27.10.2023 13:25
      +1

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


    1. onikiychuka
      27.10.2023 13:25

      Вкурсах. По этому пытаются перевести Blazor под wasm-unknown toolchain (через WASI-Libc) вместо emscripten. Только вот проект очень медленно стоит на месте. Emscripten - это 18й век, который нужен что-бы запускать сужествующие С приложения на wasm без особых изменений. Wasm-unknown - куда более нативный и быстрый. Ну и основная часть работы над wasm вне браузера (WASI) ведется как раз на Rust. Так что выбор очевиден. Для браузерных API поддержка в Rust тоже прекрасна.


  1. koshkoshka2
    27.10.2023 13:25
    -4

    Чем вам так не угодил php и js? Это же самые простые языки программирования. Специально создают сложные языки?