LINUX.ORG.RU

Чисто технические причины НЕ любить Rust [holywar mode activated]

 , ,


3

9

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

Ответ на: комментарий от anonymous

Затем, чтобы, получив запрос из всего такого замечательного асинхронного io, вчерашние пэхэпэшники могли продолжать выполнять блокирующие запросы к базе и другим сервисам как в старые добрые времена и ни о чем не думать

anonymous ()
Ответ на: комментарий от hateyoufeel

тормоза Snap не доказывают тормознутости green threads
тормоза Go не доказывают тормознутости green threads
тормоза Yesod не доказывают тормознутости green threads

Да я смотрю, тебя ничем не взять.

anonymous ()
Ответ на: комментарий от anonymous

Ну вообще грин трэды - это обычно просто лямбдочки, которые выгребаются из очереди и выполняются на нитке ОС. В Haskell/Go немного не так, но смысл такой же. Там физически нечему тормозить как бы. А Erlang тормозной, да, просто потому что он интерпретируемый.

afiskon ()

Напишите в комментариях свою версию этих пунктов, а потом сравним.

У меня есть некоторое количество «претензий» к языку, но их можно на три категории разделить:

1. «Непривычно» (ака «синдром утёнка»). Скажем, мне хотелось бы видеть в языке исключения и перегрузку функций. Вот только есть языки, которые без этого отлично живут, так что это не может быть фатальным недостатком. Хотя исключения, пусть и когда-то потом получить хотелось бы.

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

3. Реально раздражающие вещи. По моему, их не так уж много. Тоже пару раз брался выписывать их, но благополучно потерял список. Навскидку: отсутствие неймспейсов для макросов (опять же, бегло читать макросы я так и не научился, хотя может мало «старался»), «дурацкие» ограничения на реализацию трейтов (нельзя реализовывать «чужие» трейты для «чужих» типов). Последнее правда обходится и не так уж сложно, да и может «в реальном коде» проблемой не будет. Макросами, опять же, особо активно не пользовался (ну кроме стандартных), так что не могу сказать насколько отсутствие нейспейсов будет мешаться. Но это точно «некрасиво» - так макросы выглядят инородно, а не как часть языка. Ну и синтаксис дженериков местами корявый.

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

DarkEld3r ★★★★★ ()
Последнее исправление: DarkEld3r (всего исправлений: 2)
Ответ на: комментарий от Legioner

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

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

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

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

это умеют макросы. посмотри, например, как vec! реализован

перегрузку функций

есть перегрузка дженериками и/или трейтами. считается, что этого достаточно

нельзя реализовывать «чужие» трейты для «чужих» типов

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

MyTrooName ★★★★★ ()
Ответ на: комментарий от afiskon

Есть истории успеха с по процессу на пользователя, кроме Эрланга?

zz ★★★★ ()
Ответ на: комментарий от tailgunner

Суть проблемы: https://github.com/rust-lang/rust/issues/24456

Хитро составленный цикл из RC-указателей не освобождается никогда, приводя к утечки памяти в safe-коде. Получается, GC-free memory safety не будет, посаны, расходимся, нас опять нае*али.

anonymous ()
Ответ на: комментарий от anonymous

Я знаю, в чем суть.

посаны, расходимся, нас опять нае*али.

Да ладно, куда ты денешься... всё равно будешь приходить в новости о Rust и ныть.

tailgunner ★★★★★ ()
Ответ на: комментарий от zz

Есть истории успеха с по процессу на пользователя, кроме Эрланга?

Scala, Akka

afiskon ()
Ответ на: комментарий от anonymous

Насколько эта проблема возникаема в реальном мире?

anonymous ()
Ответ на: комментарий от afiskon

А, ты про по процессу при подключении, а не по процессу при регистрации. Ну это такое.

zz ★★★★ ()
Ответ на: комментарий от MyTrooName

это умеют макросы. посмотри, например, как vec! реализован

