Re[9]: Rust vs C++ 17
От: DarkEld3r  
Дата: 11.01.16 16:19
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Так об этом и шла речь
Автор: ELazin
Дата: 06.01.16
, либо мы платим тормозами за корректность, либо заворачиваемся в unsafe даже в таких типичных местах как массивы.

Ну справедливости ради — если мы обходим коллекцию целиком через итераторы, то код будет (по крайней мере, должен быть) идентичным. Да и для доступа к "случайным" элементам поведение раста мне кажется более "удобным": определённое поведение (паника) с возможностью отключить проверки (и подчеркнув это необходимостью использовать unsafe).

Может у меня опыт не такой, но в плюсах, зачастую, вижу использование [] с асертом рядом, at доводилось видеть весьма редко.
Re[10]: Rust vs C++ 17
От: Evgeny.Panasyuk Россия  
Дата: 11.01.16 16:56
Оценка: +1
Здравствуйте, DarkEld3r, Вы писали:

EP>>Так об этом и шла речь
Автор: ELazin
Дата: 06.01.16
, либо мы платим тормозами за корректность, либо заворачиваемся в unsafe даже в таких типичных местах как массивы.

DE>Ну справедливости ради — если мы обходим коллекцию целиком через итераторы, то код будет (по крайней мере, должен быть) идентичным.

О чём речь? Идентичным чему?

DE>Да и для доступа к "случайным" элементам поведение раста мне кажется более "удобным": определённое поведение (паника) с возможностью отключить проверки (и подчеркнув это необходимостью использовать unsafe).


Я только за явные секции с unsafe'ом, да и вообще не только unsafe — это могут быть всякие явные монадические области и тому подобное.

DE>Может у меня опыт не такой, но в плюсах, зачастую, вижу использование [] с асертом рядом, at доводилось видеть весьма редко.


Но против дорогого преждевременного defensive programming а-ля .at
Отключаемые assert'ы на пред/пост условия, инварианты/варианты циклов и т.п. — пожалуйста. Есть кстати хорошая презентация на тему методологии assert'ов в C++ — John Lakos "Defensive Programming Done Right" (1, 2)
Re[11]: Rust vs C++ 17
От: DarkEld3r  
Дата: 12.01.16 12:28
Оценка:
Здравствуйте, ELazin, Вы писали:

EL> В том же Rust строки — мутабельные. Язык, появившийся в 2015-м году имеет мутабельные строки в своей стандартной библиотеке. Жизнь людей ничему не учит.

И чем это плохо?

EL>А если я возьму для этого Rust, мне все равно придется писать unsafe код, только у меня не будет calloc и арифметики указателей и всего такого.

Во первых, почему не будет?
Во вторых, если ты напишешь библиотеку, то пользоваться ей можно будет не прибегая к unsafe и имея при этом внутри всё что хочется. Разве это плохо?
Re[3]: Rust vs C++ 17
От: DarkEld3r  
Дата: 12.01.16 14:49
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Эти два пункта скорее минус, чем плюс, так как провоцируют написание г-нокода.

Можно развернуть мысль?
Re[7]: Rust vs C++ 17
От: DarkEld3r  
Дата: 12.01.16 15:34
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>foo (Foo val1 val2) = val1 + val2

LP>Добавляем в Foo третье поле val3. Конкретно в функции foo это поле НЕ используется. Но мы должны ее изменить
LP>foo (Foo val1 val2 val3) = val1 + val2
Честно говоря, не совсем понял (псевдо?)код, но в расте это уже работает для "нормальных структур" (в том числе, внутри enum). То есть можно делать так:
Foo{a, b, .. /*не важно сколько полей*/}
Bar(a, b, _, _)

Почему оно не работает для tuple-struct (Bar) — не знаю. Может недосмотр, может сознательное решение. Похоже на второе потому что проигнорировать все поля сразу можно (всё тем же ..).
Re[11]: Rust vs C++ 17
От: DarkEld3r  
Дата: 12.01.16 15:44
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>О чём речь? Идентичным чему?

