LINUX.ORG.RU

Rust и типобезопасность

 ,


3

7

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

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

Почитав документацию:

The as keyword does safe casting

Набросал такой примерчик:

fn main() {
        let a: f64 = std::f64::MAX;  // данное значение просто пример "большого числа"
        let b = a as i64;
        println!("{}", b);
}

Вопросы:

1) С какой стати это вообще компилируется?

2) Да, f64 и i64 нужно одно и то же количество битов для хранения значения, ну и что?

3) Почему результат меняет знак?

Представьте, что какой-то тех. процесс идет, и определенный параметр нельзя изменять скачкообразно, иначе физически система (по крайней мере, один из компонентов) выйдет из строя (встанет в раскоряку, взорвется, выпустит токсичный газ, убивающий 100тыс. населения; нужное подчеркнуть). И вот значение в f64 положительное и увеличивается постепенно, с i64 все вроде в порядке (и тестирование проходит на тестовых значениях), и вдруг хренак! и уже -9223372036854775808

Как так?

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

Чуешь разницу? Как опытный плюсовик ты должен был бы воскликнуть сейчас: «Эврика!»

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

В случае Rust аналогичный код, скорее всего, будет состоять из трейтов и генериков. Важное отличие от С++ - растовский код будет проверен до инстанцирования генериков!

А о каких проверках речь идет? Не мешало бы примерчик.

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

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

struct MyType(i32);

fn max_value<T>(items: &[T]) {
    println!("{:?}", items.iter().max());
}

fn main() {
    max_value(&[MyType(1), MyType(2), MyType(3)]);
}
error[E0277]: the trait bound `T: std::cmp::Ord` is not satisfied
 --> src/main.rs:4:35
  |
3 | fn max_value<T>(items: &[T]) {
  |              - help: consider restricting this bound: `T: std::cmp::Ord`
4 |     println!("{:?}", items.iter().max());
  |                                   ^^^ the trait `std::cmp::Ord` is not implemented for `T`
  |
  = note: required because of the requirements on the impl of `std::cmp::Ord` for `&T`

error[E0277]: `T` doesn't implement `std::fmt::Debug`
 --> src/main.rs:4:22
  |
3 | fn max_value<T>(items: &[T]) {
  |              - help: consider restricting this bound: `T: std::fmt::Debug`
4 |     println!("{:?}", items.iter().max());
  |                      ^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
  |
  = help: the trait `std::fmt::Debug` is not implemented for `T`
  = note: required because of the requirements on the impl of `std::fmt::Debug` for `&T`
  = note: required because of the requirements on the impl of `std::fmt::Debug` for `std::option::Option<&T>`
  = note: required by `std::fmt::Debug::fmt`

error: aborting due to 2 previous errors

vs

#include <iostream>

struct MyType { int d; };

template<typename T>
void max_value(const std::vector<T> &items)
{
    std::cout << std::max_element(items.begin(), items.end()) << std::endl;
}

int main(int argc, char *argv[])
{
    const std::vector<MyType> items{ {1}, {2}, {3} };
    max_value(items);
    return 0;
}

Вывод копипасть не будут, ибо не влезет.

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

Вывод - на C++ простой и лаконичный код, а на Расте какая-то портянка текста, да еще и сообщение об ошибке.

Разорванный Флакон

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

Проверки в расте - как в haskell: на соответствие ограничениям (type class constraints).

Тут либо раст надо знать, либо haskell. У меня сейчас нет времени расписывать. Могу сказать, что это очень крутая штука. В C++ что-то такое то ли будет скоро, то ли уже где-то можно увидеть, но выглядит как ужас-ужас, тогда как в rust и haskell изящно и лаконично. Кажется, я к этому начинаю уже привыкать.

dave ★★★★★
()
Ответ на: комментарий от RazrFalcon
#include <iostream>
#include <vector>
#include <concepts>
#include <algorithm>

struct MyType { int d; };

template<std::totally_ordered T>
void max_value(const std::vector<T>& items)
{
    std::cout << std::max_element(items.begin(), items.end()) << std::endl;
}

int main(int argc, char* argv[])
{
    const std::vector<MyType> items{ {1}, {2}, {3} };
    max_value(items);
    return 0;
}

Вывод копипасть не будут, ибо не влезет.

Вывод:

Ошибка	C7602	"max_value": связанные ограничения не соблюдаются	
fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Это, конечно, здорово. Но осталось подождать лет 10 и можно будет юзать эти концепты в коде за пределами своей личной «песочницы».

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

Но сообщение об ошибке все равно слишком гроздкое :( Будем надеяться, что поправят в дальнейшем.

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

А остальное кто будет копипастить, Печкин?

Кажется кто-то пропустил появление концептов. Да ты и сам должен понимать, что в общем случае дженерики Rust не ровня шаблонам С++.

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

А остальное кто будет копипастить, Печкин?

Шарик, ты балбес. С первых строк сообщения об ошибке уже все предельно ясно.

Разорванный Флакон

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

И много народу сидит на свежих версиях? Я недавно «откатывал» свой код до C++11 варианта, т.к. на одной из систем, где считать пришлось (выч. кластер), стоит CentOS 7.3.1611 с очень «свежим» gcc 4.8.5. И обновлять эту систему будут примерно через бесконечность :(

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

Кто-то пропустил суть сообщения и пытался сыграть в дурачка.

Кто и где? По ссылке fsb4000 текст ошибки не намного больше чем у Rust.

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

И много народу сидит на свежих версиях?

Очнись, в этом же треде твоя секта советует людям для решения проблемы собирать код только nightly компилятором (и то с костылями) Rust и типобезопасность (комментарий), а как C++, то сразу надо брать только C++ 1917, игнорируя все последние версии? Вся суть форумных военов.

Разорванный Флакон

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

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

В коде кстати заведомо ошибка в виде остуствия двух хедеров, об этом тоже в первой строчке в ошибках компиляции видно.

Потом даже школьник поймет что нельзя выводить итератор в поток вывода, когда он исправит код ка нужно (поставив разыменование) то сразу же по выводу компиллера поймет что в объекте взятом по итератору не оперделен способ вывода в поток (не определен оператор <<).

Все там локанично и просто - вы просто придираетесь. Я бы даже сказал что вывод удобнее в Си++, потому что он выше получается и сразу видно проблему. Компилял на годболт-онлайн-компиллер-сайте последним гцц…

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

т.к. на одной из систем, где считать пришлось (выч. кластер), стоит CentOS 7.3.1611 с очень «свежим» gcc 4.8.5. И обновлять эту систему будут примерно через бесконечность :(

Я для подобного взял Ubuntu 14.04 (можно даже 12.04 было), поставил там gcc 9 и пользуюсь С++17.

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

Вот и я о том что в отличии от раста вывода там в первых строчках видна проблема, что нельзя итератор в поток выводить, далее идёт исправление ошибки (которую любой новичек знает как исправить)

просто разоменовать итератор:

-std::cout << std::max_element(items.begin(), items.end()) << std::endl;
+std::cout << *(std::max_element(items.begin(), items.end())) << std::endl;

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

<source>:10:15: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'const MyType')

иными словами в такой то строе для объекта типа «std::ostream» (проинстанцированного std::basic_ostream<char>) и объекта типа const MyType не определен оператор вывода в поток <<

bonta ★★★★★
()
Последнее исправление: bonta (всего исправлений: 1)
Ответ на: комментарий от anonymous

Разница только в том, что Rust на ту же центось ставится в одну команду, а свежий gcc надо руками конпелять.

Вся суть форумных военов.

Я, вообще-то, не растоман, а вполне себе плюсовик. А вот почему у тебя так бомбит, мне не совсем понятно :)

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

Вы буковки считаете или полезную нагрузку?

Если говорить про «полезную нагрузку», то у меня clang выделил красным место ошибки:

/usr/include/c++/8/bits/predefined_ops.h:43:23: error: no match foroperator<’ (operand types are ‘const MyType’ andconst MyType’) { return *__it1 < *__it2; } 

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

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

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от Serral

опять же, если бы в Rust были бы возможности шаблонов, дедукции и перегрузки как в С++

Зачем все эти возможности в Rust’е? Mozilla сказала «ненужно», значит «ненужно», зато это самое безопасное «ненужно» в мире.

Разорванный Флакон

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

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

Ж*па только в том, что этого «мусора» часто на порядки больше, чем действительно полезной информации.

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

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

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

в отличии от раста вывода там в первых строчках видна проблема

Что именно в выводе rustc кажется непонятным? Он же внятно говорит, что тип T должен реализовывать std::cmp::Ord и std::fmt::Debug. И при этом не генерирует километр дополнительной «полезной» информации. Меня, как пишущего на C++, выхлоп плюсового компилятора в таких ситуациях нихрена не радует.

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

строго говоря, тут еще надо обложить концептами функцию operator<<. А в целом да, концепты в C++ куда более мощная штука, чем трейты в расте.

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

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

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

Ж*па только в том, что этого «мусора» часто на порядки больше, чем действительно полезной информации.

Бывает, ждем внедрения концептов.

но, например, при компиляции на удалённой системе парсить эти портянки часто приходится «глазами».

У нас сборки на виртуалках. Есть отдельная копия для таких случаев, с IDE, блэкджеком и куртизанками.

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

Что именно в выводе rustc кажется непонятным?

грубо говоря почти все. Т.к. синтаксиса его не знаю. Вот ++-ый вывод я читаю легко и быстро, раставский посмотрел минуту, что вывод что код и ничего не понял))

При этом я например не знаю Оберон (вроде - или на чем там книга Вирта) и Паскаль не знаю и Бейсик, и Джаву/Шарп, но если я смотрю их код (например те же описания алгоритмов) - то все понятно - потому что это языки с классным простым и многословным классическим синтаксисом.

В расте какая-то нечитаемая штуковина для меня (т.е. нужно изучать чтобы понять) но как бы на самом деле не нужно, потому что есть другие ЯП, не раст :)

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

грубо говоря почти все. Т.к. синтаксиса его не знаю. Вот ++-ый вывод я читаю легко и быстро, раставский посмотрел минуту, что вывод что код и ничего не понял))

Это дело привычки (опыта) - никакого rocket-science тут нет :) Я сам раст тыкаю палочкой иногда из любопытства и во многих аспектах он мне вполне симпатичен. Полностью C/C++ он вряд ли заменит, но свою нишу займёт, я думаю.

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

тут еще надо обложить концептами функцию operator<<

Согласен, вот чуть поправил тот пример, теперь компилируется

https://godbolt.org/z/zXhNLS

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

Полностью C/C++ он вряд ли заменит, но свою нишу займёт, я думаю.

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

Разорванный Флакон

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

В C++ сначала происходит инстанциирование, а затем компиляция.

Компиляция не имеет к теме никакого отношения.

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

Неверно. В расте не существует такого понятия как инстанцирование. И никакие трейты не проверяются.

В расте аннотируются трейтами сигнатуры, а далее функция проверяется.

Из-за чего ошибки в шаблонном коде намного более вменяемые.

Нету в расте шаблонного кода. Эксперт не разбирается в вопросе. Раст просто не тайпчекает типы аргументов на входе. Тайпчекается одна сигнатура, с одним типом. Это не шаблон.

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

Далее можно увидеть попытки писать на С++ не умея в него. Попытки засрать С++-код.

<source>:6:34:   required from 'void max_value(auto:11&&) [with auto:11 = MyType [3]]'

<source>:10:40:   required from here

/opt/compiler-explorer/gcc-trunk-20200327/include/c++/10.0.1/bits/predefined_ops.h:43:23: error: no match for 'operator<' (operand types are 'MyType' and 'MyType')

   43 |       { return *__it1 < *__it2; }

А что же это? А где же «не влезет»? Неужели эксперт врёт? https://godbolt.org/z/gnJ_ot

Ну а теперь чудо. Мы берём и заменяем тип на тип имеющий данный оператор: https://godbolt.org/z/wsXVtp и всё работает. А вот в расте нет. Почему?

Потому что С++ может в тайпчекер, а раст нет. Такие дела.

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

Это, конечно, здорово. Но осталось подождать лет 10 и можно будет юзать эти расты в коде за пределами своей личной «песочницы».

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

Остальное - это что? Это не ошибки. Это контекст. То, что в твоём изваянии контекст не осилили - это не уменьшение ошибки. Контекст можно вырубить. И опять же, то что тебе об этом не рассказали - это твоя проблема. Проблема твоей полной несостоятельности.

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

Чего для раста такое не требуешь? Почему твои потуги не собираются другими раст-компиляторами? Почему не собираются старыми версиями? Объясняйся, не убегай как обычно.

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

И много народу сидит на раста? Я недавно «откатывал» свой код до не-раст варианта, т.к. на одной из систем, где считать пришлось (выч. кластер), стоит CentOS 7.3.1611 без раста. И обновлять эту систему будут примерно через бесконечность :(

Методичку почини. Не позорься так.

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

Разница только в том, что Rust на ту же центось ставится в одну команду, а свежий gcc надо руками конпелять.

Есть тысячи говносборок подобным говносборкам раста. Как гцц так и шланга. К тому же ты настолько опозорился, что сел в лужу даже с центос7 - https://copr.fedorainfracloud.org/coprs/jwakely/gcc-latest/ - первая ссылка в гугле.

Латай методичку.

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

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

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

Если в С++ ты в шаблонную функцию, использующую <, подставишь int, как ты сделал в том примере, то конечно она заработает. Если MyType, то конечно она не заработает, ведь у MyType не реализован оператор <. Минус такого подхода заключается в следующем:

  • Необходимо знать, что лежит в потрохах этой функции, чтобы не получать неожиданные ошибки.

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

В Rust эти проблемы решаются следующим образом: ты требуешь от типа реализации необходимых трейтов. Пример с int провалится не потому, что у int не реализовано отношение строгого порядка, а потому, что сама функция некорректна. Прочитай сообщение об ошибке внимательнее, функция обобщенного аргумента &[T] не может реализовать max потому, что сферический T в вакууме не реализует Ord, а именно сферический T в вакууме ты и получаешь на входе. Аналогично с Debug: ты не можешь напечатать обобщенный аргумент типа T потому, что T не реализует Ord. Даже если ты подашь на вход какой-то конкретный тип, который будет реализовывать используемый трейт, функция все равно будет некорректной, ее корректность не зависит от аргумента на входе. Использование функции не требует знания ее потрохов – ее сигнатура уже сообщает тебе все, что нужно.

Если ты сделаешь

struct MyType(i32);

fn max_value<T: Ord + Debug>(items: &[T]) {
    println!("{:?}", items.iter().max());
}

fn main() {
    max_value(&[MyType(1), MyType(2), MyType(3)]);
}

, то функция окажется корректной, а подстановка туда MyType – нет, ведь MyType не реализует Ord. Такая версия уже будет работать с int и любым другим элементом класса типов Ord и Debug.

Итого, либо ты не понял, о чем говорил @RazrFalcon, либо ты принципиально не понимаешь, как работает такая система типов. Такой вот царь.

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

Итого, либо ты не понял, о чем говорил @RazrFalcon, либо ты принципиально не понимаешь, как работает такая система типов.

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

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

Использование функции не требует знания ее потрохов – ее сигнатура уже сообщает тебе все, что нужно.

У тебя потекла методичку. Это убогость твоего недоязычка. В любой нормальной системе типов существует вывод типа возврата и это базовый контр-аргумент против твоих нелепых потуг.

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

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

Именно поэтому, маня, твои хозяева(хозяева твоей методички) не используют настолько жалкие потуги. Там используется другой заход. Заход о том, что определить требования к типам сложно, ведь ошибку надо как-то решать.

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

Но, если мы возьмём требования посложнее - ты тут же обделаешься. Во-первых тупо потому, что ты никогда не напишешь код эквивалентный С++. Твоё недоязычок слишком слаб. А там, где ты его напишешь - у тебя будет сигнатура на пол экрана. Приватные трейты, генерик-трейты, сигнатуры говнофункций. Хотя в целом код на твоём недоязычке максимально примитивен и шансов реализовать что-то уровня С++ ты не сможешь в 999 случаев из тысячи.

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

В Rust эти проблемы решаются следующим образом: ты требуешь от типа реализации необходимых трейтов.

@Siborgium, @dave, @RazrFalcon

Дак в итоге, С++20 разрешил ваши претензии или нет?

В С++20, ты тоже можешь требовать от типа реализации необходимых концептов(трейтов), и С++ не будет заглядывать внутрь функции(пытаться инстанциировать)…

https://godbolt.org/z/ewtxkX

Ошибки:

https://godbolt.org/z/Yka52P (если не реализована печать)

https://godbolt.org/z/rdKFNW (если не реализовано сравнение)

Плохо разве что тем, что довольно мало встроенных концептов:

https://en.cppreference.com/w/cpp/concepts

Ну и то что поддерживается пока лишь двумя компиляторами: gcc 10 и VS 2019:

https://imgur.com/a/cj9cx8F

https://en.cppreference.com/w/cpp/compiler_support

http://libcxx.llvm.org/cxx2a_status.html

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

По большей части да. Другое дело, что это более-менее затронет реальные программы лет через 10-15, но это уже другая тема. Да даже и тогда использоваться будет не всеми (луддиты-с), что несколько убивает цель.

Из претензий разве то, что три синтаксиса для концептов – оверкилл, но это лично мои придирки.

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

Ну и самое важное, маня. Ты обделался ещё с одним фундаментальным свойством мироздания. Что-то менее ограниченное всегда можно ограничить, но не наоборот.

Поэтому ничего не мешает ограничить тип в С++, но вот получить тип в твоём мусоре - невозможно. Примеры с концептами тебе уже показывали.

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

Другое дело, что это более-менее затронет реальные программы лет через 10-15, но это уже другая тема. Да даже и тогда использоваться будет не всеми (луддиты-с), что несколько убивает цель.

Когда твой недоязычок затронет реальные программы? Расскажешь? У тебя опять методичка течёт.

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

ничего не мешает ограничить тип в С++

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

получить тип в твоём мусоре - невозможно

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

Когда твой недоязычок затронет реальные программы?

Не смешно, царь. Хотя доля Rust невелика, существуют успешные проекты, написанные на нем.

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

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

Ну давай, поставь оттуда свежий gcc без рутовских прав :)