В курсе. Но задача-то простая и часто требуется. Мне всё-таки кажется, что макросы средство «более мощное» и тут без них можно легко обойтись.

Опять же, посмотри на какой-нибудь контейнер типа HashMap. Для конструирования у нас есть new, with_capacity, with_hash_state, with_capacity_and_hash_state. А если ещё что-то добавить захочется? И заметь, что аналога vec! нет, а хотелось бы. Весь этот зоопарк можно убрать при помощи аргументов с дефолтными значениями (или перегрузки). Но теперь-то оно будет с нами «всегда», ведь апи стабилизировали.

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

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

DarkEld3r ★★★★★ ()
Ответ на: комментарий от Legioner

Но ведь в C++ всё абсолютно то же самое.

Я тоже не понимал чего все лайфтаймы сложными считают. Но потом «осознал». Бывает и правда, что чекер «надоедает», но это справедливо для всех типизированных языков. Просто чем больше (лучше) они типизированы, тем чаще компилятор по рукам бьёт.

В С++ правила чуть другие, поэтому и проблемы возникают не такие.

DarkEld3r ★★★★★ ()

Похоже, systemd-срачам появилась достойная альтернатива.

anonymous ()
Ответ на: комментарий от vertexua

Работает

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

DarkEld3r ★★★★★ ()
Ответ на: комментарий от DarkEld3r

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

vertexua ★★★☆☆ ()
Ответ на: комментарий от DarkEld3r

И заметь, что аналога vec! нет, а хотелось бы.

где-то в фичреквестах видел, думаю, добавят

Для конструирования у нас есть new, with_capacity, with_hash_state, with_capacity_and_hash_state

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

MyTrooName ★★★★★ ()
Ответ на: комментарий от MyTrooName

хоть это и приведет к еле заметному оверхеду.

Тут не понял, откуда оверхед?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от vertexua

Это C++ - специфичные проблемы. Лучше никаких исключений, чем такие.

anonymous ()
Ответ на: комментарий от anonymous

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

Саму проблемой проблемы относительно легко избежать, если внимательно писать код и вручную ловить циклы, но тогда не понятно зачем нужен Rust, если обещанный cost-free memory safety by default не сложился.

anonymous ()
Ответ на: комментарий от DarkEld3r

оверхед

чем больше аргументов, тем дороже вызов функции

MyTrooName ★★★★★ ()
Ответ на: комментарий от anonymous

Хм. Разве не очевидно, что подсчет ссылок будет приводить к циклам? Что бы вы с этим не делали. Зарорвать нормально циклы можно только с помощью weak_ptr и его аналогов. Это вам не GC.

anonymous ()
Ответ на: комментарий от anonymous

Цикл на Rc в расте составить не так просто, как в C++. Как раз borrow checker будет ругаться во многих случаях. Но, видимо, все-таки можно

MyTrooName ★★★★★ ()
Ответ на: комментарий от MyTrooName

Я ещё раз говорю, это должно было быть очевидно...

anonymous ()
Ответ на: комментарий от MyTrooName

чем больше аргументов, тем дороже вызов функции

ага, а в цикле лучше ++i, а не i++ писать

anonymous ()
Ответ на: комментарий от MyTrooName

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

anonymous ()
Ответ на: комментарий от anonymous

ага, а в цикле лучше ++i, а не i++ писать

да, если у тебя ++i и i++ - перегруженные операторы, которые нельзя заинлайнить

MyTrooName ★★★★★ ()
Ответ на: комментарий от anonymous

Ну вот ожидалось, что borrow checker решит эту проблему в safe-коде, а когда подобный цикл на самом деле нужен будет, нужно будет использовать unsafe. Идея была, что если твой safe-код прошел borrow checker, то он memory safe. Вот оказалось, что мутабельность и Option позволяют обмануть borrow checker.

anonymous ()
Ответ на: комментарий от anonymous

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

anonymous ()
Ответ на: комментарий от anonymous

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

anonymous ()
Ответ на: комментарий от anonymous

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

anonymous ()
Ответ на: комментарий от anonymous

Вообще подобная ситуация описана в документации, так что для разработчиков это не стало открытием http://doc.rust-lang.org/1.0.0-beta/std/rc/ :

Rust actually makes it somewhat difficult to produce this loop in the first place: in order to end up with two objects that point at each other, one of them needs to be mutable. This is problematic because Rc<T> enforces memory safety by only giving out shared references to the object it wraps, and these don't allow direct mutation. We need to wrap the part of the object we wish to mutate in a RefCell, which provides interior mutability: a method to achieve mutability through a shared reference. RefCell enforces Rust's borrowing rules at runtime.

anonymous ()
Ответ на: комментарий от cyanide_regime

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

Вот у меня немножко быдлокода есть, ковыряю потихоньку - https://github.com/ozkriff/zoc.

$ find src -name "*.rs" | xargs wc -l
  ...
  5585 итого

И в парочку библиотек комитил, типа cgmath-rs, gl-rs, glfw-rs, glutin и т.п. Мне позволительно о плюсах языка говорить, о Великий? )

ozkriff ()
Ответ на: комментарий от anonymous

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

Почему?

ozkriff ()
Ответ на: комментарий от anonymous

Лучше никаких исключений, чем такие.

Что не так с плюсовыми исключениями?

DarkEld3r ★★★★★ ()
Ответ на: комментарий от Legioner
pub fn check_read_write<T, R, W>(value: &T, bytes_hex: &[u8], read: R, write: W)
    where T: PartialEq + fmt::Debug,
          R: Fn(&mut &[u8]) -> s11n::Result<T>,
          W: Fn(&mut Vec<u8>, &T)

pub fn check_read_write<
    T: PartialEq + fmt::Debug,
    R: Fn(&mut &[u8]) -> s11n::Result<T>,
    W: Fn(&mut Vec<u8>, &T)
>(value: &T, bytes_hex: &[u8], read: R, write: W)

А люди продолжают ругать синтаксис лиспа.

loz ★★★★★ ()
Ответ на: комментарий от loz

Первый вариант мне очень нравится. Очень читаемый. Впрочем мне и лисп норм )))

Legioner ★★★★★ ()

не включающих в себя пункты про отсутствие нормальной IDE,

Если vim еще не умеет подсветку для rust, то скоро ее прикрутят. Осталось убедиться, что шатания разработчиков языка действительно прекратились.

малый размер сообщества,

Зарелизится язык, будет и сообщество.

andreyu ★★★★★ ()
Ответ на: комментарий от DarkEld3r

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

anonymous ()
Ответ на: комментарий от loz

А люди продолжают ругать синтаксис лиспа.

Ржавчину ж регулярно ругают за синтаксис. Всегда есть люди, которые чего-то за что-то ругают))

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

ozkriff ()
Ответ на: комментарий от DarkEld3r

А это будет в стандартной библиотеке когда-нибудь?

Сильно сомневаюсь. И анонс в /r/rust особого фурора не вызвал. А какая разница, будет оно в стандартной библиотеке или нет? Этот макрос на совместимость кода никак не влияет же. Подключай да используй.

ozkriff ()
Ответ на: комментарий от andreyu

Если vim еще не умеет подсветку для rust, то скоро ее прикрутят

Есть для вима и подсветка, и автодополнение.

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

Смотря в каком смысле. После 1.0 еще дохрена всего будут добавлять. Обратно-совместимое, но все-таки.

ozkriff ()
Ответ на: комментарий от ozkriff

Не будет ненужных запятых и точек с запятой, как минимум.

loz ★★★★★ ()
Ответ на: комментарий от anonymous

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

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

DarkEld3r ★★★★★ ()
Ответ на: комментарий от ozkriff

А какая разница, будет оно в стандартной библиотеке или нет?

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

DarkEld3r ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.