Я к тому, что если мы обходим коллекцию целиком, то не получаем аналог at для каждого элемента.

EP>Но против дорогого преждевременного defensive programming а-ля .at

Можно, конечно, поспорить на тему того насколько оно дорого, но мне всё-таки больше нравится defensive programming, чем неопределённое поведение. Хотя да, в плюсах at не использую.
Re[12]: Rust vs C++ 17
От: Evgeny.Panasyuk Россия  
Дата: 13.01.16 19:33
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

DE>Я к тому, что если мы обходим коллекцию целиком, то не получаем аналог at для каждого элемента.


Это понятно, но эти простые случаи не особо интересно рассматривать, так как на C++ в этом месте будет либо range-based-for, либо один из многих алгоритмов STL, которые оттестированы и отлажены, то есть выход за границы мы и так там не получим.
То есть по-хорошему это не use-case'ы для применения индексов в пользовательском коде.

EP>>Но против дорогого преждевременного defensive programming а-ля .at

DE>Можно, конечно, поспорить на тему того насколько оно дорого, но мне всё-таки больше нравится defensive programming,

А мне больше нравится выделять всякие хитрые доступы по индексу в отдельный алгоритм или класс, и обкладывать их тестами и assert'ами.
Это кстати всё равно придётся делать и в языках с проверкой индексов, так как проверка помогает диагностировать только малую часть возможных багов, и например не спасёт от зацикливания или что ещё хуже неправильного результата.

Если же стоит организационная проблема с кадрами которые пишут опасный код с запутанной адресной арифметикой и т.п. и не могут его отлаживать, то да — можно и запретить некоторые опасные конструкции и выдать взамен defensive а-ля .at, но это крайняя мера, и C++ тут скорей всего не лучший выбор.

DE>чем неопределённое поведение.


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

DE>Хотя да, в плюсах at не использую.


Если например индекс приходит откуда-то извне — то можно и использовать .at или подобное, но здесь проверка нужна в любом случае — это не defensive programming.
Re[13]: Rust vs C++ 17
От: DarkEld3r  
Дата: 14.01.16 13:28
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>То есть по-хорошему это не use-case'ы для применения индексов в пользовательском коде.

Индексов — нет. Просто мне кажется, что "полный проход" по "стандартной коллекции" (вектор/массив) используется, возможно, даже чаще чем обращение по индексу. То есть, это use-case более частый.

EP>А мне больше нравится выделять всякие хитрые доступы по индексу в отдельный алгоритм или класс, и обкладывать их тестами и assert'ами.

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

EP>Определённое но бесполезное не особо лучше-то, изначальный баг оно же не исправит, а лишь поможет его диагностировать, да и то только на стороне пользователя.

Ну если поможет, то (совсем) бесполезным это поведение сложно назвать.
Re[10]: Rust vs C++ 17
От: T4r4sB Россия  
Дата: 14.01.16 14:13
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

DE>Может у меня опыт не такой, но в плюсах, зачастую, вижу использование [] с асертом рядом


А почему рядом, а не внутри?
Re[11]: Rust vs C++ 17
От: DarkEld3r  
Дата: 14.01.16 14:42
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>А почему рядом, а не внутри?

Внутрь стандартного вектора не так просто (свой) асерт запихнуть. Не делать/оборачивать же свой контейнер ради этого.
Re[12]: Rust vs C++ 17
От: Evgeny.Panasyuk Россия  
Дата: 14.01.16 15:15
Оценка: +1
Здравствуйте, DarkEld3r, Вы писали:

TB>>А почему рядом, а не внутри?

DE>Внутрь стандартного вектора не так просто (свой) асерт запихнуть.

В стандартных обычно уже есть и assert'ы при доступе по индексу, и отладочные итераторы и т.д. и т.п.

http://coliru.stacked-crooked.com/a/312b68b7dba0be84
/usr/local/include/c++/5.3.0/debug/vector:406:error:
attempt to subscript container with out-of-bounds index 2, but container only holds 1 elements.


DE>Не делать/оборачивать же свой контейнер ради этого.


Почему бы и нет? Через private наследование + using это достаточно просто.
Re[14]: Rust vs C++ 17
От: Evgeny.Panasyuk Россия  
Дата: 14.01.16 15:31
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

EP>>То есть по-хорошему это не use-case'ы для применения индексов в пользовательском коде.

DE>Индексов — нет. Просто мне кажется, что "полный проход" по "стандартной коллекции" (вектор/массив) используется, возможно, даже чаще чем обращение по индексу. То есть, это use-case более частый.

Полностью согласен, он более частый, я бы сказал даже на порядки. Только это не доступ по индексу

EP>>А мне больше нравится выделять всякие хитрые доступы по индексу в отдельный алгоритм или класс, и обкладывать их тестами и assert'ами.

DE>Дык, в этом плане раст никак не мешает, разве нет? Раз уж алгоритм и так хитрый, то осознанное использование отдельных методов для сознательного выбора способа "обработки" неправильных индексов сложности не добавит, как мне кажется.

Я о том что это придётся делать в любом случае. И пользы от подобного defensive остаётся очень мало, особенно учитывая то что выгоду он даёт только в release у конечного пользователя (без использования defensive programming, те же самые проверки происходят в debug сборках).

EP>>Определённое но бесполезное не особо лучше-то, изначальный баг оно же не исправит, а лишь поможет его диагностировать, да и то только на стороне пользователя.

DE>Ну если поможет, то (совсем) бесполезным это поведение сложно назвать.

Да, совсем бесполезным не является, но и соотношение между преимуществами и недостатками своеобразное, особенно на уровне C++/Rust.
Re[8]: Rust vs C++ 17
От: Baudolino  
Дата: 14.01.16 15:56
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>В требовательном к надежности коде исключения неприемлемы.

Очень спорное утверждение, видимо, связанное с непониманием того, как исключения могут работать "в требовательном к надежности коде". Вы с checked exceptions в Java знакомы?
Re[12]: Rust vs C++ 17
От: T4r4sB Россия  
Дата: 14.01.16 16:07
Оценка:
Здравствуйте, DarkEld3r, Вы писали:

DE>Здравствуйте, T4r4sB, Вы писали:


TB>>А почему рядом, а не внутри?

DE>Внутрь стандартного вектора не так просто (свой) асерт запихнуть. Не делать/оборачивать же свой контейнер ради этого.

Во-первых, какого хрена его там нет изначально, смысла вылазить за индекс — никакого, ну и короче идиотизм отказываться от проверки в дебаге.
Во-вторых, у себя дома можно и поколупать стандартную библиотеку.
Re[9]: Rust vs C++ 17
От: AlexRK  
Дата: 14.01.16 17:36
Оценка:
Здравствуйте, Baudolino, Вы писали:

ARK>>В требовательном к надежности коде исключения неприемлемы.

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

Это утверждение, которое вполне подтверждается практикой. Все распространенные операционные написаны на С. Софт для марсохода написан на С. Многие программы, связанные с авиакосмической отраслью, написаны на SPARK: http://www.adacore.com/customers. (Правда, на Аде тоже пишут, и одна из космических катастроф — Ариан 5 — была вызвана необработанным исключением.) Игры на приставках тоже в основном пишутся без использования исключений (по заявлению одного игродела).

B>Вы с checked exceptions в Java знакомы?


Кое-что слышал об этом. А вы с RuntimeException в Java знакомы?
Re[10]: Rust vs C++ 17
От: uncommon Ниоткуда  
Дата: 14.01.16 21:14
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Игры на приставках тоже в основном пишутся без использования исключений (по заявлению одного игродела).


Об играх разговор особый. В играх можно считать, что все операции всегда заканчиваются успешно, ресурсов всегда хватает, файлы всегда открываются, етс. В играх вообще исключительных ситуаций не бывает, поэтому их обрабатывать не нужно. А если какая-нибудь исключительная ситуация всё-таки произойдёт, то игра может просто упасть, и ничего страшного, это-же просто игра! Поэтому я бы не стал считать игроделов авторитетными источниками в вопросах надёжности кода.
Re[11]: Rust vs C++ 17
От: AlexRK  
Дата: 14.01.16 21:36
Оценка: :)
Здравствуйте, uncommon, Вы писали:

ARK>>Игры на приставках тоже в основном пишутся без использования исключений (по заявлению одного игродела).


U>Об играх разговор особый. В играх можно считать, что все операции всегда заканчиваются успешно, ресурсов всегда хватает, файлы всегда открываются, етс. В играх вообще исключительных ситуаций не бывает, поэтому их обрабатывать не нужно. А если какая-нибудь исключительная ситуация всё-таки произойдёт, то игра может просто упасть, и ничего страшного, это-же просто игра! Поэтому я бы не стал считать игроделов авторитетными источниками в вопросах надёжности кода.


Да, согласен. Про приставки я сказал "до кучи". Источник, на который я ссылался, утверждал, что включение исключений дает до 30% пенальти производительности.
Re[12]: Rust vs C++ 17
От: uncommon Ниоткуда  
Дата: 15.01.16 04:01
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Да, согласен. Про приставки я сказал "до кучи". Источник, на который я ссылался, утверждал, что включение исключений дает до 30% пенальти производительности.


Я бы с ним не согласился. Особенно, когда известно, что на x64, например, исключения имеют нулевой overhead.
Re[13]: Rust vs C++ 17
От: AlexRK  
Дата: 15.01.16 09:50
Оценка:
Здравствуйте, uncommon, Вы писали:

ARK>>Да, согласен. Про приставки я сказал "до кучи". Источник, на который я ссылался, утверждал, что включение исключений дает до 30% пенальти производительности.

U>Я бы с ним не согласился. Особенно, когда известно, что на x64, например, исключения имеют нулевой overhead.

Там речь шла про приставки прошлого поколения — PS3 и Xbox 360, которые не x86. Возможно, на текущем поколении положение дел изменилось.
Re[10]: Rust vs C++ 17
От: Baudolino  
Дата: 15.01.16 10:52
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Здравствуйте, Baudolino, Вы писали:


ARK>>>В требовательном к надежности коде исключения неприемлемы.

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

ARK>Это утверждение, которое вполне подтверждается практикой.

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

ARK>А вы с RuntimeException в Java знакомы?

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

B>>Вы с checked exceptions в Java знакомы?

ARK>Кое-что слышал об этом.
Замечательно. Тогда вы наверное знаете, что это вид исключений, подлежащий обязательному декларированию в сигнатуре метода.
А теперь давайте посмотрим на код:
T1 fn1(P... args) throws E { ... }

/* без обработки ошибки */
T2 fn2(P... args) throws E {
    ...
    return new T2(fn1(args));
}

/* с обработкой ошибки */
Optional<T1> fn3(P... args) {    
   try {
      return Optional.of(fn1(args));
   } catch (E ex) {
      log.error("error in fn1", ex);
      return Optional.empty();
   }
}

Немного изменим запись, сохранив логику реализации:
(T1|E) fn1(P... args) { ... }

(T2|E) fn2(P... args) {
   var x = fn1(args);
   x match 
     case T1 : return new T2(x);
     case E : {
         return x;
     }
}

Optional<T1> fn3(P... args) {
   var x = fn1(args);
   x match 
     case T1 : return Optional.of(x);
     case E : {
         log.error("error in fn1", x);
         return Optional.empty();
     }
}

Ничего не напоминает?
Checked exceptions это эквивалент использования union types для обработки ошибок с синтаксическим сахаром (просто сравните реализацию fn2 в обоих случаях).
Не более того. Разница с unchecked exceptions состоит в том, что пользователь API здесь может не ждать сюрпризов и утечек абстракции, помимо того, что уже объявлено в сигнатуре, и он обязан либо обработать ошибку, либо задекларировать её и делегировать обработку на уровень выше. Проблемы той же Java, связанные с исключениями, связаны с тем, что во-первых в языке присутствуют unchecked exceptions, а во-вторых в стандартной библиотеке есть общий базовый класс для checked exceptions, с помощью которого в говнокоде постоянно утекают абстракции через throws Exception.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.