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

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

Rust, конечно, это клёво и всё такое, но я просто не могу заставить себя полюбить спецсимвольный ад именованных лайфтаймов или, например, местный вариант тернарного оператора let y = if x == 5i { 10i } else { 15i }.

Возможно, это не будет так сильно заметно если реально писать на языке, да и прямой работы с лайфтаймами в коде Армина вроде не так уж и много, но пока подобный код вызывает приступы сомнения в новом убийце C++.
Это на многих языках так — не могу полюбить отступы в питоне, вызовы методов без скобок в руби. Но мы же понимаем что это фигня.
С лайфтаймами конечно заморочка, но она же там специально, краеугольный камень так сказать.
Это всё-таки не вариант тернарного оператора, а популярная в функциональных языках идея, что каждое выражение возвращает какое-то значение. Например:
let y = if x == 5 then 10 else 15 in (* ocaml *)
let y = match x with | 5 -> 10 | _ -> 15 (* то же самое, только pattern matching *)

auto y = [x](){if (x == 5) return 10 else return 15;}(); // аналог из C++
Я понимаю, но подобная запись — то, что предлагается использовать вместо тернарника. По крайней мере, обычный вид убрали именно из-за неё.
Мне кажется, что для таких вещей вообще надо заимствовать синтаксис перла, который, как правильно пишут комментом ниже, отчасти спародировали в питоне:
doSomething() if x == 3;
doOtherThings() unless x == 4;

Для тернарного оператора, емнип, в перле как раз аналога нет, но подобная реверсивная запись для чтения достаточно удобна.
НЛО прилетело и опубликовало эту надпись здесь
В Перле это оператор, а в Пайтоне — выражение, так что не сказать, что это заимствование синтаксиса из Перла.
perl -e 'my $x = do { if (2+2==4) { 10 } else { 11 } }; print $x'
10

Пайтон:
a = 6 if x == 5 else 7
Честно признаюсь, что меня гораздо больше пугает версия для С++. Никак не могу запомнить, где там if, а где там else. А тут словами написано, не перепутаешь.

Лично меня в Rust не радует синтаксис для задания типа, let x: i32. Но это дело привычки.
Как ни странно, это
impl<'a> Map<&'a str, Value> for InfoDict {
    fn find<'x>(&'x self, key: &&str) -> Option<&'x Value> {
        self.map.find_equiv(key)
    }
    fn contains_key<'x>(&'x self, key: &&str) -> bool {
        self.find(key).is_some()
    }
}

эквивалентно этому:
impl<'a> Map<&'a str, Value> for InfoDict {
    fn find(&self, key: &&str) -> Option<&Value> {
        self.map.find_equiv(key)
    }
    fn contains_key(&self, key: &&str) -> bool {
        self.find(key).is_some()
    }
}

благодаря lifetime elision :) как видите, от аннотаций почти ничего не осталось. Видимо, автор redis-rs не успел обновить код или проглядел этот кусок.
Тут в чём фишка — это не отдельный тернарный оператор (выражение), альтернативный обычному оператору (набор инструкций).
Это общая форма, не нуждающаяся в отдельном представлении.
Ну вот немного с потолка пример, но наглядно иллюстрирующий

let y = if x >= 5 { let b = 3; x * b } else { let b = 100; b / x };