Маня, как же ты поставил гцц тогда, если прав нету? И побежал показывать, где ты болтал до этого про какие-то права.

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

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

Насколько твои потуги нелепы и позорны.

Не мешает ничего, кроме того, что из мажорных компиляторов пока лишь 2 поддерживают эти фичи

Маня, ты обделался. Поддерживают все компиляторы мажорные. И шланг и гцц и даже маздайское говно.

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

не говоря уже о том, что никто не будет переписывать существующий код под концепты, и не все будут писать новый код с концептами.

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

А зачем мне получать тип?

Слишком слаб. Повторю, мне лень описывать школяру очевидные вещи. Научись чему-то, а потом уже пытайся с кем-то спорить. К тому же, тебе уже привели пример зачем получать тип. Пример доступный даже такому слабому балаболу как ты. Вывод типа возврата.

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

Никакого обхода у тебя нет. Ты обделался. Зачем болтаешь о том, о чём не знаешь?

Не смешно, царь. Хотя доля Rust невелика, существуют успешные проекты, написанные на нем.

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

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

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

Я тебе сказал. Все твои потуги - нелепая ретрансляция услышанной в интернете пропаганды. Когда твоё говно попадёт в мейнтрим. Ему 10-15 лет. Побежал показывать.

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

Маня, как же ты поставил гцц тогда, если прав нету?

Маня, я туда вообще ничего не ставил, я пришел туда как обычный юзер. Работал на вычислительных кластерах когда-нибудь? Если да, то должен знать, что софт там как правило «стабильный» (т.е. древний) и поставить что-то дополнительное можно только путём длительной переписки с админами, которым, как правило, лень что-то менять («работает - не трогай»). Но, судя по твоим тупым высерам, ты типиный юзер локалхоста, конпеляющий свои гениальные хеллоуворлды транковыми версиями gcc/clang.

В очередной раз можно увидеть балабола, который уже 10 раз обделался и опозорился

Ты сегодня самокритичен, царёк :)

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

Маня, я туда вообще ничего не ставил, я пришел туда как обычный юзер.

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

Задача ясна? Действуй.

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

Что-бы окончательно доказать всю нелепость этого трепла - поиграем в игру. Первая ссылка в гугле: https://stackoverflow.com/questions/36651091/how-to-install-packages-in-linux-centos-without-root-user-with-automatic-depen

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

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

Маня, потуги после меня не волнуют. Побежал показывать эти потуги изначально, в изначальных условиях.

Маня, твои потуги меня не волнуют. Побежал показывать блог на C++. Быстро побежал, трепло. Задача ясна? Действуй.

Меня не волнует то, что эникей с помойки придумал

Можно подумать, мнение шизоидного царька кого-то волнует. Бегом пили блог на C++, у вас там в СФУ как раз карантин/каникулы :)

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

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

то будет этот код переписывать на говнораст

Да никто не будет, дурачок, я и не предлагал этого делать. Любой код на расте написан с использованием трейтов потому, что иначе нельзя, тогда как С++ под концепты придется переписывать.

Программ на новых крестах больше.

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

не про программы, а про переход

Да нет, я как раз про программы говорил. И опять ты додумываешь за меня. Бинго!

К тому же, тебе уже привели пример зачем получать тип. Вывод типа возврата.

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

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

я без рута на centos7 запущу этот gcc

Можно вообще из исходников собрать :) Только зачем заниматься рукоблудством без острой необходимости? Вот народ и сидит на старых стандартах, чтобы «работало везде» без необходимости дрочить вприсядку.

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

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

Этот шизик всех обвиняет в «сектантстве» и при этом сам ведёт себя как буйный сектант. «У кого что болит, тот о том и говорит» :)

htower_ ★★
()
Последнее исправление: htower_ (всего исправлений: 1)
Ответ на: комментарий от Siborgium

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

Оправдания любого обгадившегося трепла.

Да никто не будет, дурачок, я и не предлагал этого делать. Любой код на расте написан с использованием трейтов потому, что иначе нельзя, тогда как С++ под концепты придется переписывать.

Ты совсем тупой, маня? Возможны две ситуации: пишется новый проект, дописывается текущий.

Берём первый случай - выбор говнораста и С++-20 - никак не отличаются. Т.е. для нового проекта эти две вещи однозначны. Если у кого-то есть потребность делать что-то на С++-98 - он будет это делать на нём. Ни на говнорасте, ни на С++-20. Здесь ты обделался.

Берём другой вариант. Существует код, он существует на С++/си. Если его никто не будет переписывать на С++-20, то никто не будет переписывать и на говнораст. Тут ты опять обделался.

Всё, никаких аутов у тебя нет. Ты в дерьме.

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

Ещё одна нелепая потуга балабола. Ты говорил это. Ты балаболил «никто не будет переписывать на новые кресты», а в другом случае болтал «на раст переписывают». Из этого прямо следует цитируемый тобою тезис, трепло.

Я лишь сказал, что существуют успешные проекты на расте.

Их нет, ты обделался. ТЫ обязан их показать - побежал показывать.

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

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

Да нет, я как раз про программы говорил. И опять ты додумываешь за меня. Бинго!

Ну чего говорил - балаболь. Что следует из этого потйги?

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

Чего пример, трепло? Я тебе сказал и ты цитируешь тезис «нету вывода типа возврата». Что тебе тут непонятно? Приводить примеры отсутствия чего-то я не обязан - это невозможно.

Ты можешь оспорить это? Показывай вывод типа возврата для говнофункций в твоём недоязычке. Это твоя обязанность, трепло.

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

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

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

Т.е. мне надо понять виртуалку с определенной версией ОС, поставить туда нужные либы (mpi/hdf5/CUDA/etc. При этом версии должны соответствовать тому, что стоит на удалённой системе), затем конпелять, заливать полученный «блоб» и надеяться, что всё заработает? Можно, в принципе, но не слишком удобно, как мне кажется :)

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

Нахрен «определённая версия ОС»? Версии либ, да, они важны, но не всегда, даже glibc можно с собой таскать. Разве что версия MPI важна, да и то мажорная версия.

WatchCat ★★★★★
()
Последнее исправление: WatchCat (всего исправлений: 1)
Ответ на: комментарий от anonymous

Возможны две ситуации: пишется новый проект, дописывается текущий.

Берем ситуацию «пишется новый проект». Если проект на С++, то концепты могут как использоваться, так и не использоваться. Если проект на Rust, то трейты там будут просто потому что это необходимое условие работы кода.

Берем ситуацию «дописывается текущий». Если проект на С++, то концепты можно добавить, потеряв совместимость со старыми компиляторами. А можно и не добавить, если в компании про С++20 и слыхом не слыхивали, все работают хорошо если с С++14. Можно добавить не везде, а только выборочно. Если проект на Rust, то трейты там уже были, дописывать их никуда не нужно.

Список проектов на Rust есть на официальной страничке и легко гуглится.

ы балаболил «никто не будет переписывать на новые кресты», а в другом случае болтал «на раст переписывают»

Твою ж мать. Приведи-ка мне прямые цитаты со ссылками на посты. Отсутствие этих цитат я сочту публичным признанием вида «Я, царь, не умею читать и спорю с оппонентами у себя в голове».

Вывод типа возврата

Я тебе еще раз повторяю, в Rust нет вывода типа возврата потому, что это является плохой практикой и плохо сочетается с другими фичами языка.

говнораст говно и порождает ошибки

Как раст может порождать ошибки выводом типа возврата, если в нем нет вывода типа возврата? Расскажи-ка поподробнее с этого момента.

Теперь перейдем к более ранним сообщениям.

сути шаблоны это такой динамически язык с реплом.

Ты споришь с этим же утверждением чуть выше. Прими уже таблетки.

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

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

Дак в итоге, С++20 разрешил ваши претензии или нет?

Увы, это просто ужас-ужас-ужас, а не концепты. Сколько на них ни смотрю последний год, никак не могу понять, что они хотели этим сказать, зачем так намудрили?.. Вот тут некоторые любят часто поворчать, что код на растишке дескать тяжело им понять... Смешно, будто бы код с концептами C++20 понять проще! Причем человеку, который успел довольно плотно поработать с C++, эпизодически, но очень плотно. Мне кажется, что С++ становится только сложнее и сложнее, и тут у меня возникают невольные ассоциации с монстром ПЛ/1, а ведь тоже какой крутой язык был для своего времени!

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

Смешно, будто бы код с концептами C++20 понять проще!

Проще.

Причем человеку, который успел довольно плотно поработать с C++, эпизодически, но очень плотно.

ИМХО, тут нужно выбрать одно из двух: либо плотно, либо эпизодически.

Ваш плюсовый код где-нибудь в открытом доступе увидеть можно?

А то многие жалуются, что C++ срет им в штаны не смотря на 100500 лет программирования на C++. А по факту такой говнокод производят, что не понятно, как им вообще что-то работающее получается написать.

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

А по факту такой говнокод производят, что не понятно, как им вообще что-то работающее получается написать.

Поменьше пафоса, Евгений :) А то выглядит примерно как вежливый-царь-едишн.

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

А то выглядит примерно как вежливый-царь-едишн.

В вежливости меня еще никто не обвинял.

А так суровая правда жизни: в разговорах все супер-пупер программисты, а как попадает реальный код на сопровождение, так хоть ценник в полтора-два раза повышай… :(

Да вот один из самых рьяных местных растоманов, RazrFalcon, уже многократно доказывал, что не смотря на годы работы с C++ у него владение плюсами где-то на уровне «пишу программы на Qt». Так что мнение RazrFalcon-а о возможностях C++ можно смело множить на ноль.

По поводу dave как программиста не ничего не известно, поэтому не знаю, какую поправку стоит использовать для его высказываний о C++.

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

Дрочить в присядку это переписывать код под очередную платформу.

А я разве к этому призывал? Вы меня с кем-то путаете :)

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

В вежливости меня еще никто не обвинял.

Ну извините :)

Да вот один из самых рьяных местных растоманов, RazrFalcon, уже многократно доказывал, что не смотря на годы работы с C++ у него владение плюсами где-то на уровне «пишу программы на Qt». Так что мнение RazrFalcon-а о возможностях C++ можно смело множить на ноль.

Тут такое дело. Есть программисты, которые знают C++ хорошо, даже отлично, они пишут всякие там бусты и т.п. Яркий пример из прошлого - Александреску. Но вот «среднестатистическому» C++ программисту такой код читать капец как тяжело, а поддерживать - так и вообще невозможно. Плюсы дают слишком большой простор, поэтому одни генерят «хайлевел», а другие - говнокод, и при этом обе стороны считают друг друга м*даками :) Тот же Qt, по-моему, вполне себе пример достаточно хорошего и понятного кода, где с одной стороны нет упарывания шаблонами, а с другой - нет «заката солнца вручную», в стиле сишников. Крайности - это всегда плохо.

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

А я говорил, что кто-то к чему-то призывал? Я говорил вот про это:

Я недавно «откатывал» свой код до C++11 варианта,

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

Не, мой посыл несколько в другом. Это другое из двух частей состоит:

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

  2. Язык программирования – это инструмент. Инструментом хорошо бы владеть. Ну или, по крайней мере, иметь представление о его возможностях. Соответственно, если кто-то надевает на себя шапочку «среднестатического» программиста и довольствуется неким подмножеством C++ (тем же С++ из Qt), но при этом позволяет себе поносить остальные возможности языка (типа исключения – это плохо, а шаблоны – это говно), то это выглядит странно. А говорящий такие вещи выглядит неадекватно.

Ну понятно, что кому-то достаточно определенного подмножества. Ну Ok. Это нормально.

Ненормально когда вещи вне этого комфортного подмножества для «среднестатического» программиста предаются анафеме, высмеиваются и т.д.

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

Я недавно «откатывал» свой код до C++11 варианта

А, вы про это. Ну да, налетел немного :) В итоге пришел к выводу, что писать нужно на c++11, так проще будет в моём случае. В 17-м стандарте добавили некоторые «вкусности», но, к сожалению, много выч. систем «из коробки» тянет только 11-ю версию.

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

плюсы дают слишком большой простор, поэтому одни генерят «хайлевел», а другие - говнокод, и при этом обе стороны считают друг друга м*даками :)

Не так. Одни стараются писать хороший код, следят за его качеством и поддерживают/развивают его, а вторые пишут на от%бись. И не важно что из языка они используют.

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

у него владение плюсами где-то на уровне «пишу программы на Qt»

Так это проблема языка, а не моя.

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

C++ сейчас в роли догоняющего

Да ладно, вчера ради интереса решил посмотреть на функторы в Rust, и, правильно, они в unstable. Как и многое другое, что уже есть в С++. Причем далеко не все есть даже в unstable.

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

Модули, концепты (считай трейты), ranges, fmt. Это всё уже 5 лет как есть в расте. Почему бы и не из него.

Тогда уже из D, а не из раста, раст сам тут догоняющий.

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

Блин, какая незамутненность…

Модули,

Появились в Modula-2 и Ada еще в начале 1980-х.

концепты (считай трейты),

Которые до этого выпилили из C++11 из-за сырости. Т.е. работа над концептами полным ходом шла еще до того, как появился первый прототип Rust-а.

ranges,

Да, да. Седой Boost.Ranges из начала 2000-х как предтечу Ranges.v3 игнорируем. Зато Rust да, прям первоисточник.

fmt.

С корнями из Python-а.

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

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

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

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

Вы говорили:

Ну в C++20 добавили пару фич из раста, есть такое.

И на прямой вопрос что именно добавили дали вот такой перечень: «Модули, концепты (считай трейты), ranges, fmt.»

А я вам показал откуда ноги растут у этих фич. И это вовсе не Rust.

Вы же как тот студент, который выучил только вопрос про блох: раз есть в Rust-е, значит и в C++ они попали из Rust-а.

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

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

