Комментарии 64
Если стать на сторону работодателя или заказчика, то в приоритете выбор за популярными языками и платформами, а разработчикам всегда интересно попробовать чтото новое.
Почему ты мне не сказал, что "
done”
может не быть функцией??
Так сказал же, буквально, красным по розовому.
В этом конкретном примере, во весь рост становится философская проблема натягивания "совы на глобус" - ожидание каких-то паттернов поведения, неестественных для скриптового языка, в случаях, когда наиболее применимы принципы хаос-инжиниринга. Просто поменяйте в своей ментальной модели в голове местами элементы цикла разработки, деплой и компиляцию, и это перестанет вас так раздражать. Ну и статический анализ с JS никто не отменял, есть же "взрослые" практики, типа использования TypeScript.
А wasm на Rust - это, конечно, здорово, но вот размер сборок... пока эта история точно не про легкий UI и область применения весьма и весьма ограничена очень специфичными задачами.
Что значит “done" не функция? Почему ты мне не сказал, что "done” может не быть функцией??
a few moments later..
После двух десятков лет работы с JavaScript и приличного опыта взаимодействия с Go это наиболее существенный источник головной боли в Rust. Это преодолимая проблема, но всегда следует готовиться бороться с чудовищем async, когда оно поднимает свою голову. В других языках async практически невидим.
Не понимаю, что вы пытаетесь набросить? Автор често говорит о пробемах языков. То что асинк в расте реализован очень неудачно (что поразительно, учитывая что язык кажется буквально созданным для асинхронщины), не отменяет обнаружения ошибок во время исполнения в яваскрипте.
Так неудачно он реализован из-за того, что был выпущен раньше времени под давлением общественности.
Ну вот там конечно если бы сразу были нормальные auto трейты, то можно было бы без этих пинов обойтись, которые мозг ломают.
Плюс async в трейтах сколько усилий потребовал, почти 5 лет понадобилось, чтобы под него допилить систему типов.
если бы сразу были нормальные auto трейты, то можно было бы без этих пинов обойтись
Интересно стало, есть ссылки на материалы или поясните, если не сложно?
Ну вот, например
А как auto traits помогут от пинов?
Upd: увидел ссылку сверху, но всё равно не понял. Автор там мечтает о Move
вместо Pin
, но я не понимаю как это будет работать в async.
Pin в async нужен пока структура, содержащая конечный автомат async функции находится в одном из промежуточных состояний. Грубо говоря, между первым и последним poll. В остальное время её можно гонять по памяти как угодно. В существующем API я могу навесить Pin на эту структуру когда мне это надо. Как бы это могло выглядеть с Move
? Предлагаемое там решение: "взятие mutable reference передаёт ещё и владение", но это же противоречие: reference я взял на две строчки и выкинул, кто теперь владеет этим значением? Выглядит не очень продуманным.
Благодаря WebAssembly я могу использовать один и тот же двоичный файл для запуска LLM в браузере, что и в командной строке.
Когда-то это была коронная фишка Java, но потом она сконцентрировалась на других вещах. Интересно, повторит ли WebAssembly судьбу апплетов
Не повторит, потому что не привязан к языку или платформе. wasm можно хоть на хаскеле пилить.
Но и надо понимать, что нельзя просто скомпилить и загрузить wasm и получить рабочее приложение 1-в-1 здесь и сейчас.
Все равно нужно прописывать биндинги и прикручивать JS-обертку для этого всего. Если нужен UI, придётся пилить его отдельно. Тоже html+css+js. Чуда нет. WASM это не про "огосподи, я теперь могу писать код на любом языке, а не только js!", нет, wasm это про "с такой-то матерью и через столько-то боли я смог прикрутить такую-то либу к своему веб-приложению, чтобы взаимодействовать с ней из JS".
WASM - безусловно крутая штука, но он не очередной флэш или джапплеты. WASM это когда у тебя есть математическая либа на JS, сношающая матрицы за n времени, а ты можешь прикрутить к проекту ее аналог на том же расте, который будет те же матрицы сношать в 30 раз быстрее.
При этом у WASMа нет доступа к API браузера. Ни к какому. Он не способен заменить JS. Это просто пассивный код, у которого наружу торчат уши. Но он способен улучшить ряд сценариев. Иногда - радикально.
А, ясно. То есть аналог у Java - это JNI, мост в dll-кам грубо говоря.
Ну тогда это да, очень специфичный случай. JS на фронте ничего не угрожает
wasm можно хоть на хаскеле пилить
Для тех, кто хочет пилить веб приложения на хаскеле есть замечательный purescript. По сути хаскель, который дружит с js библиотеками и транспилируется в js код. Типизация такая строгая, что никакому typescript не снилась. Поэтому лёгкий рефакторинг и высокая надёжность кода. Ещё из плюсов алгебраические типы данных и лаконичный кавайный синтаксис. Ну а ещё, конечно, монады и всякие аппликативные функторы, ну это уже так, на любителя...
Для тех, кому нужен haskell на клиенте, именно haskell, с его либами, с его софтинами, а не haskell-like язык, раньше существовал проект Asterius, для компиляции оного в wasm как раз. Относительно недавно этот проект переехал прямо в хаскельный GHC и стал нативной частью платформы :)
WASM это когда у тебя есть математическая либа на JS, сношающая матрицы за n времени, а ты можешь прикрутить к проекту ее аналог на том же расте, который будет те же матрицы сношать в 30 раз быстрее.
А вот и не только! WASM это еще и кросс-платформенные бинарники, например, для контейнеров (как только стандартизуют системные вызовы для них). Как Java, только быстрее и пишется на любом языке. И запускается хоть на арме, хоть на мипсе, хоть на x86.
Думаю, там была проблема не техническая, а политическая. Авторы браузеров не хотели иметь какую-то стороннюю инородную штуковину, которая подключалась через небезопасный API. Авторы браузеров так же не хотели лицензировать Java у Sun/Oracle (чтобы включить эту инородную штуковину прямо в код бразура) и впадать в зависимость. WebAssembly - это что-то схожее, но изобретённое у них, так что нет, не повторит.
Да, там совокупность проблем. И основная как раз - "а на кой ляд нам поддерживать работу хреновины, которуя нам навязывает Оракл, кладя болт на безопасность и забивая на наши требования?"
А wasm этим по умолчанию не страдает. Переживать за перспнктивы wasm можно так же как ща перспективы indexedDb, например, или webGL. Они уже есть, никому не мешают, кушать не просят.
Пардонь-те, но где вы увидели здесь:
Системное программирование
-
Плюс щепотка сарказма:
Заголовок статьи:
Мнение три года спустя: стоил ли того переход с JavaScript на Rust?
Финал статьи:
Об этом слишком рано говорить
В целом, автор подтверждает рейтинг, что Rust - самый "обожаемый" язык. И походу автор подводит к тому, что нужно было оставаться на JavaScript: не такой обожаемый, зато работает.
И походу автор подводит к тому, что нужно было оставаться на JavaScript: не такой обожаемый, зато работает.
Автор пишет, что у них были "технические причины" выбрать раст. Очень может быть, что в их случае JS как раз не работал.
Теперь я не могу писать код на других языках без ощущения дискомфорта, если строки находятся в беспорядке или когда возвращаемые значения не проверяются.
А если содержать строки в порядке и проверять возвращаемое значение?
На нём сложно устранять проблемы с памятью и производительностью
Расскажите плиз, пару случаев. Адепты же только и говорят, что проблем с памятью нет, а вы нагло смели утверждать обратное:)
Вспоминается мне, когда я сел пробовать Раст, переписывая на него маленькие кусочки важные мне с проектов на питоне, горшке, то столкнулся с какой то дичью. А именно - нужен был потоковый парсинг xml, очень много, вычитывать все файлы в память очень затратно.
Что стандартные библиотеки на go, что на питоне справлялись с этим отлично.
Может я конечно не нашел того же в stdlib раста, но 3 года назад я пошел искать библиотеки для этого. И мне кажется я сошел с ума тогда.
Каждый реализует этот парсинг по своему, кто то даёт возможность вернуть токен, кто то нет, вот тут скопируйте-перекопируй, тут не используй указатель, а тут возвращай копию того что ты ожидал.
В общем, я понимаю что "растовчане" могут по делу напихать мне, но честно говоря экосистема раста меня до сих пор отталкивает.
Он правда что прекрасен, когда пишешь что-то, что не требует использования чужих реализаций. Но отсутствие какого-то единого стиля очень сильно отталкивает.
Дополню себя же. Мне кажется, расту нужно ещё 2-3 года, чтобы определились какие-то стандартны для интерфейсов библиотек, линтеров и т.п.
Пока что это ЯП который очень хорош внутри, но кататься на котором не очень приятно.
Я так же думал 3 года назад. Воз и ныне там.
Ситуацию осложняет сила и изобразительность макросов. Ладно интерфейс, некоторые библиотеки приносят буквально свои DSL, правила мета программирования и прочие прелести кодогенерации.
Поддержу по обоим пунктам.
Issue где в async происходил захват данных где его быть не должно - уже 5 лет открытое
Надо просто поработать с аргументами командной строки - надо обмазаться макросами clap чтобы это хоть как-то адекватно выглядело
Что стандартные библиотеки на go, что на питоне справлялись с этим отлично.
Он правда что прекрасен, когда пишешь что-то, что не требует использования чужих реализаций. Но отсутствие какого-то единого стиля очень сильно отталкивает.
Может я не совсем понял суть претензии, но кажется, что она в большей степени заключается в том, что нужной реализации не нашлось в стандартной библиотеке. Да, есть такое - автор хоть и говорит, что стандартная библиотека огромна, но я бы сказал, что она наоборот минималистична и у этого есть свои преимущества. Скажем, я помню времена когда ещё не было серде и все пользовались другой библитекой (rust-serialize
или что-то в таком духе). В общем, на серде перешли не зря и если бы изначальная сериализация была в std
, то это было бы печально. И так со многими другими вещами: порой кажется, что это прям совершенно базовая штука, почему бы не предоставлять её из коробки, а потом придумывают что-то получше.
Возвращаясь к парсингу xml - что удивительного в том, что у разных библиотек разный инферфейс?
*простите за графоманство, что-то понесло в рассуждения
Да, скорее озадачивает отсутствие каких-то казалось бы базовых вещей в стандартной библиотеке. Не настаиваю на своей позиции, но мне кажется, когда стандартная библиотека задает определенный стиль/интерфейс, то сторонние реализации получаются как-то совместимее/удобнее, что ли.
Возвращаясь к парсингу xml - что удивительного в том, что у разных библиотек разный инферфейс?
Тут скорее вопрос не в удивительности, а в интуитивности, что ли. Например реализации библиотек json в питоне или go так или иначе имеют единый интерфейс, ну или на 99% совместимый. Вспоминается разве что orjson питоновский, и то только тем что он не работает со строками, что объяснено и оправдано, да и не вносит серьезных прям изменений в интерфейс, т.е. можно адаптироваться.
Тут опять же - субъективный опыт, не охота тыкать прям в библиотеки которые я пробовал (сейчас и не вспомню точно, брал просто что-то из топа), но каждая из них реализует что-то сильно по своему. Но в моем конкретном случае нужен был потоковый парсинг, и все возможные реализации прекрасно работают когда речь идет о некой целой структуре/классе в который надо распарсить данные полностью, но если это что-то большое, что нужно парсить частично, проверяя каждое поле/значение в процессе чтения, то это становилось болезненно. Хотя казалось бы, я прошу просто хорошо написанный токенизатор, который будет мне возвращать корректно открытие/закрытие тэгов и что там внутри него навалено.
И как бы вроде бы, сам виноват что полез в этом спустя 1-2 недели щупанья раста, но что-то слишком неудобный велосипед пока что. Типа, у меня нет предпочтений ЯП, т.к. банально приходится писать и на js (фронт и бэк), на go, python, иногда тыкать палкой в php и раст в это семейство я рассматриваю как один из инструментов для каких-то супер нагруженных задач, где мне и память беречь надо и скорость иметь, но например я могу пожертвовать сложностью и временем разработки/поддержки. Пока что я не вижу удобной и комфортной экосистемы вокруг раста, но вижу сам по себе хороший инструмент.
Ну и да, тут конечно не сравнимые вещи, но слишком похожие в плане запуска потоков, асинхронности с питоном. Не знаю как у кого, а у меня после go это вот всё вызывает чувство духоты - спавним потоки, джойним, а еще не забываем обернуть и обмазать что-то что мы шарим по потокам и вот это всё... ууух... Но это ладно, это go так избаловывает.
Если мы начнем воспринимать программирование как ремесло, а ЯПы как инструменты, то сильно проще оценивать всё это. Да, есть действительно мощные вещи, но вряд ли вы будете прибивать картину на стену кувалдой или резать колбасу бензопилой, ровно как и копать грядки ложкой сомнительное времяпрепровождение.
Да, скорее озадачивает отсутствие каких-то казалось бы базовых вещей в стандартной библиотеке.
Для языка "общего назначения" базовые вещи - это понятие очень растяжимое. С одной стороны, удобно когда не надо искать и выбирать зависимости. С другой - у джавы так в стандарной библиотеке появились AWT и Swing, которыми, насколько я знаю, не то чтобы сильно пользуются. Опять же, когда зависимость подключается в одну строчку, то не такая это и проблема.
Кстати, про xml - мне этот формат парсить на расте приходилось пять лет назад и тогда ситуация с библиотеками действительно была печальная. С тех пор не требовалось, так что не могу сказать стало ли лучше.
Про разнородный интерфейс библиотек сложно рассуждать без примеров. Лично мне кажется, что штуки претендующие на фреймворки действительно могут вызывать подобные ощущения, но разве это не везде так?.. А с "обычными" библиотеками такого не замечал.
Опять же, когда зависимость подключается в одну строчку, то не такая это и проблема.
Проблема серьёзнее чем кажется.
Как только ваши требования становятся чуть кастомнее чем использование одного Rust фреймворка, проблема зависимостей становится явной:
статическая типизация
трейты для чужих структур реализовывать нельзя
банально конфликт общих зависимостей
Например, мы хотим сделать геоинформационный сервис. Для этого нам понадобятся библиотеки для работы с пространственными данными, геокодированием, JSON.
Всё перечисленные библиотеки будут работать по отдельности, но не вместе. Чтобы их использовать придется написать кучу обёрток, адаптеров, маперов. Не факт, что это реализуемо в принципе.
Но не нужно тащить всё в стандартную библиотеку, это наносит прямой ущерб портируемости языка.
Можно подсмотреть как это сделано, например, в мире C#. Там в стандартной библиотеке есть интерфейсы для системных и базовых вещей. Основные вендоры типа Microsoft так же поставляют набор интерфейсов, но уже на пользовательском уровне. Сторонний разработчик может реализовать эти интерфейсы, это даёт его работе большую популярность, а сообщество взамен получает интегрируемое решение.
В Rust сейчас некоторые разработчики стараются выпускать набор интерфейсов для той области в которой работают. Но это не помогает, я думаю просто из-за человеческого фактора. Кто будет слушать каких-то там ноунеймов? Кажется что Rust очень нужен сильный покровитель, крупный вендор, на авторитет которого массовый разработчик будет реагировать, по аналогии с Microsoft или Google.
Ну как это не работает, вот есть log, есть embedded-hal. Оно не работает в общем виде, но можно договариваться на уровне какой-то предметной области
статическая типизация
Так это плюс, а не минус.
трейты для чужих структур реализовывать нельзя
Чужие трейты. И то если очень хочется, то через враппер можно. Да, неприятно и некрасиво, но можно.
Можно подсмотреть как это сделано, например, в мире C#.
Так в расте тоже пытаются. Скажем, дофига усилий ушло (и продолжает идти) на то чтобы асинхронный рантайм/экзекьютор мог быть внешним и подменяемым. Просто команда у языка не такая большая и ресурсы ограничены, заниматься всеми вопросами сразу никак не получится. Да, если завалить из деньгами, то станет лучше. И то с нюансами. Скажем, за С++ стоит много корпораций с деньгами, но (или скорее именно по этой причине) договориться им бывает непросто. Если же контроль над языком у какой-то одной корпорации, то совсем не факт, что это хорошо, особенно если рассматривать не сиюминутную пользу, а промежуток хотя бы в 5-10 лет.
Скорее всего, проблема в том, что xml Rust программистам просто нафиг не сдался и делается он как попало, с более популярными форматами все куда более хорошо и понятно.
А xml старый, сложный и используется больше в энтерпрайзе, где Rust не особенно то и жалуют.
Точно не находил эту библиотеку, скорее всего ее и не было нигде в поиске, т.к. судя по репозиторию первый релиз был в конце 22 года.
Вот тут да, сходу в примере чтения виден прекрасный интерфейс бесконечного цикла для потокового чтения.
Спасибо большое, поставил звездочку, точно пригодится.
quick-xml только в тегах на гитхабе существует с 2016 года, а на crates.io версии публиковались и того раньше. Или можно было взять xml-rs, который медленнее и не поддерживает асинхронщину, но появился даже ещё раньше.
Мой личный фаворит на случай если не нужно парсить XML из неизвестных источников это xmlparser. Имеет много ограничений, но благодаря архитектуре можно использовать как в синхронном, так и в асинхронном коде.
Первый релиз на GitHub-е был примерно тогда, так как люди попросили делать релизы; некоторые только на эти события подписаны. А так-то библиотека давняя и когда я пришел в проект, она уже была на 1-2 месте по популярности.
Ну это же вопрос "как выбрать библиотеку для Х, если этого нет в стандартной библиотеке".
Вот я плохо знаю инфраструктуру Python (использую, конечно, его как клей или мелкие сервисы на работе).
Завтра захочу найти библиотеку, ну не знаю для парсинга plain-text (вроде в стандартной библиотеке такого нет). Как мне найти правильную библиотеку на Python для этого?
С академической точки зрения, парсинг даже для controlled language не самая лёгкая задача. Например, lark
даст вам настраиваемые лексеры и грамматики, зато pyparsing
легче отлаживать. А если речь об NLP, то вам, скорее всего, в первую очередь понадобится соответствующее железо и DL-стек — и это уже не совсем про Python.
Я, наверное, неудачно выразился и взял слишком сложную задачу (т.е. мой запрос несравнимо сложнее чем "парсинг xml").
Вот смотрите@stvoid жалуется, что не может выбрать правильную библиотеку на Rust (не обладая достаточным опытом).
Но это же не Rust-специфичная проблема. Пока не набрался опыта - подобрать правильную библиотеку одна из самых больших проблем в языке вообще.
Вот я, например, не обладаю опытом в Python, как мне выбрать библиотеку на Python (если в stdlib нет соответствующей библиотеке - тогда боле-менее понятно).
Очень хитрый ход, разве чтоб рабочее место себе застолбить ))
Мощно, конечно, восхвалять язык за его негибкость, вместо того чтобы повышать свою компетенцию в написании кода на другом языке. Как-то странно, когда чел, написавший книгу (sic!), учится базовым принципам программирования от линтера. С другой стороны сейчас модно выпячивать своё невежество, но, имхо, в профессиональной среде такие каминг ауты некомильфо.
Данные и сигнатуры функций могут иметь обобщённые типы, обобщённое время жизни и ограничения типажей
Автор не знал про type aliases, далеко пойдет
С тех пор мы с ещё несколькими потрясающими разработчиками создали Wick, — фреймворк приложений и среду исполнения
Типичный джавасриптизер. Во времена существования leptos и прочих топовых аналогов, они создают что-то своё, корявое. А потом просто всё валят на язык, мол язык виноват, что он , например, не знал о type aliases
Автор не знал про type aliases, далеко пойдет
Каждый impl в любом случае должен перечислить все дженерики и ограничения на них. Здесь нужны trait aliases, но они так и не стабилизированы.
Боль автора очень понимаю, особенно если вдруг показалось красивым запихать в поле структурки какой-нибудь associated type — тогда копипастить придётся совершенно безальтернативно.
Вообще, в целом альясы трейтов можно накостылить, но надо просто понимать, что когда портянки where становятся очень длинными, то значит где-то перемудрил со связностью кода.
но надо просто понимать, что когда портянки where становятся очень длинными, то значит где-то перемудрил со связностью кода.
Да вот нет. Или простейшая конвертация данных между потоками это что-то "перемудренное"?
pub struct StreamConverter<St, A, E1, Si, B, E2, F>
where
St: Stream<Item = Result<A, E1>> + Unpin + Send,
A: Debug + Send,
E1: Error + Send,
Si: Sink<B, Error = E2> + Send + Unpin,
B: Debug + Send,
E2: Error + Send,
F: Fn(A) -> B + Send + Sync,
{
stream: St,
sink: Si,
adapter: F
}
Я могу писать код системного уровня на том же языке, что и приложения CLI, веб-серверы и веб-клиенты
а как там дела у старичка Perl? В 90-е и немного в нулевые пересекался с ним на линуксе, довольно классная штука.
Там кинули "какульку" в Go. Что какие-то паники среды и бла-бла-бла. Разрабатываю довольно высоконагруженныe ассинхронные приложения на нем, со сложными структурами. У меня таких проблем нет. Есть нюансы, есть где подумать…много иногда кода приходится писать лишнего…но чтоб так…не, такого нет.
из всех проблем Go которые мне не нравится - бинарные деревья. Они очень медленные по скорости. В моих приложениях нужна именно скорость исполнения и это то что печалит. Но от версии к версии становится быстрее. За последние 2 года они ускорились процентов на 20-30. Но не дотчгивают до раста и c++. поэтому пришлось немного подпрыгнуть и придумать обход этого узкого места.
ПС: прошел год, я не увидел (но и не сильно и пытался увидеть) статью где показан пример работы на Rust после которой сидишь и думаешь: «ну, да…на go сделать такое сложно или невозможно, или будет крайне медленно»
Да, знаю что некоторые блоки у различных корпораций переписаны на Rust (тот же Cloudflare), но это не является причиной для того чтобы бежать его и учить. И всегда может возникнуть вопрос: А может C++...специалистов, фреймворков и прочего для него как грязи.
"Несколько лет назад я отказался от всего и полностью сосредоточился на WebAssembly. В то время Rust имел наилучшую поддержку компиляции в WebAssembly "
а майкрософт с его C# и Blazor вкурсах?
В Webassembly нет нативной поддержки сборки мусора, поэтому Blazor вынужден помимо кода приложения компилировать в блоб и весь .NET рантайм. То есть по сути интерпретатор запускает интерпретатор. Так что оно в принципе особо производительным не будет.
Вкурсах. По этому пытаются перевести Blazor под wasm-unknown toolchain (через WASI-Libc) вместо emscripten. Только вот проект очень медленно стоит на месте. Emscripten - это 18й век, который нужен что-бы запускать сужествующие С приложения на wasm без особых изменений. Wasm-unknown - куда более нативный и быстрый. Ну и основная часть работы над wasm вне браузера (WASI) ведется как раз на Rust. Так что выбор очевиден. Для браузерных API поддержка в Rust тоже прекрасна.
Чем вам так не угодил php и js? Это же самые простые языки программирования. Специально создают сложные языки?
Мнение три года спустя: стоил ли того переход с JavaScript на Rust?