А внутри можно и цикл прокрутить, если надо, и флаг какой-нибудь установить.
В языках не поддерживающих такое смешение короткий тернарный оператор сразу рассыпается на несколько строчек.
Язык очень интересный, но синтаксис меня местами огорчает. Самый лучший синтаксис из си-подобных языков пожалуй у C#. Rust претендует на низкоуровневость Си (и еще очень интересно что в итоге получится со встроенными «умными указателями»), Go содержит интерейшие концепции эмбеддинга вместо наследования и интерфейсов, в D весьма много мелочей, которые упустили в С++; в общем, идеального языка опять нет.
У Swift очень классный синтаксис, но Apple пока ничего не говорила о его стандартизации или портировании.
Он не далеко уехал от Rust или Go.
Всё главное, как известно, кроется в деталях. А в деталях (синтаксис) Swift делает и Rust и Go. Причём, если Go имеет чётко выраженную специфику (многопоточность), то Rust вообще ни то ни сё.
Rust вообще ни то ни сё
Ох, действительно? Почитайте
Действительно. Дальше Mozilla он не выйдет. Можете вернуться к этой ветке через 5 лет и посмотреть, кто был прав.
Ого! Да вы, прямо, Нострадамус! Может, все же поделитесь подробностями, на чем основаны ваши предсказания? Это ж, все-таки, Хабр, а не «Битва экстрасенсов».
Если без перехода на личности, то моё мнение основано на аналогии с Vala, тоже как бы язык общего назначения, но за пределы GNOME не вышел.
Ну, знаете, можно привести множество аналогий, которые «вышли или не вышли за пределы». Но как это будет связанно именно с Rust? И как можно, основываясь на этом, делать такие категоричные утверждения?
P.S. У меня не было цели вас обидеть переходом на личности, если что. Там, в моем комментарии, предполагается смайлик. Что я в действительности хотел узнать — это то, насколько обоснованы ваши предсказания.
Достаточно посмотреть первую двадцатку на той же Tiobe, чтобы увидеть, что большинство из широко ныне используемых языков имеют в общем-то примитивный синтаксис, за редким исключением. Сложный язык = дорогой код.
Тут не поспоришь. До тех пор, пока заказчики не начнут подсчитывать убытки от позднего обнаружения багов, для них главным аспектом будет скорость и лёгкость разработки. Надеюсь, они таки образумятся ;)
А Objective C не вышел за пределы Apple.

У Rust, тем временем, есть перспектива заменить C/C++ в системном программировании. Большая такая ниша.

А что Swift? Очередное apple-only решение, с нескучным синтаксисом и набором фич из других языков.
Objective C слишком ужасен, чтобы его добровольно использовать (имхо). Swift вообще-то LLVM-язык, так что больших проблем портировать его практически as is в данный момент нету. Вопрос в том, будет ли это сделано.
Есть мнение, что в Objective C объектный подход более «трушный», чем в том же С++ и Java. Лично мне, кстати, многие вещи в нем очень сильно понравились, хотя опыт использования его в реальных проектах у меня не очень большой. Единственное, что меня удержало от полноценного обширного использования Objective C — это его некроссплатформенность. Точнее, отсутствие полноценной стандартной библиотеки (какой-то части Cocoa, не связанной с GUI) на других платформах. Так что зря вы так о нем )
Ну, это конечно на вкус и цвет.
У Objective C синтаксис непривычный, хотя концептуально это очень интересный язык — не менее интересный чем Rust и Go (а в чем-то даже и более). А вот у Swift к сожалению, насколько я понял, синтаксис привычный, а многих интересных возможностей ObjC (пока еще?) нет.
По крайней мере в руководстве по Swift я не нашел упоминаний динамических возможностей — все что связано с отправкой сообщений (я подозреваю что отправка сообщений используется неявно — но я ожидал увидеть возможность явно указывать вызов метода или отправку сообщения), также всевозможные добавления методов в классы на лету, доступ к метаинформации и т.д.
Насколько я помню — runtime у него общий с Objective-C, так что стандартные API уровня C должны работать.
Для Obj-C классов (и совместимых с ними Swift-классов, т.е. помеченных атрибутом objc) ничего не меняется, всё те же трюки через Obj-C runtime. Также есть fine-grained контроль над динамикой, т.е. можно не помечать весь класс objc, а лишь пометить атрибутом dynamic нужные свойства или методы (то, что вы называете «возможность явно указать вызов метода или отправку сообщения»).

Для нативных Swift-типов действительно отсутствует интроспекция и подмена методов в рантайме, ибо методы либо биндятся во время компиляции (для структур, перечислений и private/final методов классов), либо используется vtable.
Добавлю: для Apple портировать и стандартизировать Swift было бы огромным вином, т.к. продвигая язык, продвигаешь платформу. Это отлично понимает например Microsoft, развивая свой C#.
НЛО прилетело и опубликовало эту надпись здесь
Не слежу за Vala, но вот сразу вспомнил что есть Tox клиент, кросс платформенный, написанный на Vala: wiki.tox.im/Venom
НЛО прилетело и опубликовало эту надпись здесь
Надеюсь, что пока. Выше написал, почему Apple выгодно его стандартизировать и портировать.
Rust настолько динамичен, что стоит отвлечься на пару месяцев...
Да, это не Python, и множество вещей, привычных для него, не работают в Rust.

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