Вот так всегда, если его нет, значит оно не особо надо, а как выползет из unstable в stable, так наш Rust основа всех основ и у него все копируют.

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

Вы бы вместо того, чтобы свое скудоумие в очередной раз демонстрировать, лучше бы ответили за свои слова о том, что в C++20 какие-то фичи из Rust-а включили.

Но ведь конкретика и способность ответить за слова – это же не про RazrFalcon, как показывает история LOR-а.

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

Вы мне сами что-то приписали

раз: «Ну в C++20 добавили пару фич из раста, есть такое.»

два: «Модули, концепты (считай трейты), ranges, fmt. Это всё уже 5 лет как есть в расте. Почему бы и не из него.»

Надо полагать, что это не вы из-под своего аккаунта на LOR-е написали, а я вам приписал. Угу.

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

Да оно и сейчас не нужно.

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

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

А можно подробнее? Какой юзкейс функциональных объектов вы не могли бы заменить лямбдами?

У меня функция - полноценный объект с информацией о себе, который можно передавать в сиплюсный код, в питон или JS и использовать там как родную. С поддержкой именованных параметров, переменного числа аргументов, дефолтных значений и т.д. Все это умеет в статическую типизацию (на С++) с кастом связанных типов параметров/результата. Реализация может быть тоже на любом языке. На С++ это реализовано относительно просто и очень удобно. На Rust же даже выдергивание функции из скриптового языка это треш и угар (если подразумевается представить ее как родную).

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от eao197

лучше бы ответили за свои слова о том, что в C++20 какие-то фичи из Rust-а включили.

Вам нравится включать дурачка?

С практической точки зрения эти фичи появились в Расте раньше и этого достаточно.

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

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

и тут вдруг неожиданно именно те из них, которые есть в Расте

Так может думать только тот, кто дальше Rust ничего не видел. Во-первых все это было в D (откуда уже в С++ действительно попадали наработки), во-вторых «неожиданно» список изменений на этом не заканчивается, и там есть то, что Rust не умеет.

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

С практической точки зрения эти фичи появились в Расте раньше и этого достаточно.

Во-первых, бремя доказательств лежит на том, кто сделал утверждение. Кивок на то, что похожие вещи появились в Rust-е раньше таковым служить не может, ибо

Во-вторых, после не значит вследствие.

И, в-третьих, для концептов, ranges и fmt прекрасно известно их происхождение и прототипы, на которых они базируются. И это далеко не Rust. Происхождение модели модулей в C++ мне доподлинно неизвестно, но схожесть модулей из C++20 и модулей Rust-а нуждается в доказательстве. Которого пока ни RazrFalcon, ни вы привести не удосужились.

А в-четвертых, я не хочу, чтобы мне докучал настолько дремучий демагог, как вы, который даже не дружит с элементарной логикой. Поэтому вы идете в игнор.

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

Так может думать только тот, кто дальше Rust ничего не видел.

Чего не видел, модулей? Несерьёзно. Да даже если бы и не видел, вон eao197 перечислил языки, в которых это было, так что теперь я могу делать вид, что всегда об этом знал.

Во-первых все это было в D

А вот плевать всем на этот Д. О нём что-то слышали полторы калеки. Если уж сравнивать, то сравнивать с Java, на худой конец с C#, это языки достаточно популярные. Но и из них не особо-то спешили заимствовать, это вроде как другой мир, у них там сборка мусора и байткоды всякие, а у нас тут серьёзные люди серьёзный хайперформанс софт на плюсах пишут. Другое дело Раст, язык вроде как в ту же нишу метящий и с хайпом. И вот программисты посмотрели на него и спросили: «а что, так можно было?» И комитет, который до этого кормил завтраками и обещал подумать когда-нибудь потом начал довольно быстро наверстывать, причём именно в тех местах, где позорно отставать от выскочки. Разве не логично?

Ну а то, что именно в Расте модули, равно как и ограничение дженериков трейтами изобрели никто и не утверждал.

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

А вот плевать всем на этот Д.

«Все» не имеют никакого отношения к разработке языков.

вот программисты посмотрели на него и спросили: «а что, так можно было?» И комитет, который до этого кормил завтраками и обещал подумать когда-нибудь потом начал довольно быстро наверстывать,

Комитет активизировался начиная с С++11, тогда про Rust никто не слышал ничего. И эти возможности в С++ не с наскока добавили, их обсуждали, к примеру спецификация на концепты была утверждена уже в 2015-м.

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

Во-первых, бремя доказательств лежит на том, кто сделал утверждение. Кивок на то, что похожие вещи появились в Rust-е раньше таковым служить не может, ибо

Во-первых, есть такая мудрость, что докопаться можно и до столба. РазрФалкон сообщил, что использовать кресты не имеет смысла, так как новые фичи появляются там с запозданием относительно Раста. Про заимствование упомянул мимоходом и, видимо, не горит желанием вам что-то доказывать. Поэтому с практической точки зрения важно только время появления, если б вы не решили включить дурачка, то никакого спора бы и не было, все поняли бы его правильно.

Во-вторых, после не значит вследствие.

Да-да-да, можно бесконечно требовать от оппонента доказать каждое из его высказываний, попутно ссылаясь на «бремя доказательства», «после не значит вследствие», «ложная дихотомия» и «strawman argument» и гарантированно ему надоест и он пошлёт. Однако это не отменяет факта, что вы просто валяете дурака. Вы надеетесь не на то, что оппонент не прав, а на то, что он не сможет сформулировать так, что вам не удастся ткнуть куда-то и сказать, что в этом месте доказательство слабое.

Вот не верю я, что может реально существовать человек, который всерьёз считает, что лайфтаймы с GSL чисто случайно запилили после того как появился Раст, ну а если принять, что лайфтаймы сделали под влиянием, то нет никаких причин не верить что и остальное добавили чтоб не отставать. Да, доказать такое невозможно, о том, что не хватает модулей говорили ещё когда Раста в проекте не было, и на наркоманские сообщения об ошибках при разворачивании шаблонов давно ругались, только что-то 20 лет на это забивали, а тут вдруг пропёрло.

И, в-третьих, для концептов, ranges и fmt прекрасно известно их происхождение и прототипы, на которых они базируются. И это далеко не Rust.

А вот это чистой воды strawman argument, никто не утверждал, то эти штуки изобрели в Расте. Так что рано вы начали обзываться «демагогами», как бы самому таким не оказаться.

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

«Все» не имеют никакого отношения к разработке языков.

Извините, это так не работает.

Вот выпускает какая-то фирма новую штуку, и разоряется. А потом, через 10 лет, выходит новый айфон с подобной штукой, и через 2 года это есть везде, во всех телефонах, от самсунга до последнего китайца. Так откуда эту штуку содрали, с айфона, или с того, старого продукта, который сгинул?

Те, кто разрабатывает языки, они много что знают, они и в начале 80х слышали, например, про лямбды и всякую функциональщину, однако добавлять во все языки начинают не тогда, когда узнают разработчики языков, а когда это появляется в популярном языке, люди узнают и появляется спрос. Поэтому D вообще не канает. Если кто-то скажет, что авторы крестов реализовали некую не сильно сложную фичу 1в1 как в D, реализовали после D, но реализовали независимо и это просто совпало, я сочту это более правдоподобным чем то, что они не догоняли Раст в 20м стандарте.

Комитет активизировался начиная с С++11, тогда про Rust никто не слышал ничего. И эти возможности в С++ не с наскока добавили, их обсуждали, к примеру спецификация на концепты была утверждена уже в 2015-м.

Тут другой вопрос: когда бы это было? Обсуждать можно долго, и спецификация, готовая в 2015м может, например, не войти в C++17, почему бы ей войти в C++20, а не быть отложенной до C++23?

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

Опять же, в расте к этому стараются аккуратно подходить: новые фичи обкатываются в найтли (временами весьма долго)

Тут другой вопрос: когда бы это было? Обсуждать можно долго, и спецификация, готовая в 2015м может, например, не войти в C++17, почему бы ей войти в C++20, а не быть отложенной до C++23?

в расте долго обкатывают новые фичи - хорошо. В плюсах долго обкатывают новые фичи - плохо. Понимаю.

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

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

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

в расте долго обкатывают новые фичи - хорошо. В плюсах долго обкатывают новые фичи - плохо. Понимаю.

Ну передёргивание же.

А вообще это от конкретной фичи зависит. Если это что-то, что можно в библиотеке реализовать, то и в С++ оно будет реализовано (в бусте, например). Если это что-то более глобальное, то, как правило, в расте это будет проще пощупать.

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

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

в расте долго обкатывают новые фичи - хорошо. В плюсах долго обкатывают новые фичи - плохо. Понимаю.

Речь не о хорошо или плохо, а о том как оно есть. Практика показывает, что комитет C++ может сиськи мять десятилетиями.

Меня лично во всей этой фигне смущает даже не факт отставания, а то, что делают чисто для галочки. Понятно, что обратная совместимость, все дела, но не оставляет чувство, что все понимают, что реально пользоваться не будут, типа «а у нас тоже есть фича X! А теперь го выделять память маллоком».

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

В расте, долго - это годик, а не 5-10 лет как в плюсах. Оно-то и понятно, у них ответственность выше. Но если у людей нет необходимости поддерживать легаси - то проще использовать современные языки.

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

То есть, пошел переход на личности, а по существу вопроса ответить нечего. И не мните себя в роли экзаменующего - это не Ваше.

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

расте, долго - это годик, а не 5-10 лет как в плюсах.

Раст еще не дорос по возрасту. При этом упомянутые мною фичи висят с 2015 года. Можно было бы сказать, что совпадение, но они ж не одни такие.

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

В расте, долго - это годик, а не 5-10 лет как в плюсах

я просто напомню, тема началась с бага, который в расте не могут пофиксить уже 5 лет. Причем бага в самой рекламируемой фиче языка, UB за пределами unsafe-блоков. Компилятор даже варнинг не показывает, лол.

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

То есть, пошел переход на личности

Вот это:

Увы, это просто ужас-ужас-ужас, а не концепты. Смешно, будто бы код с концептами C++20 понять проще! Причем человеку, который успел довольно плотно поработать с C++, эпизодически, но очень плотно.

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

а по существу вопроса ответить нечего.

По существу чего?

Вот у меня есть впечатление, что вы на C++ эпизодически пытаетесь писать как на Haskell-е или как на каком-нибудь Lisp-е. Отсюда и ваша боль.

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

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

РазрФалкон сообщил, что использовать кресты не имеет смысла, так как новые фичи появляются там с запозданием относительно Раста. Про заимствование упомянул мимоходом и, видимо, не горит желанием вам что-то доказывать.

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

Ничего личного, но ты первый начал нести чушь.

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

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

void f(T)(T value) if (is(T == int)){
    value.writeln;
}
SR_team ★★★★★
()
Ответ на: комментарий от RazrFalcon

Я и не утверждал обратное.

Ок, принято.

И в расте ограничение идёт по трейтам, а не по типам.

Типы используются в приведенном мной примере и типами в D тоже все не ограничено.

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

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

А мне кажется, что С++ и Rust достаточно похожие языки…

https://imgur.com/a/zwYYHfA

https://youtu.be/olM7o_oYML0

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

Дополню комментарий мнением царя на этот пример, а то тред закрыли от анонов :(

https://imgur.com/a/DM1yIHQ

Ну и повторюсь, на С++ можно писать по разному, но если хочется как на Rust, то получается по-моему довольно похоже…

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

Вы видимо в какой-то || реальности живёте ^_^

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

Ахахаха )) А может не из раста а в принципе из парадигм программирования, отвязанных от любого языка? ))

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

В чем-то похожи, но разница есть. Это чувствуешь, когда у тебя многие методы являются полиморфными, т.е. там генерики, а типы генериков подпадают под различные ограничения трейтов. Короче, это сложно описать без примеров, а подходящих для ЛОРа примеров у меня нет (нафиг не сдалось тут что-то такое писать). А то, что ты привел, это слишком банальный код, в котором пока не увидел ничего интересного.

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

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

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

но ведь по ссылке и правда код так себе. Там даже концепты не нужны - тупо наследуемся от чего-нибудь вроде

struct DynShape {
  virtual double area() const = 0;
  virtual double perimeter() const = 0;
  friend auto area_per_perimeter(const DynShape& shape) {
    return shape.area() / shape.perimeter();
  };
  virtual ~DynShape() {}
};

, и все.

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

При чём тут код? Царь не умеет себя вести, постоянно мечет в людей г*вно и вообще считает себя «илиткой», а остальных плебеями. Ну ни о чем с таким шизиком можно конструктивно общаться?

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

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

Как бы в C++ полиморфность можно реализовать и на обычном ООП. И, в простых случаях, вообще на перегрузке функций/методов под нужные типы параметров.

При таких возможностях далеко не всегда нужно прибегать к обобщенному программированию.

Короче, это сложно описать без примеров, а подходящих для ЛОРа примеров у меня нет (нафиг не сдалось тут что-то такое писать).

«У нас есть такие приборы, но мы их вам не покажем» (с)

А тот, кто смеет не верить некому @dave с LOR-а на слово, тот «надоедливая муха» и «типа эксперт», поэтом разговаривать с ним не о чем.

Позвольте у вас спросить @dave, который хз кто хз откуда, т.к. в вашем профиле о вас ничего нет: как можно узнать что вы вообще программировать умеете? По крайней мере на С++.

Ну вот не сочтите это за наезд, а просто подумайте сами: откуда?

Или может на LOR-е теперь принято верить на слово? Типа поверим на слово RazrFalcon-у что в C++20 включают фичи из Rust-а. И еще больше поверим хрюнделю, который утверждает, что RazrFalcon ничего подобного не говорил (а ведь он говорил).

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

И да, это пока без учета концептов, но мне кажется, что с ними сильно намудрили.

Концептов не пробовали, но они «ужас-ужас-ужас». Пастернака не читал, но осуждаю.

Ужас-ужас-ужас – это пятиэтажные SFINAE в коде. Или надобрость писать static_assert-ы в обобщенных функциях чтобы как можно раньше диагностировать несоответствие типов.

Вряд ли вы с этими настоящим ужасами сталкивались, поэтому для вас концепты, которые все это приводят в норму, выглядят как «ужас-ужас-ужас».

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

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

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

Как бы в C++ полиморфность можно реализовать и на обычном ООП. И, в простых случаях, вообще на перегрузке функций/методов под нужные типы параметров.

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

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

В контексте генериков я применил самое подходящее значение для этого термина, а именно то, как это принято в хаскеле

Повторю то, что уже говорил раньше:

Вот у меня есть впечатление, что вы на C++ эпизодически пытаетесь писать как на Haskell-е или как на каком-нибудь Lisp-е. Отсюда и ваша боль.

С++ – это С++, не Haskell, не Rust, ни Common Lisp. На C++ нужно программировать как на C++.

Но вы, видимо, пытаетесь делать это как вам привычнее из Haskell-я.

Нет, я больше препираться с тобой не хочу. Поэтому извини, дальше не стал тебя читать.

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

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

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

Евгений, вы тут тоже хороши, на самом деле. Вы регулярно включаете снисходительно-вежливый старперский стиль, который многим (осознанно или инстинктивно) не нравится. Я понимаю, что вам, скорее всего, больше лет, чем многим тут, но не надо тупо «давить авторитетом» и намекать оппоненту, что он лох с С++, т.к. лично вы его код не видели. Я вот ваш код видел и не могу сказать, что в восторге :)

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

он лох с С++

Сказать, лох ли он в C++ или нет формально нельзя. Речь о том что он лох в общении

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

плебея от царя я как-нибудь переживу, чай не обидчивый

А смысл? Лично мне фильтровать его поток фекалий ну совсем не интересно.

А вот когда тебе без всяких аргументов пытаются заткнуть рот, как принято в (особенно буржуйском) раст-комьюнити, - тогда да, конструктивное общение действительно невозможно.

Сам такого не видел, но если это имеет место быть, то ничего хорошего, конечно.

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

