Комментарии 44
Кто-нибудь workspace'ы пощупал уже, как оно на деле? :)
Rust все продолжает привлекать к себе внимание core developers других языков. Вот и Georg Brandl в списке "участников". Для тех кто живет в мире Python известное имя. Возможно еще много кто есть в этом списке, просто Georg первая знакомая для меня персона из этого списка )
лишего пиара и пафоса
Так разве они лишние? Вообще не продвигать язык нельзя — тогда пользователям-первопроходцам неоткуда будет взяться, а без них язык постепенно загнется.
Это в английском «to announce» — объявлять.
Основная сложность — мне не удалось обнаружить красоту-симметричность структуры языка:
1) Send и Sync
2) используется множество сокращений, которые читаются куда хуже, чем полные названия, например в Qt
3) отсутствие ключевого слова и вообще точки с запятой при возврате значения в последней строке функции
Мне как-то вообще малопонятна его (языка) логика — откуда берутся такие решения? О чем думают авторы — об экономии символов кода вместо простоты и понятности?
Красота и симметрия в физике — это понятно. Различные симметрии соответствуют различным законам сохранения.
В программировании с этим как-то сложнее. Максимальное значение знакового целого в дополнительном коде 32768, минимальное -32767. Несимметрично, но проще для аппаратной реализации.
В OpenGL было принято решение перед отрисовкой приводить все координаты (x, y, z) к диапазону [-1; 1]. Видимо из соображений красоты/симметрии (в DirectX диапазон для z [0; 1]). Это привело к тому, Z-buffer имеет максимальную точность не вблизи камеры, а на некотором расстоянии, там где она не нужна.
Это первые контрпримеры, которые пришли на ум, к утверждению, что симметрия в программировании всегда полезна. Подтверждающие примеры, как-то не вспоминаются. Абстрактно-теоретическая симметрия между IEnumerable и IObservable, разве что. Впрочем, рассуждать о программировании в терминах симметрии я не привык, могу что-то и упустить.
1) Send, Sync — трейты-маркеры, обозначающие, что объект может безопасно передан в другой поток и что два потока могут безопасно использовать ссылку на один и тот же объект одновременно. Они, например, позволяют безопасно использовать Rc (указатель со счетчиком ссылок) вместо Arc (указатель с потокобезопасным счетчиком ссылок).
2) Спорное решение. Но не так уж их и много. fn
, pub
, mut
, impl
, mod
, Rc
, Arc
. Что ещё забыл? Я перестал замечать через час.
3) Язык ориентирован на выражения. Блок в фигурных скобках — это выражение, возвращающее последнее значение в блоке. Можно написать let x = if y {a} else {b};
или fn id<T>(x: T) -> T {x}
. Но можно, конечно, сделать и fn id<T>(x: T) -> T {return x;}
. return
рекомендуется использовать только для раннего возврата значений из функции, если использовать return
только для этого, то ранний возврат легче заметить.
… fn, pub, mut, impl, mod, Rc, Arc. Что ещё забыл? ...
Из ключевых слов еще вот сокращения:
- const
- enum
- priv
- proc
- ref
Благодарю. const
, enum
привычны по C, priv
ещё не используется, proc
уже не используется, ref
забыл, спасибо.
Но, в любом случае, сокращений не так уж и много.
Да я так, для полноты картины)
priv
ещё не используется
Он тоже "уже": https://github.com/rust-lang/rust/issues/8122 :)
симметрия в программировании всегда полезна. Подтверждающие примеры, как-то не вспоминаются.
Слово «всегда» я не говорил, но вот Вам некоторые примеры, подтверждающие красоту, простоту и понятность системно-симметричного подхода разработки ПО:
- constructor/destructor
- (), {}, [], <>, 'c', «string»
- + / -, ++ / --
- open/close
- read/write
- min/max
- begin/end
- lock/unlock
- show/hide
- create/destroy
- old/new
- first/last
- start/stop
Мне, например, такими конструкциями очень легко и приятно пользоваться.
constructor
Что пользовательские конструкторы типов как часть языка вообще являются хорошей идеей согласны далеко не все.
… вот Вам некоторые примеры ...
А что конкретно в ржавчине жутко асимметрично без причины?
https://doc.rust-lang.org/book/strings.html#slicing (перемешивание байтов и чаров)
https://doc.rust-lang.org/book/strings.html#concatenation (два типа почти одинаковых строк конкатенируются несколько по-разному)
И причина в обоих случаях написана почему так сделано, но недостаток системности для меня неприемлем. Это просто мое мнение. Кому нравится — пусть программируют.
Прошу только поменьше мне ставить минусы за высказывание своего мнения, как за начальный комментарий. А то у меня еще возникнут и сложности в понимании логики оценивания людей :)
slicing, concatenation
Во, это уже интереснее. Хотя это тоже уже очень много раз разобранные со всех сторон вопросы, про которые есть много статей. Про String/&str
вообще только ленивый не писал еще)
два типа почти одинаковых строк конкатенируются несколько по-разному
Они не по-разному соединяются, сам по себе &str
вообще не имеет операции соединения (это одолженная строка, она не владеет своими данными и не может ничего в них дописывать). .to_string()
это как раз приведение &str
к String
.
без «жутко», которое я не говорил
Так и не цитата же была :) Я "жутко" добавил потому, что в любом инженерном решении, если достаточно пристально прикопаться, можно найти нестыковки и кривости разные, но внимания обычно заслуживает только какая-то их часть. Так же, многие кривости определяются врожденной кривостью самой предметной области и тут тоже не всегда что-то можно сделать, что бы совсем их убрать.
И причина в обоих случаях написана почему так сделано, но недостаток системности для меня неприемлем.
И то, и другое объясняется как раз тем что это системный язык и ему нельзя абстрагироваться от этих деталей, иначе ржавчина как язык вообще смысла бы не имела.
Да и строки это вообще отдельный разговор, абсолютное большинство языков отвратительно работает с текстом и скрывает от программиста кучу потенциальных ошибок.
Недостаток скорости в системном языке (если бы все строчки были неизменяемыми и всегда создавались в куче) или провокация языком ошибок (если бы все строки были массивами char
ов) были бы приемлимы?
Прошу только поменьше мне ставить минусы за высказывание своего мнения, как за начальный комментарий.
Как я понимаю, минусы или за странную форму изложения мысли, или за очень поверхностные наблюдения, поданные в категоричном тоне.
странную форму изложения мысли
Я думаю, каждый человек имеет право излагать мысли в удобной ему форме. Тем более, если это никак не вредит окружающим.
за очень поверхностные наблюдения, поданные в категоричном тоне
Наблюдения поверхностные — «первое впечатление», ведь я уделил языку около 2 часов. На счет категоричности тона мало согласен, основной фразой была: «впечатление осталось малоприятное».
Вообще, мне кажется, если ставить -1, то лучше описать причину. Какое малооптимальное решение было принято с моей стороны?
1) не надо делиться своим мнением и опытом
2) нужно изучить тему досконально (потратить 100...1000 часов) и только потом комментировать
3) я не имею права говорить, что мне не понравилось работать с языком
Я думаю, каждый человек имеет право излагать мысли в удобной ему форме.
Всё верно, но и другие имеют право поставить минус, пусть и "не совсем объективно".
Вообще по моему опыту, если люди начинают возмущаться (пусть и справедливо) минусами, то ситуация становится только хуже. Выводы делать не возьмусь, но ситуацию с растом попробую прокомментировать.
Языком, в основном, интересуются энтузиасты и не удивительно, что отношение соответствующее (сам такой). Опять же, по своему примеру могу сказать, что тоже прошёл стадии "что за бред?" и "зачем сделано так (криво)?!". В этом плане и правда стоит подумать решение обосновано или как можно было бы сделать лучше. Или хотя бы задавать вопрос в менее провокационной форме. (:
Скажем про строки — мне после С++ странно слышать такие претензии, где только стандартных строк есть 100500 разновидностей. Да, можно сказать, что в расте местами сделано "более топорно" из-за того, что нет отдельных перегрузок и "владеющая строка" не создаётся автоматически. Но многие в языке ценят именно явность и стоит признать, что в этом есть свои преимущества.
P.S. Не минусовал, если что.
Как по мне, это скорее вкусовщина, ну и дело привычки (синдром утёнка), но давайте посмотрим повнимательнее. Вместо ключевых слов constructor/destructor в "некоторых популярных языках" используется совсем не симметричный значок ~
для деструктора. new/delete мне в программировании попадалось чаще, чем new/old. Кстати, в С++ для обращения к первому и последнему элементам (например) вектора используется front/back, а не front/last и как-то я не встречал жалоб на это.
Многие приведённые пары вообще к программированию имеют опосредовательное отношение. Ну и раз уж мы говорим и "симметричности, красоте, простоте и понятности" и были упомянуты операторы инкремента/декремента, то можно вспомнить как "симметрично" выглядит перегрузка префиксной и постфиксной форм.
О чем думают авторы — об экономии символов кода вместо простоты и понятности?
pub fn foo(n: &mut u32) {...}
public function foo(n: reference mutable unsigned integer32bit) {...}
Пытаются найти баланс между краткостью и понятность, что бы язык не стал ни Джавой, ни APL. Ну и да, это прям сферическая вкусовищина, где объективных критериев не может быть.
Я попробовал несколько подходов к изучению этого языка
Пока мне самым правильным подходом кажется:
1) Бегло пролистать Книгу — http://rurust.github.io/rust_book_ru — что бы получить общее представление о языке;
2) Пробежаться по http://rustbyexample.com и пощупать там примеры;
3) Начать писать какую-то небольшую программу:
3.1) Одновременно внимательно читать главы Книги о тех кусках языка, которые прям сейчас используешь в своем коде;
3.2) Спрашивать в https://gitter.im/ruRust/general, если чего-то все равно остается непонятным;
4) Послать парочку PR в открытые проекты, что бы как следует разобраться в том, как другие люди на языке пишут.
Можно и так, но моя логика в том что кривая обучения более плавной будет, если сначала свой малюсенький проектик написать и на нем постепенно познакомиться и понять зачем нужны всякие clippy, rustfmt, cargo, travis, appveyor и т.п., чем если все это сразу на тебя обрушится комом.
Travis и appveyor же вообще напрямую к языку не относятся, но тоже лучше на живом проекте знакомиться, если уж до этого не сталкивался с чем-то подобным.
) -> () {
а это вообще ад.Это не ад, а вопрос привычки. Тем более так всё равно никто не пишет, а пишут
) -> {
а пишут ") -> {"
пишут ") {", просто стрелка ошибку выдаст :)
походу эту бессмысленную, на практике, конструкцию добавили для порядку, так как fn, назвали-бы кусок кода — method (mhd хехе), или еще как, без уточнения возвращает этот кусок кода не именованный параметр или нет, и не надо было захламлять язык.
по мне так зря, fn ничего не дает, пустая трата ресурсов, я как паскалист даже не вижу в коде function\procedure, определяю что метод является функцией смотря на возвращаемый тип, потому что на практике надо знать не просто что это функция а этот самый тип.
такое впечатления что Rust это C над которым поглумились паскалисты.
Докопаться до синтаксиса: бесценно.
Я несколько раз прочитал, но сомневаюсь четко что понял мысль.
Не нравится что из:
1) ключевое слово fn
перед объявлением функции?
2) стрелка перед возвращаемым значением функции?
3) использование пустого кортежа ()
в качестве замены void
/none
/nil
?
В любом случае, эта вкусовщина точно так важна? Далеко не самая интересная особенность языка же.
1) вероятность требования указывать «пустой кортеж ()» в угоду канонического вида
2) бессмысленный «пустой кортеж ()» как дань за использование ключевого слова fn
3) fn ненужно — все равно на него не обращаешь внимания на примере паскаля
4) Rust это C над которым поглумились паскалисты
1) Кто это может потребовать и зачем? С таким же успехом можно предположить, что у вас на паскеле потребуют (работодатель, заказчик, не важно) именовать функции строго тремя символами. Вероятность примерно одинакова.
2) А мне наоборот нравится единообразие. Вместо того чтобы вводить исключение "функция не возвращающая значение" (или процедура) используется общий механизм.
3) Так может определимся что именно не нужно? Или ()
или fn
(и замена для пустого возвращаемого значения). В любом случае, что мешает в расте точно так же "смотреть на возвращаемый тип"?
Функция ровно в том же виде может объявляться локально рядом (перед, после) с простыми вызовами. И тут уже имеет значение, что имелось в виду — то ли функция объявляется, то ли она вызывается.
Машинный парсер можно под самые экзотические случаи придумать. Но человеку будет много легче опираться на ключевые слова с подсветкой синтаксиса.
Пустой кортеж не бессмысленен, а означает ровно то, что задумано — пустое значение. То, что на него сделали «сахар» в виде необязательности указания, так даже и хорошо, никто пока обязательного указания не требовал. Опасаться подобного ничем не лучше, чем ходить в шапочке из фольги «а вдруг инопланетяне нас зомбируют?»
языки стремятся к единому виду, остается обсуждать только вкусовщину, да когда добавят ту или иную идею.
языки стремятся к единому виду,
Не похоже, чтобы скажем Haskell, Racket и Rust к единому виду стремились. В мейнстриме, конечно, всё немного не так, но это и не удивительно.
Ну а там, допустим, безопасная работа с памятью и многопоточность в императивном языке без сборщика мусора — это ерунда и обсуждать тут нечего даже?
оно решает какую-то задачу
грамматику делает вменяемой
Анонс Rust 1.12