И про практичность… Что вы понимаете под практичностью? Haskell и Erlang хоть и популярные, но довольно маргинальные языки с высоким порогом входа. Причем у Erlang'а высокий порог входа больше психологический, вызванный непривычным синтаксисом…

Сравнивать с ними новые языки, это видимо мода такая. Какое-то время назад некий товарищ сравнивал с ними язык Go и делал очень странные выводы…
Это перевод.
Если, допустим, сравнивать с плюсами, то вот лично для меня реально порог входа в них оказался б0льшим, чем в хаскелл: он просто оказался легче в освоении. Что касается Эрланга, то отовсюду народ пишет, что срок освоения его с OTP и плюшками, исчисляется двумя неделями… одним месяцем. В то время как плюсы на нормальном уровне — это годы. Так что про высоту порога вы, на мой взгляд, приврали.
Дык, про Erlang я так и написал, что порог входа скорее психологический чем реальный…

На счет C++ и Haskell тут я думаю проблема в бэкграунде… Я например начинал с ассемблера и обычных процедурных языков программирования, типа Паскаля, Модулы-2 и прочая. Для меня в C++ главной проблемой было перестроиться на объектно-ориентированное мышление и не увлекаться строительством иерархий…

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

У вас очевидно другой бекграунд… )
моя приблизительная последовательность изучения языков программирования:
spectrum basic -> qbasic -> object pascal -> c -> assembler -> lisp -> haskell -> visual basic -> erlang -> java -> c# -> prolog -> Objective c -> c++ ->…
Я очень жду, когда он повзрослеет. Потому что главная беда индустрии — за столько лет никто не сумел стать Си. Это означало, что всё большее число нового кода «нагибалось» под Си, обрастая всякими синтаксическими ужасами (только потому что в Си этого нет, хотя и могло бы быть без раздувания рантайма — например, возврат нескольких значений из функции).

Я думаю, как только он повзрослеет, нас ждёт множество, наконец-таки _быстро_ работающего и быстро пищущегося софта, способного работать в нативном режиме (ELF-файл).
Go ИМХО сейчас лидирует, пользуясь мощной PR-поддержкой Google. Хотя лично я бы предпочел на его месте видеть D.
Ни тот ни другой не годятся как замена C — это уже много раз обсуждалось.
C это прежде всего прозрачная и полностью контролируемая работа с памятью, возможность работать без библиотеки, стандартный ABI.
А вот по этому поводу не затруднит показать подробный разбор что именно нельзя сделать на rust?
Я про Go и D
Ну, на D есть, например, вот это github.com/JinShil/D_Runtime_ARM_Cortex-M_study

Понятно, что стандартная библиотека пролетает, но никто вроде не мешает написать свою, не требующую кучи.
Это понятно. Но тут всё же требуется run time поддержка, без нее половина фишек языка перестает работать. И писать её для нестандартных случаев нужно самому.
Для rust же есть несколько возможностей:
1. no_std — совсем без библиотеки(зависимости уровня компилятора stack_exhausted, eh_personality, fail_fmt)
2. libcore — минимальная библиотека (дополнительно зависимости memcpy, memcmp, memset)
А какого рода runtime поддержка требуется D? Я просто не в курсе, к сожалению.
В D по-умолчанию сборщик мусора, на который завязана вся стандартная библиотека.
Это, в моем понимании, означает, что «embeded-вариант стандартной библиотеки» еще не написан.
Ну, так можно сказать, что любой язык подходит для embeded, например ruby. Просто «embeded-вариант стандартной библиотеки еще не написан». В том виде, в котором он есть сейчас, язык D подразумевает наличие сборщика мусора, а значит для embeded не подходит. И ещё много для чего (например драйвера на нём не очень-то попишешь).
Ну, отчасти вы правы. Есть ведь и embedded python и java. И даже javascript.
Другое дело, что эти языки (особенно javascript) плохо подходят по другим причинам. В embedded хочется видеть тот же С, только безопасный.

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