Я вот ваш код видел и не могу сказать, что в восторге :)

А это и есть цель, по сути-то. На основании того, что вы видели вы составляете себе некий коэффициент доверия к моим словам. И когда я что-то говорю, типа «на C++ных шаблонах это делается элементарно» или «в С++ это будет геморройно», то вы сможете понять насколько это просто/сложно будет для вас (или насколько вы захотите вляпываться в подобный код).

Или вот взять RazrFalcon. Я понимаю, как относиться к его словам про C++. При этом я видел его Rust-овский код. И когда RazrFalcon говорит что-то про Rust, то у меня нет оснований не воспринимать его мнение всерьез. Возможно, с чем-то я буду несогласен, но точно буду знать, что под сказанным есть основание. Хорошое такое основание.

Тогда как со словами dave непонятно что делать. Сразу в /dev/null или же посчитать что в них есть рациональное зерно.

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

плебея от царя я как-нибудь переживу, чай не обидчивый.

+1

Кстати, если кому интересно, ликбез царя на тему концептов и С++ и переписанный код примера:

https://godbolt.org/z/HTU2RX

И немного ответов:

https://pastebin.com/raw/XbNh10p3

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

Нифига сколько тут говноедов поклонников шизоЦаря

https://godbolt.org/z/HTU2RX

Почему он не используется в остальных языках? Всё очень просто - не осилили.

Ну т.е. Гугль со своим Go или Apple с Swift имея охрененные ресурсы и «ниасилили»? Отдаёт шизой.

никакого обобщённого программирования нигде и нет, кроме С++

скритпухи типа хаскеля

получается такая система, которой ненужны никакие аннотации, никакие интерфейсы. Если код собирается - он весь удовлетворяет друг другу. Адепты всякого мусора будут пытаться вас убедить, что какие-то концепты нужны в С++ для каких-то ограничений. Что какие-то ограничения нужны для чего-то. Нет. Они нужны скриптухи - С++ же может без них. И может максимально хорошо. Добиться подобного используя мусорные подходы в принципе невозможно. Почему я уже говорил.

У кого-то ещё есть сомнения в невменяемости поцЫэнта?

Именно поэтому решение одно … Этот подход используется в С++

И эти люди ещё что-то говорят про сектантов :)

элементры

интерфесы

Попытатки

урощения

фундементальное

нелпое

Бл*, кто-нибудь, подарите ему глаза или спелл-чекер.

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

Мне интересно, кто-нибудь смог осилить поток сознания из комментариев в примере кода с godbolt-а? Я сломался на втором или третьем абзаце.

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

все конечно круто, но разве в std::function под капотом не тот же самый type erasure с вызовом виртуальных методов?

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

все конечно круто, но разве в std::function под капотом не тот же самый type erasure с вызовом виртуальных методов?

Ну и царь говорит, что static dispatch лучше:

// правда такой подход, что бы о нём не говорила адепты, такое же говно как и наследование. Проблема фатальна - он затирает типы. В скриптухе на типы покласть, но не в С++.
// По этой причине в С++ везде где можно используется статический диспатч, а где нельзя - почти везде он заменяется на вариант, который типы не затирает. 

а вот его ответ: https://pastebin.com/raw/UvRvt563

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

Ну пипец тебе нечем заняться, как работать ретранслятором :)

потуги балабола

Царь обещал запили блог на C++-движе и обосрался. И кто тут балабол? :)

Для тех, кто не в курсе, Царь - шизоид из Красноярска, работает в СФУ:

http://ikit.sfu-kras.ru/e/166

Ромка работает в зарсра*ом вузе быдло-доцентом, читает «лекции» и пишет статьи во всяком г*вне уровня Scopus (кто знает, тот поймёт). Вне СФУ он никто и звать его никак.

Помимо этого товарищ всезнайка ведёт «курсы» по то, «как опубликовать говно, чтобы пролезло» в типа рецензризуемых «журналах»:

https://rtsarev.ru

Серьёзно воспринимать этого спецЫализда - себя не уважать. За всё время г*номентания на ЛОРе он так и не дал ссылку ни на один свой проект, чтобы местное население смогло, наконец, приобщиться к «высокому искусству» программирования на «настоящем C++».

htower_ ★★
()
Последнее исправление: htower_ (всего исправлений: 1)
Ответ на: комментарий от fsb4000

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

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

Насколько это точно?

На 100% не уверен, но на ЛОРе уже проскакивали посты про «царя из Красноярска». Я лично с ним (Царёвым) не общался, а вот у коллег был опыт. Список публикаций вполне «погромистский», так что думайте/решайте сами :)

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

Этот факт придает больше смысла тому бреду, который он тут пишет?

Нет, конечно :)

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

Текст же, даже скипая часть слов получается быстрее чем смотреть видео. А вроде тут многим нравится смотреть доклады по С++/другим языкам.

Да и не дело в царе. Дело просто в каких-нибудь тезисах. Вот например у Александреску есть похожие мысли относительно концептов: что все возможности концептов уже есть в С++, и что этому уделяется слишком много внимания и потратили много ресурсов на это, а нужно было развивать интроспекцию/рефлексию.

Ну пипец тебе нечем заняться, как работать ретранслятором :)

@htower_, да, нечем. Смотрю КВН: https://www.youtube.com/watch?v=TcBBghFIt2A

Да и ответы на pastebin проще скипнуть чем целые посты от анонимуса, если они вам совсем неинтересны.

А я и @stasolog и может ещё кто почитаем…

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

Всё больше убеждаюсь что раст вы в глаза не видели, раз пишете такую чушь.

Расту же хуже от этого :)

Я посмотрел вот этот курс по расту: https://www.youtube.com/watch?v=Oy_VYovfWyo&list=PLlb7e2G7aSpTfhiECYNI2EZ1uAluUqE_e

почитал растбук и растомикон. И немного пописал хелло вордов на https://github.com/hecrj/iced

Не претендую на гуру раста, просто могу читать закорючки и они имеют какой-то смысл для меня :)

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

могу читать закорючки и они имеют какой-то смысл для меня :)

Срочно пишите резюме в Apple, они как раз сейчас набирают rust-программистов в новый проект :)

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

Текст же, даже скипая часть слов получается быстрее чем смотреть видео. А вроде тут многим нравится смотреть доклады по С++/другим языкам.

Ты серьезно сравниваешь доклады на больших конференциях типа CppCon с постами «говно-говно» на LOR?

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

Да и не дело в царе. Дело просто в каких-нибудь тезисах. Вот например у Александреску есть похожие мысли относительно концептов: что все возможности концептов уже есть в С++, и что этому уделяется слишком много внимания и потратили много ресурсов на это, а нужно было развивать интроспекцию/рефлексию.

зачем плюсам интроспекция/рефлексия? хоть одну толковую причину приведите.

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

Я посмотрел вот этот курс по расту: https://www.youtube.com

facepalm.bmp

Не удивительно, что ваши попытки сравнивать C++ и Rust выглядят нелепо. Как в прочим и 95% критики раста.

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

Я понимаю, как относиться к его словам про C++.

Я C++ только за деньги пишу =)

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

Если уж нравится ютуб, то был нормальный ролик со сравнением концептов C++ и Rust: https://www.youtube.com/watch?v=olM7o_oYML0

PS: сам не смотрел, ибо не перевариваю видосы, но хвалили

RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от alysnix

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

UPD: Еще логгер, от которого ссут кипятком в конфе по D, можно отличный написать

SR_team ★★★★★
()
Последнее исправление: SR_team (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Спасибо, но я не интересуюсь мнением сумасшедших.

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

Сейчас в плюсах, чтобы отобразить содержимое какого-то объекта в лог (на консоль) нужно вручную написать для него operator<<. В том же D это делается посредством рефлексии.

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

зачем плюсам интроспекция/рефлексия? хоть одну толковую причину приведите.

Сама по себе рефлексия в C++ не так уж и полезна. Даже к самой часто упоминаемой сериализации/десериализации на базе рефлексии есть ряд вопросов.

Но вот предложения от Саттера по этой теме содержат не только рефлексию, но и возможности по генерации нового плюсового кода прямо в комплайт-тайм. И вот это открывает широкие возможности для построения различных DSL-ей.

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

Может там и еще чего. Но вот я от D-шников именно такой пример касательно логирования слышал.

Еще вроде в D сериализацию/десериализацию в JSON через рефлексию в vibe.d делают (если мне склероз не изменяет).

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

зачем плюсам интроспекция/рефлексия? хоть одну толковую причину приведите.

«Экспорт» классов и функций в скриптовые языки, да и просто байндинги к сиплюсным библиотекам.

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

Кстати, если кому интересно, ликбез царя на тему концептов и С++ и переписанный код примера:

https://godbolt.org/z/HTU2RX

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

Если кратко то:

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

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

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

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

В общем, нельзя сказать что вообще 100% бред, 5% текста осмысленны. Действительно, трейт != концепт. Критика трейтов вполне вменяема, однако поверхностна и до Царя эти проблемы разбирали люди и поумнее и более внятно. Ну и, как бы, если у трейтов есть проблемы, это ещё не значит, что вариант «забить, скомпилялось и ладно» лучше. У ручного назначения трейтов как бы тоже есть достоинства, тем более когда можно назначить трейт чужому типу. Ну и несколько сомнительна идея Царя о том, что в Расте, где, как сам Царь заметил, нет перегрузки и, соответственно, проблем с поиском нужного дженерика, нельзя было запилить instantiation-time утиную типизацию. В конце концов рядом лежат макросы, которые тупо генерят код, вырезать тело дженерика и обернуть в макрос - вот и получишь примерно ту же instantiation-time утиную типизацию. Как бы даже если Царь это в полемическом угаре написал, ну, блин, хоть немного-то надо о правдоподобии думать, если не совсем дурачок.

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

Да читал. Кстати вот ответ тебе если интересно:

https://pastebin.com/raw/ZxXiWkhJ

И объяснение для студентов:

https://pastebin.com/raw/sA8PYg71

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

и примеры:

https://godbolt.org/z/YbGXwo

https://godbolt.org/z/zGxQu9

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

В gsl есть narrow, есть не хватает проверки при инициализации

Все уже было в Симпсонах есть в boost. Но по факту С++ тут такой же кривой как и Rust. Можно долго с пеной у рта доказывать, что эти преобразования задокументированы, есть альтернативы и т.д., но по факту на лицо возможная потеря/порча данных при преобразовании. Причем непонятно, что мешало авторам Rust сделать такие преобразование сразу правильно, например, если человек хочет явно кастануть signed в unsigned и забить на проверки, то пусть делает это только в unsafe.

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

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

Хотелось бы, чтобы ТС продвинулся в познании Раста чуть дальше. Чтобы, так сказать, разоблачить Раст по-полной. Еды в девелопменте не хватает :).

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

Непонятно одно: зачем ты тут надрываешься и портянки текста производишь.

Решил поддержать единомышленника? У меня 200 сообщений, у тебя за 5000. Подумай сам, кто тут надрывается.

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

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

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

У меня 200 сообщени

Дата регистрации: 11.11.19

у тебя за 5000

Дата регистрации: 07.10.11

Не так уж и много за 9 лет. почти 2 сообщения в день. У тебя так же

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

Не так уж и много за 9 лет. почти 2 сообщения в день. У тебя так же

Ну он же сюда как на работу ходит. А, к примеру, предыдущее его сообщение это просто тупняк и мусор:

Объясните про аннотации типов сложных объектов в Python (комментарий)

П.С. посмотрел остальные комментарии, он просто агрессивный и малограмотный неадекват, в игнор.

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от Serral

если человек хочет явно кастануть signed в unsigned и забить на проверки, то пусть делает это только в unsafe.

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

Как по мне, ансейф тут не нужен, но преобразование через as сделано действительно не идеально. Но всё-таки прям всё и сразу предусмотреть маловероятно. Тут более показательно будет дальнейшее развитие языка. Если на as предупреждение будет выдавать, то отлично, проблемы не вижу. Впрочем, уже сейчас в клиппи есть пачка линтов на тему кастов. При желании можно вообще запретить as.

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

Если на as предупреждение будет выдавать, то отлично, проблемы не вижу.

Если оно будет по умолчанию, согласен.

Впрочем, уже сейчас в клиппи есть пачка линтов на тему кастов. При желании можно вообще запретить as.

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

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от Serral

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

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

В защиту раста скажу, что клиппи - инструмент почти стандартный. Правда по умолчанию не все линты включены.

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

объяснение для студентов

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

i-rinat ★★★★★
()
Ответ на: комментарий от Serral

У меня 200 сообщений, у тебя за 5000. Подумай сам, кто тут надрывается.

Так ты поди без году неделя зареган, счетовод, лол. Дальше не читал — против аргументации, подкрепленной статистикой, мне нечего предложить 😆.

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

Не стоит пытаться достучаться до упоранта. @Naserral из таких.

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

Да читал. Кстати вот ответ тебе если интересно:

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

И объяснение для студентов:

Тут могу дать Царю ещё один совет. Смешной препод, которого не воспринимают всерьёз и потому которому не возражают, может этого не понимать, но вообще, перед тем как что-то объясняешь следует подумать о том, кому и зачем.

Если объясняешь тому, кто и так знает, то наверное не стоит время тратить. Если объясняешь тому, кто не знает, то надо объяснять так, чтоб поняли и поняли правильно. Особенно если объясняешь сектанту скриптухи, он ведь докопается до любой неточности. Вот конкретно в этом тексте Царь заявляет, что дженерики работают через vtable и тратит много времени на объяснение type erasure. Это неправда. Так дженерики работают только в Java и, в ограниченном числе случаев, в C# (параметр дженерика не должен быть структурой). Если в C# в качестве параметра передан value-type, то генерится собственный экземпляр. Когда дело касается Раста, то никакого vtable в дженериках там и в помине нет, vtable в Расте бывает только у функций, принимающих ссылку на трейт, тогда передаётся жирный указатель, состоящий из указателя на структурку и указателя на втейбл. В случае дженерика, естественно, никакой виртуальщины, честная инстанциация. Можно говорить о некотором аналоге еразуры только в отношении лайфтаймов, там да, если один раз вызвать функцию-дженерик для структуры со статическим лайфтаймом, а потом для такой же структуры в стеке, то вызовется одна функция. Но для всех комбинаций типов генерится собственный экземпляр, всё как в плюсах. Да и по-другому и быть не может, как запихать внутрь структуры другую структуру, не зная её размера? Аналогично с функциями, для создания переменных на стеке надо знать размер, надо знать, реализует ли конкретно этот тип Drop.

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

Момент, который я в прошлом ответе опустил, и потому Царь ещё не начал от этого отнекиваться - это критика веры Царя в пользу анализа тел функций. Он реально думает, что это достоинство плюсов, а не атавизм времён первых экспериментов «C с классами» через препроцессор. Дело в том, что, вопреки вере Царя, Раст - это не язык для лабораторок. По крайней мере при проектировании так считали. Авторы языка считали, что проекты на Расте будут крупными, будут жить и развиваться долго, и будут активно подключать сторонние библиотеки. Поэтому анализ тела функций прямо противопоказан, поэтому лайфтаймы и вынесены в сигнатуры функций и поэтому язык с отличным выводом типов внутри функции не добавил простейшую фичу вывода типа возвращаемого значения (точнее добавил в сильно ограниченном виде impl trait). В cигнатуре функции описывается полный контракт и язык не позволяет делать никаких поблажек на основании текущего кода в теле функции или вокруг места вызова. Идея в том, что пока контракт не меняли, всё должно быть работоспособно и не зависеть от обновлений библиотек или изменения собственного кода.

При написании лаб и курсовиков да, это мешает.

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

Ну в общем, судя по тому, как упорно Царь начал отмазываться от косяка с vtable, при этом не поддался на уговоры использовать нормальный термин «интерфейс», он реально думал, что там динамический вызов происходит и теперь боится признаться. Ещё и врёт, типа он говорил про «семантический vtable» при том, что это сочетание он составил, видимо, глядя на мой текст. Типа он не знает, что vtable - это описание реализации, а интерфейс - это общеупотребимый термин.

Ну ок. Дальше идёт пурга, где он пообещал разобрать потуги с атавистичными шаблонами в C++… но сделает это в другой раз.

Далее пошло обычное для идиотов нытьё про то, что на Расте только лабы пишут, что совершенно мимо кассы, пусть бы на нём вообще 1 единственную программу «хелло уорлд» написали бы, это никак не отменяло бы мотивацию проектировщиков языка. Думаю, даже такой необезображенный интеллектом чувак как Царь не станет отрицать, что авторы Раста мечтали о серьёзной разработке (про то что он уже не стану пугать беднягу).

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

Ну и про отсутствующий вывод типа:

use core::fmt::Debug;
use std::vec::Vec;
use std::convert::From;

fn foo<T:Debug>(bar: &T) {
    println!("bar == {:?}", &bar);
}

fn main() {
    // параметры дженерика выведутся
    let mut v1 = Vec::new(); // выводится тип v1 и v2, при том что справа от = тип неизвестен
    let mut v2 = Vec::new(); 
    v1.extend(
        (1..=5).map(
            |i|{
                v2.push(i); // автовывод типа v2  это Vec<i32>. Автоавывод из побочного эффекта замыкания!
                12.0 // автовывод возвращаемого значения f64 и, соответственно v1 Vec<f64>
            })
    );
    v2.extend(
        (10..=15).map(
            |i| {
                // v1.push(i); // нельзя запихать i32 в вектор с f64
                v1.push(From::from(i)); // но можно автоматически выбрать конвертер через имплементацию трейта
                  // From<i32> для f64
                i
            }
        )
    );
    foo(&v1); // тут можно переключить в отображение llvm-ir
    foo(&v2); // и убедиться, что это разные функции
    
    // v1 = v2 // ошибка. Чтоб глупый Царь не нёс пургу про то, что тут затирание параметра происходит
}

Конечно, бывают языки и с лучшим выводом типа, но это не C++ и ему подобные.

Как даже Царь может убедиться, автовывод возвращаемого значения в Расте есть, но только там, где не помешает, в лямбде например.

Вообще, самое грустное, что Царь вообще неспособен сопоставлять 2 своих утверждения, именно поэтому у него так подгорело, когда я показал, что его восхваления концептов в плюсах, если их поставить рядом, говорят о кривом дизайне языка. С темплейтами/дженериками та же фигня получается. Я объяснил ему, что авторы Раста не могли «не осилить» шаблоны как в плюсах, шаблоны из плюсов как раз самые простые в реализации, в Расте уже есть макросы, которые фактически делают то же самое. Царь увидел только слово макрос и завёл свою пластинку про недоязык, которому понадобились макросы. Он уже начисто забыл, что до этого ему не нравились нормальные дженерики с проверками типа и он топил за макроподобные.. даже не дженерики, а шаблоны из плюсов. Он реально не понимает проблемы, когда с одной стороны тело шаблона чуть ли не копипастится в исходник, авось соберётся, но при этом в объявлении 3 этажа из всякой enable_if.

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

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

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

не знаю, что там считали авторы раста, но о маштабах проектов думали при проектировании ады. масштабные проекты не особо задумываются о «времени жизни переменных внутри одного треда». а состоят из многих процессов, раскиданных по ядрам, по сети и где угодно. для языка масштабных проектов важно описание взаимодействия процессов, способы декомпозиции, инкапсуляции, обеспечения общей устойчивости и проч…

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

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

в русте нет нормального опп. а приколы со временем жизни переменных - вешь мало кому нужная.

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

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от khrundel

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

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

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

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

stasolog
()
Последнее исправление: stasolog (всего исправлений: 1)
Ответ на: комментарий от khrundel

Думаю, даже такой необезображенный интеллектом чувак как Царь не станет отрицать, что авторы Раста мечтали о серьёзной разработке

Наверное поэтому автор Раста ушел писать Swift.

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

Так будет просто добавлено ограничение и точно так же перестанет собираться, ничего не поменяется. Разве что будет более вменяемое сообщение об ошибке, что плюс, но не больше. Ну и говорить о серьезности, объемах и стабильности в случае Rust не приходится, т.к. он не умеет в то, что умеют все - в ABI. В С++ (C/Java/C#/etc.) можно собрать либу и отдать людям, а раст требует постоянной пересборки всего и вся.

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

умеют все - в ABI

В С++ (C/Java/C#/etc.) можно собрать либу и отдать людям, а раст требует постоянной пересборки всего и вся.

У C++ нет стабильного ABI.

RazrFalcon ★★★★★
()
Ответ на: комментарий от Serral
  1. https://wiki.gentoo.org/wiki/Upgrading_GCC#libstdc.2B.2B.so.6:_version_.60GLIBCXX_3.4.15.27_not_found
  2. А можно скачать Qt для MSVC и пытаться использовать его из mingw, но ничего не выйдет.
RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

У C++ нет стабильного ABI.

https://itanium-cxx-abi.github.io/cxx-abi/abi.html

Можно скачать Qt и линковаться к нему хоть на CentOS, хоть на Ubuntu. При этом можно взять gcc, clang или icc.

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


https://wiki.gentoo.org/wiki/Upgrading_GCC#libstdc.2B.2B.so.6:version.60GLIBCXX_3.4.15.27_not_found

Так и с GLIBC та же история, и там же написано, что C++ ABI обратносовместимое.

А можно скачать Qt для MSVC и пытаться использовать его из mingw, но ничего не выйдет.

Это и с С не сработает, проблема языков у которых больше одной реализации, Rust до такого не дорос и вряд ли дорастет.

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Прекрасно сработает.

Не сработает, слинковаться то оно слинукется, а в рантайме вылетит. Я из-за этого quickjs от гнусизмов чистил, чтоб в вижуале использовать.

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

Пруфца бы.

Это то, что я нашел и исправил:

#if defined(__x86_64__) || defined(__aarch64__)
#define JS_PTR64
#define JS_PTR64_DEF(a) a
#else
#define JS_PTR64_DEF(a)
#endif

#ifndef JS_PTR64
#define JS_NAN_BOXING
#endif

...

#elif defined(JS_NAN_BOXING)

typedef uint64_t JSValue;

...

#else /* !JS_NAN_BOXING */

typedef union JSValueUnion {
    int32_t int32;
    double float64;
    void *ptr;
} JSValueUnion;

typedef struct JSValue {
    JSValueUnion u;
    int64_t tag;
} JSValue;

Думаю ты поймешь. Но там есть еще и разные рантаймы, разные malloc/free, разные выравнивания могут быть и т.д. А еще на это могут влиять параметры компиляторов, которые могут еще и быть переопределены в коде. Опять же всякие директивы препроцессора. В общем на чем-то из этого оно продолжало валиться. Авторы библиотек в принципе могут стараться делать их совместимыми, но если на это изначально наплевали, то фиксить это после каждого обновления - сизифов труд.

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от RazrFalcon

Это всё замечательно, но ABI тут не при чём. Тем более аллокаторы.

Это все замечательно, но кто сказал, что ABI тут при чем?

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

У вас очень короткая память.

Нет, у тебя:

Rust и типобезопасность (комментарий)

А можно скачать Qt для MSVC и пытаться использовать его из mingw, но ничего не выйдет.

Это и с С не сработает, проблема языков у которых больше одной реализации,

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от O02eg

А чем для Rust https://crates.io/crates/abi_stable не подходит?

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

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

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

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

И это не совсем троллинг. Есть проекты на C++ до сих пор в продакшн и генерирующие мега прибыль, которые о >=C++11 ничего не слышали, STL игнорируют полностью (слышу, как революционеры одного хелловорлда кричат с галерки: «это не C++!!!», но кого из цивильных людей волнует их мнение…). И те весьма немногочисленные классы на шаблонах, которые таки используются, можно без особого труда переписать на конкретные явные специализации.

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

Есть проекты на C++ до сих пор в продакшн и генерирующие мега прибыль, которые о >=C++11 ничего не слышали

Есть такие проекты и на С, и на FORTRAN и на PL/1. Да и многие холиварщики втихую пишут себе на JS, C++, C# и т.п., а на форумы ходят рассказать про прелести Rust, CommonLisp, Erlang и прочего разного интересного.

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

Есть такие проекты и на С, и на FORTRAN и на PL/1.

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

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

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

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

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

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

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

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

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

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

Нет.

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

Так будет просто добавлено ограничение и точно так же перестанет собираться, ничего не поменяется. Разве что будет более вменяемое сообщение об ошибке, что плюс, но не больше.

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

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

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

Ну это по сути тоже самое, только другими словами. Большинство фич в попсовых языках добавляют только для программистов (внезапно), чтоб им было сухо и комфортно. Вот взять какой-нибудь Kotlin - ну вкусно же, вкусно, и начать писать на нем можно просто сразу, без особой подготовки. И джависты тоже в восторге. Но можно ли представить, чтоб в нем сделали управление памятью как в Rust? Очевидно нет, такие «фичи» нужны только тем, кто ставит удобство и скорость разработки ниже чем эффективность и корректность. А это далеко не все.

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

масштабные проекты не особо задумываются о «времени жизни переменных внутри одного треда».

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

для языка масштабных проектов важно описание взаимодействия процессов, способы декомпозиции, инкапсуляции, обеспечения общей устойчивости и проч…

И всё это реализует Раст как минимум не хуже плюсов, именно за счёт семантики заимствования.

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

Ну, как бы тему дженериков выбрал не я, я лишь слежу за полётом мысли Царя.

в русте нет нормального опп. а приколы со временем жизни переменных - вешь мало кому нужная.

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

никто не видит чужих кишок, и не занимается анализом времен жизни чужих кишок в своем контексте.

И это тоже неверно. Кишки периодически выдаются, почти любая библиотека/фреймворк на C/C++ имеют функции для получения/освобождения разных объектов, даже когда получаемое и освобождаемое представляет собой просто буферы памяти. Аналогично на приём, очень много лишней работы происходит просто от того, что в современных языках нет возможности сообщить о том, что данный объект отдаётся навсегда.

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

Наверное поэтому автор Раста ушел писать Swift.

Он молод и ему нужны деньги. Кстати, на форониксе была новость о том, что Эпол ищет раст-программистов. Так что им одного Хоара мало.

Так будет просто добавлено ограничение и точно так же перестанет собираться, ничего не поменяется.

Почему бы тогда не придумать, что автор либы просто возьмёт и сломает, ну чисто по приколу?

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

а раст требует постоянной пересборки всего и вся.

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

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

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

Вот есть Qt 4.4.3 https://download.qt.io/archive/qt/4.4/qt-win-opensource-4.4.3-mingw.exe

Он собран gcc 4… И исходники не соберутся без правок на gcc 9.

Но можно свою программу на Qt слинковать с этим Qt 4.4.3 и программа будет работать…

А в Rust можно использовать какую-нибудь либу времён Rust 0.10 на которую автор забил, и которая не соберётся текущим растом? Насколько я понимаю нет, в этом и ценность ABI.

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

Кстати, на форониксе была новость о том, что Эпол ищет раст-программистов

Сюда ее ес-но уже притаскивали, если вкратце - даже сиплюсников Эпол ищет на несколько порядков больше, ну и ес-но речь не шла про использование Rust в macOS/iOS.

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

Опенсорсные либы. Я только за опенсорс, но, очевидно, что многие конторы не будут использовать Rust по этой причине. Разве что для внутренних каких-нибудь решений и/или полноценных приложений, но ес-но не завязанных на проприетарные SDK.

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от khrundel

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

вот вопрос. как это написать на расте.

using cstring = const std::string;

class Named{
	cstring _name;
public:
	Named(cstring &fname):_name(fname){}
	cstring &name()const{return _name;}
};

class Foo:public Named{
	Foo(cstring &fname):Named(fname){}
};

void fff(){
	Foo lfoo("foo");
	std::cout<<lfoo.name();
}
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

Это просто. Сложнее перестать думать в терминах классов, наследующих данные и реализации методов.

trait Named {
    fn name(&self) -> &str;
}

struct Foo {
    name: String,
}

impl Foo {
    fn new<T>(name: T) -> Foo
    where
        T: Into<String>,
    {
        Foo { name: name.into() }
    }
}

impl Named for Foo {
    fn name(&self) -> &str {
        &self.name
    }
}

fn main() {
    let foo = Foo::new("foo");
    println!("{}", foo.name());
}
red75prim ★★★
()
Ответ на: комментарий от red75prim

Это просто. Сложнее перестать думать в терминах классов, наследующих данные и реализации методов.

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

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

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

В общем, в вопросе извлечения информации из тел функций, я так понимаю, что Царь слился.

Насчёт вывода типов: я бы посоветовал Царю прекратить переписывать словарь под свои хотелки. Vtable - это vtable, интерфейс - это интерфейс. У термина «вывод типа» есть устоявшееся значение, и оно не имеет никакого отношения к трансформации типа. Компилятор смог назначить тип без явного указания - значит вывод типа есть. И у Раста вывод типов гораздо мощнее чем у C++, C#, Java, я это продемонстрировал на нормальном коде. Это чудило сначало начало нести какую-то хрень, типа я использовал некую библиотеку, а в самом расте вывода типов нет. Это бред, библиотекой такие фичи не реализуются. Да и не подключал я никаких библиотек, тут вектор из стандартной либы и трейт From для полуявной конвертации оттуда же.

use core::fmt::Debug;
use std::vec::Vec;
use std::convert::From;

fn foo<T:Debug>(bar: &T) {
    println!("bar == {:?}", &bar);
}

//Для начала, скорее всего все мои объяснения бесполезны, потому как вероятно клоун просто перепастил какую-то херню. - Нет, но это абсолютно нерелевантно, написал, перепастил, один хрен пример демонстрирует то, что демонстрирует. Так что Царь хлебнул говна в прямом эфире.

fn main() {
    let mut v1 = Vec::new(); // Нигде ничего не выводится выводится.
//- Нет. Тут выводится тип переменной v1. Более того, в отличие от слабого вывода типов в языках типа плюсов или шарпа, тут просто офигенный момент: никакого Vec::new() в природе не существует. Существует дженерик Vec<T> и в нём метод new(), который, внезапно, уникален для каждого инстанса Vec<T>. Так что в этой строке выбирается правильный T для Vec<T>, и выбирается из контекста функции. Если убрать все v1.push и v1.extend, то компилятор станет ругаться, потому что не сможет догадаться, что это был за T в Vec<T>::new()
    let mut v2 = Vec::new(); // Ошибка клоуна объясняется следующим.
    // Клоун сидит в пхп и ему рассказали, что v1/v2 - это какие-то переменные, либо ещё какая херня
    // В реальности же нет. В этом недоязычке это так не работает и v1/v2 - это просто алиасы на выражение.
// - Чушь. Если бы v1 был алиасом к выражению Vec::new(), то каждое v1 в тексте превращалось бы в вызов функции создания вектора. Если считать, что v1 - это алиас не к выражению, а к памяти, в которой хранится результат выражения, то мы получаем обычную переменную.
    
    // второе свойство данной скриптухи. Т.к. здесь всё vtable(если угодно сектантам "динамические интерфейсы"),
// -нет, никакой динамики, тут всё статическое.
    
    // Далее, если вы внимательно читали мои объяснения - вы знаете, что в недоязычке неважен тип T. Важны именно связи.
// - нет, в "недоязычке" тип T важен, он известен, "недоязычёк" ругается, если ему подсунуть не то.
    // Т.е. путь проброса типа.
    
    // И вот где-то дальше происходит утверждение типа, руками. Допустим клоун вызывает extend(T: Vec<int>)
    // И на это недоязычку насрать - его не интересуют типы.
    
    // И далее происходит вызов, допустим, extend(T: vec<float>). Это единственный инвариант, который поддерживает данный мусор.
    
    // Алгоритм следующий. Необходимо указать тип руками, всегда. Тип - это vtable, т..е динамический интерфейс.
    // Далее типизация никого не интересует. Получается Vec -> Vec -> Vec<int> -> Vec<float> - нужно понимать, что тип цепочки всегда Vec, но цепочка не может содержать разные типы.

я оставил этот бред просто чтоб продемонстрировать какую Царь несёт хрень. Дальше вырежу и поступлю проще, переведу слова Царя на человеческий. Идея Царя заключается в том, что фронтенд языка Раст не выводит тип, а просто пихает что дают пока это не попадёт «украденному» LLVM, который в процессе кодогенерации и начнёт ругаться. Даже если бы это было правдой, это никак бы не отменило наличие вывода типов и тайпчека в расте, детали устройства компилятора совершенно неважны в обсуждении свойств языка, занимается ли этим в rustc фронтенд или бэкенд, неважно.

Однако, предположение Царя неверно, можно убедиться довольно просто:

use core::fmt::Debug;
use std::vec::Vec;

fn foo<T1: Debug + Copy, T2: Debug + Copy>(i1: T1, i2: T2) {
    let mut v1 = Vec::new();
    let mut v2 = Vec::new(); 
    // let v3 = Vec::new(); // ошибка, компилятор не может понять тип v3 из контекста
    let v3 = Vec::<bool>::new(); // а так норм, явно указан.
    v1.extend(
        (1..=5).map(
            |_|{
                v2.push(i2); // автовывод типа v2  это Vec<T2>. Автоавывод из побочного эффекта замыкания!
                i1 // автовывод возвращаемого значения T1 и, соответственно v1 Vec<T1>
            })
    );
    // v1.push(v2[0]); // Ошибка. Типы элементов не совпадают
    println!("v1 == {:?}, v2 == {:?}, v3 == {:?} ", &v1, &v2, &v3)
}

fn main(){
    foo(1,2); // T1 == T2 == i32, однако это не спасёт от ошибки если раскоментировать v1.push(v2[0])
    // Что доказывает, что вывод типов производится и без обмана  и халявы и проверка типов осуществляется не только до начала кодогенерации, но и до инстанциорования.
    // Так что Царь снова хлебнул в прямом эфире.
}

// Тут клоун несёт какую-то херню про ворованный llvm-ir. Это ничего не значит.

Царюшка, llvm-ir - это то, что фронтенд rustc скармливает LLVM для последующей обработки. Если на этом уровне foo::() и foo::() представлены как 2 независимые функции (а это так, ты можешь убедиться), значит ты попал пальцем в небо, когда предположил, будто бы инстанциация производится LLVM на этапе кодогенерации. Почему тебе такие простые вещи нужно разжёвывать?

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

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

А чем программу-то собрать? Девятым гцц? И как оно линковаться будет, если в пятом гцц поменяли аби?

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

А чем программу-то собрать? Девятым гцц? И как оно линковаться будет, если в пятом гцц поменяли аби?

Да, девятым. Но оно сейчас не работает, я проверил :( Так что сейчас патчить исходники Qt 4.4.3 и собирать новым компилятором…

undefined reference to `__gxx_personality_sj0'
undefined reference to `_Unwind_SjLj_Register'
undefined reference to `_Unwind_SjLj_Resume'
undefined reference to `_Unwind_SjLj_Unregister'

Но раньше работало, я собирал так программы точно после gcc5. Qt не использует STL, поэтому что поломали STL abi это не важно было. А вот то что сейчас в mingw32 сменили тип исключений с sjlj на DWARF оказалось важным…

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

И у Раста вывод типов гораздо мощнее чем у C++, C#, Java, я это продемонстрировал на нормальном коде

Ты это продемонстрировал на каноничном и чуть ли не единственном примере, который везде предлагают. И сравнивать так некорректно, так разные языки имеют разные ограничения и возможности. К примеру, в Rust нельзя написать аналог:

auto join = [](auto pref) {
    return array { [=](auto... v) { 
        return (... + (pref + lexical_cast<decltype(pref)>(v)));
    } };
};
    
cout << join("   "s).front()(1, 2., "3", "4"s);
cout << join(0.).front()(1, 2.);

Нет перегрузки, шаблонов, параметров значений, дефолтных аргументов и много другого. Легко уметь ограниченный набор возможностей и им манипулировать, но как только набор возможностей начинает расширятся - вылазят пачки проблем, а сложность резко возрастает, как c той же специализацией. Потому я бы сказал, что вывод типов есть везде, но каждый язык использует его с учетом своих остальных особенностей.

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

Серьёзный вопрос. Какие типы тут выводятся? Только тип результата +? Выводится, что он должен быть равен типу pref или что-то более хитрое?

Остальные типы просто берутся из типов параметров, так?

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

Какие типы тут выводятся? Только тип результата +?

Вообще-то все, тут нет ни одного явно указанного типа. Кроме разве что array, но и у того параметр выводится.

Остальные типы просто берутся из типов параметров, так?

Нет, они выводятся на их основе.

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от khrundel

Всё что есть в ООП хорошего, а именно инкапсуляция, полиморфизм (статический и динамический) есть в Расте.

«ООП» взлетело не из-за этого, а из-за выразительности, коей нет в расте, где предлагается писать месиво из struct/impl/trait/self/::new_*, в котором все разбросано по частям. А так то ООП можно на чем угодно изобразить, да и много что назвать им.

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

В Расте для статического полиморфизма сделаны генерики, для динамического — трейты. Наверное, видит, как и все языки, имеющие эти фичи. Но не ясно, зачем вы человека сравниваете с ЯП.

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

За такой код нужно сажать.

Это еще ладно, за одну только сигнатуру такой функции на Rust пришлось бы расстреливать.

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

В примере статический полиморфизм. Никаких абстрактных методов и vtable там нет.

быть не может. в растовом коде - Named это просто интерфейс, который предлагается реализовать всем, кто хочет быть совместимым с Named. если б там было 2(или 22) класса, что хотели бы быть совсместимыми с Named, им, судя по всему, предлаглось бы реализовать независимо свойство name(), каким-то способом. и это совершенно не то, что я написал в плюсовом примере.

В русте предлагается исполнить контракт на класс - реализовать свойство name():&string. а в плюсовом случае, наследникам дается готовая реализация, общая для всех. сколько у вас будет в русте в бинарнике экземпляров функций name(), что пришлось реализовать в N классах, что выполнили контракт на функцию name()?

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

В плюсах уже осилили implicit return? const auto постоянно писать тоже не задалбывает?

implicit return я считаю ненужным и даже вредным, а вот иммутабельности по дефолту не хватает, согласен.

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

В плюсах уже осилили implicit return?

пора бы расту осилить уже implicit self. :) а то писанина селфа в сигнатуре функции внутри трейта не радует. или там может быть описана статическая функция, которой не нужен селф?

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

сколько у вас будет в русте в бинарнике экземпляров функций name(), что пришлось реализовать в N классах, что выполнили контракт на функцию name()?

N и будет:

(вот тут две на 18 и 23 строчке в asm)

https://gcc.godbolt.org/z/xEjsUf

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

N и будет

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

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

в моем же случае жестко фиксирована реализация хранения базового свойства

И это запрещено в грамотном ООП.

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

и в коде она присутсвует в одном экземпляре, а не в десятках

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

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

Ты это продемонстрировал на каноничном и чуть ли не единственном примере, который везде предлагают. И сравнивать так некорректно

плюсовизм головного мозга довольно странно работает. В Расте вывод типа объективно лучше. Всё что нужно - это признать очевидное. Это непринципиальная фишка, но довольно удобная, можно не засорять тело функций ненужными подробностями. Но нет, вместо этого напишем, что сравнение некорректно, пример каноничный и вообще зато в расте перегрузки нет.

К примеру, в Rust нельзя написать аналог:

А можно полный пример, со всеми инклудами и без сраного буста? Просто пример довольно говнокодный и игра «допиши меня» малоинтересна.

Ладно, попробую дописать, как понимаю, тут у нас шаблон в массиве сидит и с разными типами инстанциируется. Как это вообще работает? Попробуем:

#include <iostream>
#include <array>
#include <string>
#include <boost/lexical_cast.hpp>
#include <cstdlib>
using namespace std::literals::string_literals;
 
int main()
{
    auto join = [](auto pref) {
        return std::array { [=](auto... v) { 
            return (... + (pref + boost::lexical_cast<decltype(pref)>(v)));
        } };
    };
    
// а теперь пытаемся воспользоваться
    if (rand()&1) {
        join = [](auto postf) {
            return std::array { [=](auto... v) { 
                return (... + (boost::lexical_cast<decltype(postf)>(v) + postf));
            } };
        };

    }


std::cout << join("xxx"s).front()(1, 2., "3", "4"s)<< std::endl;
std::cout << join(0.).front()(1, 2.);
}

Опаньки. Плюсы оказались языком, который не выполняет свои обещания. Чё толку мне сохранять темплейт в переменную, если воспользоваться этим нельзя?

Нет перегрузки, Внезапно: есть. Например см трейт From.

/*функция возвращает f64 */
if(smth) return From::from(1);
return From::from(10f32);

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

Это ограниченная перегрузка, но её предлагается использовать там, где это действительно нужно, а не просто тупо плодить 100500 функций с одинаковым именем.

Перегрузка в плюсах - это ошибка, которая дорого стоит. Страуструп конкретно лоханулся с конструкторами, их не должно было быть. Из-за невозможности различать их по именам, пришлось добавлять перегрузку и получать кучу проблем, когда вызов с интом указывает размер создаваемого объекта, а с контейнером - инициализирует объект содержимым. Добавив сюда параметры по умолчанию, получили полную жопу и теперь вынуждены писать имена параметров Something(capacity: 100) чем это лучше чем растовый Something::with_capacity(100) - непонятно.

шаблонов,

Шаблоны - говно. Идея «копипастнем вот это, попробуем откомпилять, не получилось - копипастим следующий вариант» она как бы даже выраженная словами выглядит идиотски. Ни один последующий язык не стал добавлять шаблоны, все делают нормальные дженерики. Кстати, читал недавно предложение запилить в плюсы нормальную кодогенерацию, чтоб можно было библиотекой qobject реализовать, без вызова внешней moc, или interface, чтоб в абстрактный базовый класс компилялся, plaindata или даже обычный плюсовый struct, типа видит компилятор такое слово и вызывает библиотечный кодогенератор, который из объявления сделает обычный класс, добавив public в нужных местах.

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

параметров значений

Это да, недоработка. Но некритичная.

дефолтных аргументов

а вот это создаёт больше проблем чем решает.

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

Нельзя так делать ручками прописывается вызов публичных методов внутреннего объекта. Тогда у вас будет грамотная инкапсуляция, а не спагетти-код.

Ох уж теоретики, почитатели книг, паттеранов и антипаттернов. Более корявого, переусложненного, тормозного и нерабочего кода чем у них трудно найти. Зато никто не расскажет больше них о «правильном» коде. Композиция действительно бывает лучше наследования, но бывает и хуже, о чем, кстати, в действительно хороших книгах и статьях должны упоминать.

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

Он собран gcc 4… И исходники не соберутся без правок на gcc 9.

Плюсопроблемы не беспокоят белых людей. Вообще, как это не соберётся, плюсы же обратносовместимые.

Но можно свою программу на Qt слинковать с этим Qt 4.4.3 и программа будет работать…

Сильно сомневаюсь, стабильного АБИ у плюсов нету. Наверняка скомпиляется только особым компилятором из сильно ограниченного списка. А вот если собрать из исходников, совместимость была бы гораздо лучше.

А в Rust можно использовать какую-нибудь либу времён Rust 0.10

Шикарно. А чего не написал времён 1.0? Всё-таки альфа языка… ну как бы несерьёзно.

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

Ох уж теоретики, почитатели книг, паттеранов и антипаттернов. Более корявого, переусложненного, тормозного и нерабочего кода чем у них трудно найти. Зато никто не расскажет больше них о «правильном» коде. Композиция действительно бывает лучше наследования, но бывает и хуже, о чем, кстати, в действительно хороших книгах и статьях должны упоминать.

Ну как бы определись, нужен ООП или нет. Если нужен - делай нормально. Если не нужен - не делай. А так получается типичная отмазка говнокодера: «я читал в по-настоящему умной книге, что наследование иногда лучше, поэтому я всегда тупо наследуюсь чтоб «пропатчить» 1 метод, и топчись оно всё конём».

Поэтому, кстати, никакое ГСЛ плюсы не спасёт. Плюсовики будут послушно прописывать лайфтаймы, где всё тривиально и прописывать не нужно, а там где нужно 5 минут подумать, чтоб сделать лайфтайм-безопасный интерфейс, тупо забьют. А если старший спросит - с умным видом расскажут, что вообще лайфтаймы - говно, с ними нельзя двусвязный список реализовать. В умной книге читал, да.

Да, и никакого тормозного кода там не будет: компиляторы плюсов достаточно умные, они всё заинлайнят по самое небалуйся.

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

плюсовизм головного мозга довольно странно работает. В Расте вывод типа объективно лучше

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

Опаньки. Плюсы оказались языком, который не выполняет свои обещания. Чё толку мне сохранять темплейт в переменную, если воспользоваться этим нельзя?

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

… куча фанатского бреда про то, что или «есть» в Rust или ненужно

Тут и отвечать не на что, любой вменяемый человек понимает что это чушь.

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

Ну как бы определись, нужен ООП или нет. Если нужен - делай нормально. Если не нужен - не делай.

Вот только «нормально» у всех разное. У кого-то ООП это CLOS, а ваш Rust это жалкий обрубок цэпэпэ, у кого-то это Smalltalk (все никак времени не найду на него), у кого-то это JS с его динамичностью, у кого-то Python с его гибкостью, у кого-то это Qt, у кого-то COM и т.д. А нормальный ООП это абстракция мало имеющая отношения к реальности.

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

Попробую переключиться на твой стиль общения. Фанатизм головного мозга мешает понять, что в Rust нет глобального вывода типов?

Глобального вывода типов и в плюсах нет, так-то.

Я уже выше раз 3 объяснил, почему вывод типа за пределы тела функции (кроме замыкания) вреден. Четвёртый раз нужно объяснять?

В расте два «одинаковых» замыкания тоже имеют разный тип.

Давай ты не будешь дурачка включать. ТЫ, лично ты обещал возможность сохранить шаблон в переменную. Очевидно, что такая штука на статически компилируемом языке нормально работать не будет. Я и показал, что она не работает.

А вот вывод типа, внезапно, в Расте работает, им можно пользоваться.

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

Тут и отвечать не на что, любой вменяемый человек понимает что это чушь.

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

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

Вот только «нормально» у всех разное.

Ты дурачка-то не включай. Нормальное ООП начинается с инкапсуляции. Если ты инкапсуляцию ломаешь, чтоб пропатчить метод, то ООП у тебя отсутствует по определению.

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

ТЫ, лично ты обещал возможность сохранить шаблон в переменную

Дай ссылку на это и я признаю, что не прав во всем, и что Rust идеален.

Я уже выше раз 3 объяснил, почему вывод типа за пределы тела функции (кроме замыкания) вреден. Четвёртый раз нужно объяснять? Слив засчитан

Про то, что если чего-то нет в любимом языке фанатика, то оно кривое и вредное, и так все давно знают. Можно заранее все сливы засчитывать.

шаблоны, которые после плюсов никто не стал реализовывать

Я бы посоветовал бы чуть расширить свой кругозор.

потому что всем понятно, что это тупик

Всем понятно. Ясно.

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

функция доступа к нему вызывается статически, а не через таблицу методов.

Named::name() вызывается через vtable только для трейт-объектов.

и в коде она присутсвует в одном экземпляре, а не в десятках, как оно было бы, если б наследников были десятки.

Собственно я уже ответил. Подход к структурированию кода с помощью иерархий классов - не единственный. В коллекции объектов строки с именами объектов можно положить отдельно других данных объектов, и такая коллекция всё-равно сможет выдать интерфейс Named для индивидуальных объектов. Вот и будет одна реализация.

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

Ты дурачка-то не включай. Нормальное ООП начинается с инкапсуляции. Если ты инкапсуляцию ломаешь, чтоб пропатчить метод, то ООП у тебя отсутствует по определению.

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

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

Можно заранее все сливы засчитывать.

Да этому горе-демагогу можно было защитать слив уже за одно вот это в контексте разговора про С++:

Добавив сюда параметры по умолчанию, получили полную жопу и теперь вынуждены писать имена параметров Something(capacity: 100)

У него, видимо, какой-то свой собственный C++, с именованными параметрами.

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

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

быть не может

Вы не поверите.

Преимущество трейтов в том, что мне не нужно модифицировать оригинальный тип. Я могу реализовывать трейты для любых типов, а наследование работает только для собственных. При этом мы или создаём god class, либо извращаемся с множественным наследованием. И то и другой - быдлокод.

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

Зачем тащить в новый язык старые ошибки? self нужен чтобы не извращаться с m_* и прочим ужасом.

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

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

При чём тут лайфтаймы? Или вы про аргумент функции? Ну тут раст тоже удобнее, так как сразу ясно что функция делает и не нужно лезть в хедер и проверять помечена она как static или нет. Explicit is better than implicit.

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

Или вы про аргумент функции?

Да, но его наличие в том числе предопределяет необходимость его явного использования.

Ну тут раст тоже удобнее, так как сразу ясно что функция делает и не нужно лезть в хедер и проверять помечена она как static или нет. Explicit is better than implicit.

Ну это ты уже про другое, про хедера, разделение на прототипы и реализацию, и про конкретно static, который не дублируется в С++. Для Rust это не актуально. Ну и если говорить про двойные стандарты, то трейты сами по себе нарушают принцип, что явное лучше неявного, в расте глядя на структурку, ты практически ничего о ней не знаешь, что она может, как ее создать, придется перелопатить практически весь код, чтоб это понять.

П.С. если что, мне нравятся трейты

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

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

С классами тоже самое. Ну и подход раста, это - данные отдельно, интерфейс отдельно. Тут бессмысленно обсуждать критерий удобства и правильности. Это просто другой подход. И наевшись проблем с ООП в C++ я только рад такому подходу.

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

С классами тоже самое.

Нет, у класса есть конструкторы и есть список протоколов/интерфейсов, которые он реализует. То самое явно. А если надо что-то добавить сбоку, то в том же Swift есть расширения.

подход раста, это - данные отдельно, интерфейс отдельно. Тут бессмысленно обсуждать критерий удобства и правильности.

Это разделение не отменяет наличие impl у структуры. Условно говоря, никто не мешает разделить класс на данные и методы, но при этом не разрывать его на мелкие части.

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

Мы или ищем все трейты которые реализованы для типа (cargo doc в помощь) или руками проходим по всем дочерним классам. Разницы никакой.

А если надо что-то добавить сбоку, то в том же Swift есть расширения.

Он-то тут при чём?

Это разделение не отменяет наличие impl у структуры.

И? В C++ я не могу добавить метод к структуре без её модификации или наследования. В расте могу.

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

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

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

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

наследование, это не «наследование реализации». наследование это СПЕЦИАЛИЗАЦИЯ имеющейся реализации. Я пишу свой класс - «некрашеный автомобиль» и даю его вам. вы можете из него одним движением сделать класс - крашеный автомобиль, и отдать его тому - кто эти автомобили «продает» клиенту.

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

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

а в расте это обудет 2000(!) функций написанных ручками, о которых знают все, и все знают, что они быть должны, и даже знают, как их реализовать… вы уверены, что в расте есть инкапсуляция??? как реально сокрыть это все??? вот. без наследования нет реальной инкапсуляции.

короче. в расте из трех принципов ооп - полиморфизм-инкапсуляция-наследование, нет двух, а полиморфизм однобокий. полиморфизм в расте обеспечивается только реализацией интерфейсов.

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

Мы или ищем все трейты которые реализованы для типа (cargo doc в помощь) или руками проходим по всем дочерним классам. Разницы никакой.

Вообще никакой, хорошо.

Он-то тут при чём? И? В C++ я не могу

Он-то тут при чём? (c)

добавить метод к структуре без её модификации или наследования

Конкретно в С++ для этого есть функции, операторы, шаблоны, перегрузка и специализация. Звучит костыльно, выглядит костыльно, работает костыльно и неполноценно, но я это хотя бы признаю, а не начинаю расписывать все преимущества такого подхода и выдумывать преимущества. В том же Swift это сделано уже так, как я хочу. Он-то тут при чем.

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

И? В C++ я не могу добавить метод к структуре без её модификации или наследования. В расте могу.

можешь :). напиши например void ff(Struct &self, …). или ты не понял, что раст пишет это же самое??? в расте методы не привязаны к структуре на самом деле. они не инкапсулированы в ней(что нарушает как раз инкапсуляцию), они инкапсулированы в модуле. но модули - это не ооп. чтобы понять какие-же методы имеет данный растовый «псевдокласс», надо перелопатить весь код либо поиском, либо тулзой, что будет из кода вытаскиваться методы классов.

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

Очень остроумно. Ждём Uniform Function Call Syntax. А пока что это треш, ибо даже chaining не сделать.

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

а в расте ВСЕ методы так реализованы! это вполне себе традиционные байндинги, которые вирт еще в оберон воткнул. идея - структура + раскиданные по модулю байндинги - это еще от оберона идет. можете удостовериться. но вирт был сторонник КОМПОНЕНТНОГО программирования, как некоего концепта, и потому не особо заморачивался с ООП.

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

Вам никто не мешает сделать приватный трейт со стандартной реализацией.

пример приведите, и не кидайтесь какашками постмодернистских терминов… я даже не знаю что такое приватный трейт!

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

более того! в русте в трейтах же есть реализация метода по умолчанию

А еще в rust зарезервированы ключевые слова final и override. Посмотрим, выстрелит ли это ружье.

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

А еще в rust зарезервированы ключевые слова final и override. Посмотрим, выстрелит ли это ружье.

:)))) чуваки решили соломку таки подстелить.

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

потому что приватные методы, видимые в хидере - это противоречит инкапсуляции.

Шта? Инкапсуляция - это про область видимости/доступности (хз как правильно называется) типа компилятору. То что программист может прочесть сорцы - это не инкапсуляция.

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

пример приведите

Задачу сформулируйте конкретно, а то опять вилять начнёте.

постмодернистских терминов

private и в плюсах есть, алё.

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

Там и try/catch есть. Дальше что?

И не просто есть, а и недавно добавлены. Но, если ты к тому, что try/catch не про исключения, то final/override таки подвязаны к предложению об наследовании реализации.

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

Да этому горе-демагогу

Мы так-то уже определили демагога, который перевирал слова оппонентов, а потом их «опровергал».

можно было защитать слив уже за одно вот это в контексте разговора про С++:

Убого. Впрочем, чего ещё от тебя ожидать, всё что можешь - это выискивать место, где не написаны разные оговорки и врываться на белом коне.

Я никогда не утверждал, что такое можно в C++. В контексте ненужности перегрузки я рассказал про проблемы этой фичи. Такое можно в C#, в котором есть перегрузка и параметры по умолчанию. И такое, если повезёт, появится в C++ 2030. Потому что иначе с дефолтными параметрами тяжко, второй параметр с дефолтным значением уже становится труднодоступным.

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

Дай ссылку на это и я признаю, что не прав во всем, и что Rust идеален.

лови: Rust и типобезопасность (комментарий)

Теперь самое время начинать мазаться, что ты вовсе не то имел в виду, когда показывал этот говнокод, что это вовсе не демонстрация супермегафичи, которую не умеет Раст :).

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

ТЫ, лично ты обещал возможность сохранить шаблон в переменную

лови: Rust и типобезопасность (комментарий)

ловите_наркомана.jpeg

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от khrundel

Потому что иначе с дефолтными параметрами тяжко второй параметр

с дефолтным значением уже становится труднодоступным.

foo(,2)
foo(_,2)

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

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от alysnix

это не просто лишние 10 «строк кода». это сотни-тыщи строк лишнего кода в виде текста на языке чудесатого програмирования,

Согласен, расту сильно не помешает макрос типа [redirect(SomeTrait, privateField, method1, method2, method3…)] Чисто для сумасшедших фанатов наследования. Такой подход всё равно лучше, так как позволяет обращается только к публичным методам и явно перечисляет методы, которые должны быть наследованы, так что при добавлении чего-то в трейт или при имплементации базовым классом новых трейтов оно автоматически «наследованному» не передастся.

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

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

наследование, это не «наследование реализации». наследование это СПЕЦИАЛИЗАЦИЯ имеющейся реализации. Я пишу свой класс - «некрашеный автомобиль» и даю его вам. вы можете из него одним движением сделать класс - крашеный автомобиль, и отдать его тому - кто эти автомобили «продает» клиенту.

Соболезную, но это не работает. Изменения в вашем некрашенном автомобили будут ломать мой крашенный.

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

Если у вас 200 классов, то вам наследование мало поможет. Макросы в помощь. В плюсах, кстати, тоже так делается, см

class Foo : public QObject
{
    Q_OBJECT // а это что такое?
...
}

короче. в расте из трех принципов ооп - полиморфизм-инкапсуляция-наследование, нет двух, а полиморфизм однобокий. полиморфизм в расте обеспечивается только реализацией интерфейсов.

Чего? Инкапсуляция на месте, причём не ущербная, так как нет наследования. Полиморфизм на месте. Нет только наследования.

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

ловите_наркомана.jpeg

слив засчитан. Вот на что ты вообще надеялся, интересно?

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

Шта? Инкапсуляция - это про область видимости/доступности (хз как правильно называется) типа компилятору. То что программист может прочесть сорцы - это не инкапсуляция.

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

то что я сказал, имеет смысл только если:

  • класс публичный, и неохота показывать его приватные методы(что нормально).
  • для непубличного класса, локального в единице компиляции то, что я сказал - ИЗЛИШНЕ, там проще использовать приватные методы, и не париться.

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

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

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

Если у вас 200 классов, то вам наследование мало поможет. Макросы в помощь. В плюсах, кстати, тоже так делается, см…

макросы там совершенно не причем.

class Atom{ public: string &name(){…} string &guid(){…} }

class C :public Atom{ } class CC :public C{} class CCC:public CC{} .. и так до бесконечности..

все классы имеют свойства name и guid, причем реализованные внутри Atom, и вызываемые СТАТИЧЕСКИ. то есть адрес рассчитывается на этапе линковки, и корректируется загрузчиком если надо. никаких виртуальных таблиц, необходимых для трейтов.

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

Сами придумали какую-то ерунду - сами её и опровергли.

в расте кстати можно добавить метод к структуре не внутри того модуля где она определена?

Да.

RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от Serral

final/override таки подвязаны к предложению об наследовании реализации

Пруфца бы.

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

Вам уже 10 раз объяснили, что у трейтов нет vtable.

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

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

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

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

да чо там! читаем https://doc.rust-lang.org/1.29.2/book/first-edition/trait-objects.html#representation, там все написано:

The methods of the trait can be called on a trait object via a special record of function pointers traditionally called a ‘vtable’ (created and managed by the compiler).

A vtable is essentially a struct of function pointers, pointing to the concrete piece of machine code for each method in the implementation. A method call like trait_object.method() will retrieve the correct pointer out of the vtable and then do a dynamic call of it.

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

Кстати, читал недавно предложение запилить в плюсы нормальную кодогенерацию, чтоб можно было библиотекой qobject реализовать, без вызова внешней moc, или interface…

Я не в курсе что ты там читал. Но есть проект https://www.copperspice.com/ где отвезали поганый Qt от moc.

Сейчас требуют С++17 компилятор, но первая версия которая отвязана от moc требовала лишь C++11

А вот эти ребята назад бекпортировали эти отвязания для оригинального Qt: https://github.com/woboq/verdigris

И требуют С++14 компилятора. Кстати всем рекомендую, можно пользоваться Qt как обычной либой хоть в обычном Makefile и не париться с лишними шагами кодогенерации с moc.

Так что qobject реализовать без moc можно было с С++11…

Meta-Object Compiler (moc)

The Meta-Object Compiler is no longer required for generating reflection meta data in CopperSpice

Since moc is no longer required it was completely removed

All functionality originally provided by moc was replaced with compile time templates

CopperSpice automatically generates meta data for processing Signals/Slots and Introspection

A template class can now inherit from QObject with no restrictions on data types

Complex data types can be used as a signal or slot argument, for example this is valid in CopperSpice: QMap<QString, int>

Removal of moc simplifies the build process

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от numas13

Trait != TraitObject. В отличии от С++, vtable не зашивается в структуру. Посмотри на реализацию твоего примера на Rust

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

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

Посмотри на реализацию твоего примера на Rust

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

class Atom{ 
public:
  string &name(){…} 
  string &guid(){…} 
};
class C1:public Atom{ };
class C2:public C1{ };
class C3:public C2{ };
class C4:public C3{ };

вот тут в 9 строках обьявлены 5 классов, и у всех пяти есть методы name, guid. что нам предлагает руст вместо такой записи?

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

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

Именно это я и имел виду.

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

Нет, читай ссылку которую ты привёл выше, там всё разжёвано.

fn main() {
    let c = C(AtomData::new("C", "C_GUID"));
    let cc = CC(C(AtomData::new("CC", "CC_GUID")));
    
    dump_static(&c);
    dump_static(&cc);
    
    dump_dynamic(&c);
    dump_dynamic(&cc);
    
    use std::mem::size_of;
    println!("size_of String = {}", size_of::<String>());
    println!("size_of AtomData = {}", size_of::<AtomData>());
    println!("size_of C = {}", size_of::<C>());
    println!("size_of CC = {}", size_of::<CC>());
}
 static: name = "C", guid = "C_GUID"
 static: name = "CC", guid = "CC_GUID"
dynamic: name = "C", guid = "C_GUID"
dynamic: name = "CC", guid = "CC_GUID"
size_of String = 24
size_of AtomData = 48
size_of C = 48
size_of CC = 48

Как видишь в структуру ничего не вшито.

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

Ты показывай полную реализацию, и я покажу.

using namespace std;
class Atom{ 
	static int _count; //статическмй счетчик
	string _name;
	int _guid;
	
public:
	Atom():_guid(++_count){ }
	const string &name()const {return _name;}
	int guid() const{return _guid;} 
	void setName(const string &fs){_name=fs;}
};
int Atom::_count=0; //

class C1:public Atom{};
class C2:public C1{};
class C3:public C2{};
class C4:public C3{};
alysnix ★★★
()
Ответ на: комментарий от numas13

Как видишь в структуру ничего не вшито.

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

let c = C(AtomData::new("C", "C_GUID"));    
let cc = CC(C(AtomData::new("CC", "CC_GUID")));

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

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

Atom():_guid(++_count){ } - undefined behavior при создании экземпляров классов в разных потоках. Нужно использовать std::atomic<int>. Undefined behavior при переполнении _count (до C++ 20, кажется). Нужно использовать std::atomic<unsigned int>.

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

Atom():_guid(++_count){ } - undefined behavior при создании экземпляров классов в разных потоках.

не мути воду. мы пока потоков не касались вообще. это модельный пример на ооп нотацию.

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

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

Если как было записано изначально, то вообще не будет вызван ни dump_static ни dump_dynamic, всё будет заинлайнено в main.

https://gcc.godbolt.org/z/PohadF

Если поставить #[inline(never)]

https://gcc.godbolt.org/z/RbaMya

и посмотреть на строки 158 и 187

То как я понимаю в dump_static будет заинлайнено: c.name() и c.guid()

А в dump_dynamic будут вызваны функции c.name() и c.guid() через vtable.

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

Нет особого смысла воспроизводить антипаттерн с глубокой иерархией классов, почему бы и на потенциальные UB не указать.

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

Смысла воспроизводить антипаттерн с глубокой иерархией классов нет, почему бы и на потенциальные UB не указать.

ну выкати «идеологическое ограничение» на глубину иерархии. нормальный такой тест на выразительность руста.

а также обозначь потенциальное ub если программа пытается запустить 40 млн тредов, или создать триллион об’ектов в памяти. это разве не UB?

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

Если как было записано изначально, то вообще не будет вызван ни dump_static ни dump_dynamic, всё будет заинлайнено в main.

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

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

Лоб в лоб.

static COUNT: AtomicU32 = AtomicU32::new(0);

struct Atom {
    name: Option<String>,
    guid: u32,
}

impl Default for Atom {
    fn default() -> Self {
        Self {
            name: None,
            guid: COUNT.fetch_add(1, Ordering::Relaxed),
        }
    }
}

impl Atom {
    fn set_name(&mut self, name: String) { self.name = Some(name) }
    fn guid(&self) -> u32 { self.guid }
    fn name(&self) -> Option<&str> { self.name.as_deref() 
}

#[derive(Default, Derefable)]
struct C1(#[deref(mutable)] Atom)

#[derive(Default, Derefable)]
struct C2(#[deref(mutable)] C1)

#[derive(Default, Derefable)]
struct C3(#[deref(mutable)] C2)

#[derive(Default, Derefable)]
struct C4(#[deref(mutable)] C3)
numas13
()
Ответ на: комментарий от numas13

Лоб в лоб.

итак из 9 строк на с++ получилось 26 на русте, на простейшем примере. вам не кажется что плюсы втрое выразительней оного?

а вашем случае можно написать эти две строчки?

C4 ll;
ll.setName("just a name");
alysnix ★★★
()
Ответ на: комментарий от alysnix

Если реализовать только реальную функциональность примера, то достаточно сделать что-то вроде

mod atom {
    use std::sync::atomic::{AtomicU64, Ordering};

    static COUNTER: AtomicU64 = AtomicU64::new(1);

    pub struct Atom {
        pub name: String,
        guid: u64,
    }
    
    impl Atom {
        pub fn new<T: Into<String>>(name: T) -> Self {
            Atom {
                name: name.into(),
                guid: COUNTER.fetch_add(1, Ordering::Relaxed),
            }
        }
        
        pub fn guid(&self) -> u64 {
            self.guid
        }
    }
}

Иерархия классов - средство для решения какой-то задачи, а не цель. В исходном примере не решается никакая задача.

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

Иерархия классов - средство для решения какой-то задачи, а не цель. В исходном примере не решается никакая задача.

там все готово для решения вот этой задачи:

C4 ll;
ll.setName("just a name");

и массы других.

alysnix ★★★
()
Ответ на: комментарий от numas13
let mut c4 = C4::default();
c4.set_name("just a name".to_string());

вот заболтали вы меня совсем. задача то была совсем другая! во какая задача была!

Atom* lp = new C4();
lp->setName("object of C4 class");

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

это точно компилируется? ссылка на С4 совместима со ссылкой на Atom? а почему? нет же наследования, насколько я понял. или есть наследование? с плюсах поинтер на атом и поинтер на с4 совместимы поскольку есть наследование. а тут как?

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

а тут как?

Лень листать выше, чтоб искать, что вы сравнивание, но в Rust есть так называемые fat pointers, т.е. это не просто указатель, а указатель + дополнительная информация.

Serral
()
Ответ на: комментарий от Serral
let mut atom: &mut Atom = &mut *C4::default();

почему ссылка на Atom оказалась тут совместимой с С4?

что вообще значит вот эта куета?

#[derive(Default, Derefable)]
struct C1(#[deref(mutable)] Atom)

#[derive(Default, Derefable)]
struct C2(#[deref(mutable)] C1)

#[derive(Default, Derefable)]
struct C3(#[deref(mutable)] C2)

#[derive(Default, Derefable)]
struct C4(#[deref(mutable)] C3)
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от Serral

Лень листать выше, чтоб искать, что вы сравнивание, но в Rust есть так называемые fat pointers, т.е. это не просто указатель, а указатель + дополнительная информация.

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

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

что вообще значит вот эта куета?

Это чит использование сторонней библиотеки, чтоб уменьшить кол-во строк для примера. А в целом такой себе аналог смеси перегрузки оператора * и оператора T в С++, чтоб делать умные указатели.

https://doc.rust-lang.org/std/ops/trait.Deref.html

И там ЖИРНЫМ: «Deref should only be implemented for smart pointers to avoid confusion.». Т.е. это чисто синтетический пример, где и сам подход запрещен авторами Rust, и прикручена сторонняя библиотека.

Serral
()
Последнее исправление: Serral (всего исправлений: 1)
Ответ на: комментарий от Serral

Т.е. это чисто синтетический пример, где и сам подход запрещен авторами Rust, и прикручена сторонняя библиотека.

это просто безобразие! позооор! а я думал, что говорю с интеллигентными людьми.

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

что вообще значит вот эта куета?

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

Что вы несете? Там нет использования «сторонней библиотеки». Иначе покажите строку, где подключается эта библиотека. Еще и своего собрата в заблуждение вводите.

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

Там нет использования «сторонней библиотеки».

лучше поясните, что значит этот мощный месседж? к чему эта куча буковок вместо простейшего «class C1:public Atom{}»

#[derive(Default, Derefable)]
struct C1(#[deref(mutable)] Atom)
alysnix ★★★
()
Ответ на: комментарий от alysnix

Это процедурные макросы, которые действительно избавляют от копипасты. В данном случае дописывают типам C* методы для дефолтной реализации и мутабельного разыменования (доступа к инстансу типа, который приводит к его изменению — записи в поля). Эта куча буковок позволяет использовать дефолтную реализацию типа Atom без реализации конструкторов для типов C*. А объяснять подробно мне лень, ибо долго расписывать.

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

Чувак, ты ведь вообще них*ра не знаешь про Rust, но всех убеждаешь, что он г*вно. Ты не из дурки нам сюда пишешь?

htower_ ★★
()
Последнее исправление: htower_ (всего исправлений: 1)
Ответ на: комментарий от Serral

Т.е. это чисто синтетический пример, где и сам подход запрещен авторами Rust, и прикручена сторонняя библиотека.

И есть что-то правильное в том, что кривой антипатерн из плюсов реализуется кривым антипатерном из Раста.

Вообще, чего вы, фанаты плюсов не понимаете, что Раст делался вменяемыми людьми в 10х годах 21 века, через 30 лет после плюсов. Вы можете считать, что эти люди допустили ошибки, или даже что сделали совершенное говно вместо языка, но очень наивно думать, что они вот просто взяли и прозевали какую-то однозначно полезную фичу из плюсов. Нет. Они находились в выгодном положении, им не нужно было изобретать ООП/перегрузку, как плюсам, им не нужно было мимикрировать под плюсы как Java/D/C#, они могли себе позволить решать «воровать» вот эту конкретную фичу из плюсов или не надо исключительно с точки зрения её полезности и опираясь на опыт плюсов. И у них было дофига времени на обдумывание. Поэтому чувак с ЛОРА, будь он даже он трижды гением, за полчаса написания коммента, вряд ли найдёт реальную ошибку вот прямо так, на поверхности, сравнивая фичалист Раста и плюсов, гораздо вероятнее что эта отсутствующая фича будет сильно спорной и критикуемой уже на протяжении 30 лет.

Вот конкретно проблема несовместимости инкапсуляции и наследования, например, широко известна с 1986 или 87 года, поэтому отчасти «наследники» плюсов разделили понятия базового класса и интерфейса, что также позволило отказаться от множественного наследования.

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

Что вы несете? Там нет использования «сторонней библиотеки». Иначе покажите строку, где подключается эта библиотека.

А ты про нее у автора кода спроси, почему он ее «забыл». Вот она:

https://docs.rs/derefable/0.1.0/derefable/

П.С. адепты Rust не знают своего языка, это действительно позор.

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

адепты Rust не знают своего языка, это действительно позор

Никого не защищаю, но в случае C++ почти у всех точно так же :)

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

Никого не защищаю, но в случае C++ почти у всех точно так же :)

Это у всех так, язык не важен.

И что интересно - как не запилят тред про Rust, так сразу «набигают» плюсовики и начинают хором петь про то что «рустнинужын!!!!!11». Если он такое г*вно, как вы его описываете, то зачем тратите своё время на подобные ср*чи? Ведь (следуя заветам дедушки Ленина eao197) «можно было бы заняться созданием чего-нибудь полезного на С++».

Во-первых нужен. Во-вторых набигание взаимное, а данный тред изначально создан для холивара. В-третьих срач на ЛОР - это праздник. В-четвертых, занимаемся и создаем, и не только на С++, но иногда надо проветриваться и не только физически.

П.С. А вообще С++ лучше всех для холиваров, т.к. он и ужасен и прекрасен одновременно, ему есть что предъявить, и есть чем ответить взамен.

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

В-третьих срач на ЛОР - это праздник

Дата регистрации: 11.11.19 09:16:39

Полугодовалый регистрант рассказывает про ЛОР, лол.

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

Этот субъект недавно выказывал свое «фи» в мой адрес как юзера ЛОР с многолетним стажем. Дескать, я хожу сюда, как «на работу». Признай он сейчас, что и он на ЛОР не первый год, это будет выглядеть каминг аутом :).

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

Этот субъект недавно выказывал свое «фи» в мой адрес как юзера ЛОР с многолетним стажем. Дескать, я хожу сюда, как «на работу». Признай он сейчас, что и он на ЛОР не первый год, это будет выглядеть каминг аутом :).

Я сказал, что ты здесь как на работе. А я делаю набеги раз в несколько лет.

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

О, пошли маневры.

А я делаю набеги раз в несколько лет.

Не затруднит предыдущий момент «набегаторства» обозначить? Юзернейм там, например.

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

срач на ЛОР - это праздник

наш человек :)

А вообще С++ лучше всех для холиваров, т.к. он и ужасен и прекрасен одновременно, ему есть что предъявить, и есть чем ответить взамен.

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

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

Вывод типов есть, нет шаблонных лямбд.

Не в лямбдах дело, можно все заменить на функции/структурки, а скобочки на метод, суть не поменяется.

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

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

Тут спасает документация. Даже если её нет, то всё равно можно будет посмотреть на методы и реализованные трейты.

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

К слову сказать, в моём начальном посте не было ни слова о C++, и я таки нашел в Rust багу за полчаса, или во всяком случае, дефект, не достойный языка с safe-архитектурой.

И есть как минимум 1 язык, который в подобной ситуации диктует хотя бы рантайму адекватное для safe-архитектуры поведение. И это не C++.

Это потом в тред пришли эксперты, и начали сравнивать с C++ (у кого что болит).

Напоминает диспут политиканов:

  • в России тюрьмы переполнены преступниками!
  • а вот в Америке тоже!
seiken ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Зачем, когда и так C++ чешется, во всю полыхает.

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

или там может быть описана статическая функция, которой не нужен селф?

Естественно может.

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

Не в лямбдах дело, можно все заменить на функции/структурки, а скобочки на метод, суть не поменяется.

Или я чего-то не понял или ты не прав. В расте есть вывод типов, но только внутри функций - это один момент. Второй - для одной лямбды тип выводится один раз, то есть инстанс один.

Ну или объясни о чём мы спорим.

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

Обычно дефолтные параметры используются для быстрого и грязного патча существующей функции под особый случай. Уже это перевешивает всю потенциальную пользу.

Кроме того:

  • дефолтное значение параметра нарушает инкапсуляцию. Обычно это или bool, отключающий некоторые шаги алгоритма, в особо продвинутых случаях параметр даже называться будет doNotDoSomething, или реальное значение, открывающее особенности кишок. Иногда, например чтоб установить значение следующего параметра, проще скопировать значение из сигнатуры, потом, когда дефолтное значение поменяется, будет невозможно определить, было ли это значение установлено сознательно, или просто не поменяли синхронно с значением из сигнатуры.
  • дефолтные значения позволяют объединить разные функции в одну, там где по смыслу нужны несколько разных для разных случаев, создают видимого снаружи монстра с кучей параметров, половина из которых будет с дефолтными значениями.
    • что создаёт возможность непредусмотренных комбинаций, которые надо или обрабатывать внутри, или игнорировать риск, что кто-то решит, что такой вариант возможен и получит ошибку в рантайме.
    • затрудняет поиск ненужного кода. Если функция не используется, это позволит обнаружить любое IDE, часто в автоматическом режиме, а обнаружить, что некий параметр всегда равен одному и тому же значению сложно. Соответственно, при рефакторинге придётся поддерживать нафиг не нужный код.
    • при удалении ненужного параметра с дефолтным значением произойдёт сдвиг позиций и, в некоторых случаях, это не приведёт к ошибке компиляции (это также касается перегрузки, но там вероятность чуток меньше).
    • рано или поздно с этой порнографией придётся что-то делать, в язык придётся добавить возможность указывать имена параметров при вызове, линтеры даже будут требовать это, в случаях когда параметров много и в итоге выйдет, что сэкономив на написании трёх методов под разные потребности (которые, возможно, вызывали бы такого же монстра с 10 параметрами, но приватного), придётся каждый раз писать многословный вызов с именованием каждого параметра.
khrundel ★★★★
()
Ответ на: комментарий от RazrFalcon

Это и с С не сработает

Прекрасно сработает.

А можно скачать Qt для MSVC и пытаться использовать его из mingw, но ничего не выйдет.

Мне понравилось описание совместимости ABI у tdm:

Ideally, the binaries and compiled code produced by TDM-GCC would be ABI-compatible with other Windows compilers. This is sadly not the case.

Generated code:

[NO: MSVC]

Microsoft Visual C/C++ generated code is not compatible with GCC unless you are truly elite.

DLL linkage:

[WITH CARE: MSVC]

If you take care to match calling conventions and catch exceptions, C linkage is possible.

C++ linkage for classes is fraught and for STL / libstdc++ objects is not possible.

Maybe there’s a compatibility layer somewhere.

Так что по такому описанию все всегда правы. И те кто говорят что можно и те кто говорят что нельзя :)

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

Обычно дефолтные параметры используются для быстрого и грязного патча существующей функции под особый случай.

draw_line(color = black) - это будет считаться «быстрым и грязным патчем»?

С некоторыми аргументами согласен, но далеко не со всеми. Спорить особого смысла не вижу. Как по мне, дефолтные параметры позволяют сделать апи удобнее, ну а неправильно использовать можно всё что угодно.

Aнтипаттерн Option как дефолтное значение - ещё хуже, а такое иногда встречается. Опять же, отсутствие дефолтных параметров приводит к таким замечательным штукам в апи как with_capacity, with_hasher и with_capacity_and_hasher. Билдер тоже не всегда хочется городить.

придётся каждый раз писать многословный вызов с именованием каждого параметра

Мне иногда кажется, что сделать обязательным указание имён параметров, если их больше одного, при вызове было бы хорошей идеей (примерно как в Objective-C). В конце концов, при написании кода ИДЕ могли бы делать большую часть работы, а читать было бы проще.

В ишью о добавлении дефолтных параметров, которая периодически продолжает вяло обсуждаться, насколько я помню, основным аргументом выступает, что это ещё одна возможность случайно добавить ломающие изменения в апи. Вообще было бы здорово встроить в cargo publish проверку на отсутствие ломающих изменений, если не была увеличена мажорная версия, но это не так-то просто. Конечно, есть rust-semverver, но не знаю насколько надёжно оно работает и, в прошлый раз когда проверял, проверка занимала довольно много времени.

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

Лол, он реально не понимает что там тип из push выводится?

НЕ ТАЙПЧЕКАЕТСЯ

ДИНАМИЧЕСКИЙ ИНТЕРФЕЙС

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

Константностью не тривиальных полей ты ломаешь move конструктор/оператор и они в нем начинают копироваться. Это то почему эта константность фактически бесполезна в плюсах.

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

Почему бы не почитать что-нибудь про раст и не понять, что никакого виртуального метода и vtable тут нет?

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

Почему бы не почитать что-нибудь про раст

Потому что чукча пейсатель, а не читатель :)

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

и я таки нашел в Rust багу за полчаса

О которой написано в документации раста по типам? Ваууу..

Скорее похоже что ты

Решил я тут немного изучить Rust

И решил накинуть говница.

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