Собственно, по своему (не очень большому) опыту могу сказать, что в embedded и на С стандартная библиотека нужна довольно редко. И она тоже должна быть написана специально, хотя бы из соображений экономии памяти.
Совсем забыл отвестить, забегался.
В D поддержки runtime требуют например такиа вещи как структуры, классы, срезы. Это уже не совсем библиотека. В rust такие вещи решаеются либо на уровне языка, либо на уровне libcore(требующей минимальной поддержки со стороны libc либо самостоятельной реализации 3х функций работы с памятью).
P.S. с D на самом деле не сильно глубоко знаком — ничего больше 20 строк не писал, просто изучал из чистого любопытства
Т.е. в D нельзя создать класс или структуру, не имея сборщика мусора?
runtime != сборщик мусора.
dlang.org/struct.html
Структуры в D не совсем структуры в C/C++, отсюда и требование runtime.
Сомневаюсь, что вещи вроде dlang.org/class.html#SharedStaticDestructor можно сделать без runtime.
Я дико извиняюсь, но вынужден попросить у вас уточнить, что вы понимаете под словом runtime.
В первом приближении — набор функций, объединенных в библиотеку, вызовы к которым компилятор встраивает в исполняемый файл без явных на то причин/прямых упоминаний. Обычно таким образом реализуются работа с памятью и обработка исключений. Вообще на англоязычной вики вроде вполне нормально написано подробнее. en.wikipedia.org/wiki/Runtime_library
В таком случае, опять-таки, просто нужно написать embedded runtime. Для С и С++ стандартные библиотеки тоже приходится переписывать, тут ничего особенного нет.
Вероятно, переписывать придется больше, чем для rust, но ничего невозможного или запредельно трудного я в этом не вижу.

Насколько я знаю D поддерживает ручное управление памятью и подсчет ссылок, так что runtime без сборщика мусора тоже можно реализовать.
Ключевая фраза «просто написать».
1) Нужно реализовывать
2) Объем этого runtime выше, чем для rust и C, что для жесткого embedded может быть критично

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

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

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

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

Еще раз повторюсь — решения вполне оправданы в рамках своей предметной области, но просто так взять язык и пересадить его в другую среду нельзя.
В этом и проблема — сегодня там мощная PR-поддержка, а завтра «закрываем, чтобы сфокусироваться на G+». Язык, за которым стоит коммерческая компания имеет дурноватый оттенок.
Не, тут опенсорс и приличное комьюнити. Это вам не «гугльридер» какой-нибудь, закрыть так просто не получится.
На раз-два-три. Гугль делает следующую версию проприетарной, старую форкают, а гугль вносит несколько несовместимых изменений.
Гугль, конечно, те еще засранцы, но такой сценарий — вряд ли. Да и смысла нет.
А есть смысл закрывать фидреадер и поиск по коду? Та же гребанная логика вокруг г-.
НЛО прилетело и опубликовало эту надпись здесь
Ну вообще в том же TIOBE Dart уже умудрился влететь в топ-20. Хотя тот же Go болтается на 42-м. Но рейтинги (тем более для ЯП) — это зло, конечно же.
borrow checker это проверка корректности использования общих ссылок на этапе компиляции?
Странно, то что Rust сравнивают с Python или С++

Прочитав пару статей по Rust, пришел к выводу, что его синтаксис ну очень похож на синтаксис Scala, также в нем практикуются те же подходы, что и в Scala, такие как pattern matching, Option и т.д

Скорее, и Rust, и Scala позаимствовали эти концепции из более ранних языков вроде ML или Haskell :)
Согласен, так будет более правильно сказано.

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

Rust позиционируется в качестве замены C/C++ — это низкоуровневые библиотеки, embedded, игры. Однако Rust предоставляет достаточно абстракций, чтобы залезть и в нишу Go — это высокопроизводительный бэкенд. Например, уже сейчас есть несколько легковесных веб-фреймворков.

Взаимодействие с кодом на C в Rust близко к идеальному (имхо). Проблемы там есть, насколько я помню, только в районе юнионов. С C++ сложнее, но тут уже особенности самого C++ и его всевозможным vendor-specific ABI.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории