LINUX.ORG.RU

Rust: преобразования указателя на трейт в конкретный тип

 


1

7

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

use std::collections::HashMap;
use std::any::TypeId;
use std::rc::Rc;

trait MyTrait {
    fn new() -> Self where Self: Sized;

    // Тут ещё какие-нибудь методы
}

struct MyStruct {
    items: HashMap<(i32, TypeId), Rc<dyn MyTrait>>
}

impl MyStruct {
    fn get<T: MyTrait + 'static>(&mut self, key: i32) -> Rc<T> {
        if let Some(item) = self.items.get(&(key, TypeId::of::<T>())) {
            item.clone() as Rc<T>
        } else {
            let item = Rc::new(T::new());
            self.items.insert((key, TypeId::of::<T>()), item.clone());
            item
        }
    }
}

Как правильно конвертировать элемент при его извлечении в тип T?

★★★★★

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

Мне два раза придётся писать один и тот же код лямбды, если у меня два контекста? Ужас. Это косяк языка.

Да, ленивая ты жопа. Скопипасти одну строчку. Тебя не беспокоит, что тебе требуется 2 массива, чтоб складывать в них объекты 2х типов, так почему с лямбдами должно быть иначе?

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

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

Да, ленивая ты жопа. Скопипасти одну строчку. Тебя не беспокоит, что тебе требуется 2 массива, чтоб складывать в них объекты 2х типов, так почему с лямбдами должно быть иначе?

Т.е. генерики ненужны? Я правильно понимаю? И трейты ненужны?

А если лямбда у тебя в 2 строчки? А так да, я забыл, раст это же днище, более половины кода - мусора и копипаста. И это привычно его адептам

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

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

Типа вывода типов и прочего. Удачно.

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

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

Если бы при рождении C++ этот недостаток union-а был учтен и в C++ вошел какой-то более продвинутый вариант, надобности в std::variant, возможно, и не было бы.

Значит юнион всё-таки не подходил? Так почему Труп не добавил продвинутый?

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

для меня выглядит шизофренично (т.е. содержит ряд противоречий внутри).

Во фразах «дом невысокий» и «дом деревянный» не может быть противоречий. Эти мои 2 утверждения соотносятся между собой примерно так же.

Только тут вот какое дело: язык C++ до принятия стандарта существовал в виде «язык C++» лишь пока был всего один cfront. Как только появились другие реализации, то встал вопрос о том, а что же считать C++ и можно ли говорить, что конкретный компилятор поддерживает именно C++.

Для этого необязателен был никакой комитет. Понятие АП существует очень давно, если Страуструп придумал язык и назвал его C++, то в общем и целом, хотя бы «по понятиям» ясно, что его писульки имеют значение, а, например, мои, изданные под видом новой версии спецификации - нет. Так что наличие комитета спиногрызов тут вообще не роляет. Тот же Майкрософт, тот же GCC - все они ковыряли свои диалекты и дружно забивали на ISO-стандарт и им за это ничего не было. Тут больше психологическое. Комитет скорее нужен, ну кроме того чтоб обеспечить хороших людей работой, для повышения престижа, типа это не выживший из ума старик где-то в башне что-то там пишет, а комитет, куда приглашены все заинтересованные. И если завтра Страуструп вдруг помрёт, то сохранится некий источник центрального стандарта, а не 5 разных диалектов, развиваемые разными «наследниками». Из этого следует, что язык хороший, надёжный, нестрашно на нём начинать разработку проекта с жизненным циклом во много лет.

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

Кстати, а помоги мне. У меня есть add и список типов, я хочу реализовать операцию. Ладно ты там будешь обмазываться мусором, матчами, даже костыльком мусорным можно поматчить.

Вот тебе код на расте:


struct _F64 {
    value: f64
}
struct _I64 {
    value: i64
}

enum Value {
    F64(_F64),
    I64(_I64)
}

fn add(a: Value, b: Value) -> Value {
    return match(a, b) {
        (Value::F64(a), Value::F64(b)) => Value::F64(_F64{value: a.value + b.value}),
        (Value::I64(a), Value::I64(b)) => Value::I64(_I64{value: a.value + b.value}),
    }
}

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

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

Сколько мне матчей в этом мусоре нужно написать, чтобы это работало для 10 типов? Посчитаешь?

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

А про эту чушь тебе ответили. В целом тебе удобно спорить с подобными @eao197 персонажами, которые не обладают нужным пониманием и +/- ретранслируют ту же чушь, что и ты.

Давай ещё раз. Вариант не имеет никакого отношения к union. Запомни это. Поэтому появится тогда он не мог.

Вариант - это сериализация/десериализация полиморфизма. Появился он тогда, когда из си с классами вырос С++, в котором родилась(случайно) то, чего нигде нет - статический полиморфизм. Именно полиморфизм, а не убого говно. Твои трейты/генерики и прочий мусор - это не полиморфизм. Это огрызочный полиморфизм - табличный.

Настоящий полиморфизм до этого был только в динамически-типизированных языках.

Есть проще, то visit - это fmap(x, f);, тоже самое что для тапла. Всё. Ни к какому union/enum/visit(о котором ты слышал где-то в жаве) это отношения не имеет.

Это то как сделать fmap(any, f) эквивалентным fmap(tuple, f), с any в глобально открытой системе типов мы сделать не можем, но вот локально-закрытой можем.

А union - это лишь сторедж, и то он там не используется. Потому что в C++ нет структурного полиморфизма по коду. Т.е. структура кода всегда одна. Можно что-то отключать/включать, но не изменять. Рефлексия - это попытка исправить это.

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

А как visit он называется потому, что использует некий подобный подход. Просто map/fmap его не назвать. В целом сложно рядовым си с классами-пацанам объяснить что такое полиморфизм, нахрена оно надо и прочее.

Вот визиторы они +/- знают. Оно +/- похоже.

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


fn foo<T>(x: T) ->  usize { x.len() }//ошибка

fn foo_visit<T>(x: T, f: impl Fn(T) -> usize) -> usize {
    f(x)
}

fn main() {
    foo_visit("123".to_string(), |x| x.len());
}

Вот простой пример. Первая функция не работает. Вторая работает, потому что убогий костыль.

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

Вот в цпп нет полиморфизма по возвращаемому значению, поэтому используется тот же хак. Конечно, цпп не такое говно и хаки там по сложности сложнее всего раста, но всё равно. Суть +/- та же.

Точно так же, допустим, работает твой option и его мап. Конечно, у тебя днище и ты не можешь распаковать сразу ошибку/не ошибку. Как и вернуть их. Поэтому ты используешь o.map(), как нечто что может вернуть часть типа. Именно через аргумент функции.

Вот visit это тоже самое. Только куда лучше, куда сложнее, куда мощнее.

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

Отличные проекции. К твоему сведению: я даже не помню, когда я последний раз писал больше одного if x is Y подряд.

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

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

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

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

if (x is A) {
  ...
} else if (x is B) {
  ...
} else {
  // тут надеемся что этот вариант подойдёт всем остальным
  ...
}

Так что имеем следующую ситуацию: если ты не пишешь вариант []auto && x {...} то твой std::visit(overloaded{…}, x) становится многословным и уродским аналогом match. Если пишешь авто-ветку - аналгом цепочки ифов.

А вот твоя проблема «это ж если в закрытое множество всё-таки придётся добавить новый тип» - она как бы по определению идиотская, добавление нового варианта в закрытое множество - это очень редкая штука, экстраординарная. И когда такое происходит, просто необходимо проверить, везде ли обрабатывается новый вариант корректно, и поэтому в современные языки (в отличие от старья) массово добавляют контроль полноты перебора. И твоя боязнь, что придётся писать больше кода, она основана на том, что ты - говнокодер. Вовсе необязательно копипастить один и тот же матч повсюду, процедурное программирование никто не отменял. Если у тебя N шейпов и M форматов экспорта, то тебе придётся написать N*M блоков для сохранения, неважно будешь ли ты добавлять в класс шейпа метод write(XXXWriter&) или будешь писать write_to_XXX(shape: &shape).

Но я даже пойду у тебя на поводу, и напишу

void resolve(const Identifier& id) {
   std::visit(overloaded {
       [](Id id) { resolve_index(id.value); },
       [](const Name& name) { resolve_name(name.name); },
       [](const Uuid& uuid) { resolve_uuid(uuid); },
       [](auto && id) { resolve(id); }
   }, id);
}

Что-то кардинально поменялось?

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

Но твой код неправильный. Ты опять пытаешься замести мусор под ковёр. Я исправлю

void printName(const Identifier& id) {
    std::visit(overloaded {
        [](Id id) { print(s_dbAccessor.get(id).name)}, // чё мы дураки что ли? get перегружен.
        [](const Name& name) { print(name); }, // забиваем на проверку существования
        [](const Uuid& uuid) { print(print(s_dbAccessor.get(uuid).name)); }, // во, очень удобно
        [](auto && id) {
            // самая старая ветка, написанная ещё когда оптимизированную get(const Uuid&) функцию не написали. Раньше по Uuid искалось здесь, сейчас или вообще не используется и оставлена для универсальности, или используется для поиска по каким-то редкоиспользуемым полям с ключами хз откуда
            print(s_dbAccessor.findWithUniversalSearchStoredProcedure(id.toString())); }
    }, id);
}

А потом будет переезд на распределённую архитектуру и появится идентификация данных на соседнем сервере, через URL REST.

Так понятно?

Если бы тебе не нужен был полиморфизм, ты писал бы на сишке и паскале, а на расте не трогал бы трейты.

Я же говорю: сумасшедший. Ему говорят что нахрен не нужен его полиморфизм, а он в ответ "нет, врёшь, я знаю, все любят полиморфизм.

В сишке не хватает не полиморфизма. Тем более, я хоть и сбоку, видел «полиморфизм» в проекте на сишке, запиленный через указатели на функции. myObj->foo(myObj, param1, param2, param3), такое говно забацать ненамного сложнее чем твои overloaded. Видишь, самый настоящий динамический полиморфизм и на чистом C.

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

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

Я тебе в третий раз отвечаю: да, я понял твой говнокод. Ты добавил шаблон. И теперь гордишься тем, что единственная твоя надежда на то, что шаблон не скомпиляется, если добавят что-то не то, что будет принципиально несовместимо. И всё ради того чтоб не проверять код и не написать 1 строчку.

Нет, если в нем есть _ => { … }.

Так в чём проблема? Просто не пиши такое.

Да, Rust вот пустили, из-за толпы фанбоев.

У идиотов всегда так, если что-то происходит, чего они не понимают, то или из-за заговора, или из-за толпы идиотов. У плюсов в 90е было очень много фанбоев, побольше чем сейчас у Раста. Но почему-то его не пустили. Есть версии почему?

Раст это язык для виртуальной машины. Он не может быть низкоуровневым. Задумывался когда-нибудь, что значат VM в LLVM?

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

Кстати, clang тоже является фронтэндом к той же LLVM, я уж не вспоминаю что первые версии компилятора плюсов выплёвывали на выходе сишный код.

Ты только что признал ущербность match в пользу трейтов.

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

Еще раз, это ты с самого начала пытался свести тему к С с классами.

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

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

Нет, там не существует «минимально необходимого». Для N кейсов там будет N веток. В лучшем случае ты напишешь _ => panic! и потеряешь варнинги.

Виноват, перепутал буквы в твоём примере. M сократить до минимально необходимого. Даже не M, а некое L*M. Так что правильно будет «сократить L».

Так вот, если писать по-человечески, не повторяя себя, то у тебя будет N классов, в каждом из которых LM функций. У меня будет просто LM функций, но в каждой из них матч на N вариантов. Итого и там и там LMN строк кода.

Разве что твои классы будут выглядеть офигеть как классно, ты запихаешь в них по L*M функций, в итоге твои классы будут тянуть за собой зависимостями все те либы, которые ты поддерживаешь. Тебе настучат по башке и заставят переделывать, так что ты запилишь некий общий интерфейс канваса и сделаешь рендеринг в него, а потом для каждой графической либы запилишь обёртку над ней, с реализацией твоего канваса.

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

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

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

if (x is A) {
...
} else if (x is B) {
...
}

его твоя лень укусит. И даже когда он будет писать твою любимую

std::visit(overloaded {
}), причём без ветки auto&&, он опять же наступит на твой говнокод.
khrundel ★★★★
()
Ответ на: комментарий от right_security

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

Откуда конпелятору знать, что они тебе не нужны? Что ему делать, если ты просто затупил и не подумал, что могут прийти 2 разных параметра?

Если говнокодишь - добавляй _ => panic!(). Если не говнокодишь - Делай возврат Result<Value, MismatchError>. Халявы не будет в любом случае.

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

Значит юнион всё-таки не подходил?

union подходил только для части ситуаций «или X, или Y, или …»

Тем не менее, union позволял обойтись без выстраивания иерархий классов (пусть и не всегда). Так что в C++ для ситуаций «или X, или Y, или …» вовсе не обязательно было применять ООП.

Так почему Труп не добавил продвинутый?

ХЗ. Может потому же, почему не сделал auto для вывода типов сразу в C with classes, хотя мог и даже хотел одно время.

Во фразах «дом невысокий» и «дом деревянный» не может быть противоречий. Эти мои 2 утверждения соотносятся между собой примерно так же.

Проблема в том, что вы высказались в духе: «если невысокие дома настолько лучше деревянных, то почему строят каменные». Именно так ваша фраза выглядит для человека, много лет плотно работающего с C++.

Для этого необязателен был никакой комитет.

Это вам так кажется. И, мне думается, вы сильно заблуждаетесь.

Тот же Майкрософт, тот же GCC - все они ковыряли свои диалекты и дружно забивали на ISO-стандарт и им за это ничего не было.

Производитель компилятора может добавить в язык свои расширения (что в 90-х делали, на моей памяти, как минимум, Borland и Microsoft). Только вот если проект начинает завязываться на расширения от Borland-а, то это уже не совсем проект на C++. Тогда как наличие стандарта позволяет понять, где у нас завязка на конкретного вендора, а где у нас код, который может быть скомпилирован другим компилятором.

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

Простите, обсуждать вашу конспирологию нет желания.

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

Если говнокодишь - добавляй _ => panic!().

Т.е. все ошибки добавления далее - в дерьме.

Если не говнокодишь - Делай возврат Result<Value, MismatchError>. Халявы не будет в любом случае.

Да ты чё, и описывать n * n матчей вместо n? И что я потом с этим мусорным Result буду делать? Куда делся зерокост? Куда я потом засуну этот result? Сколько мне дерьма ещё сверху навалить нужно?

Как мне проверить это на уровне типов? Как мне после протестировать этот add для отдельных типов?

Халявы не будет в любом случае.

Халява - это что? Писать код как человек? Писать код, а не бездарное дерьмо?

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

Эти оправдания.

Вот когда он будет писать твоё нелюбимое

Ты не знаешь что это такое. Продолжаешь толкать своё невежество. is - это для открытых типов. Тупой enum-мусор таким не является. Поэтому заменить is не сможет.

На самом деле даже visit не везде может, потому как базируется на не-расширяемом типе. И его не всегда можно расширить.

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

Ля ты тупой. LLVM - это кодогенератор.

Врёшь.

Или бэкенд, если хочешь. Пофиг как он называется.

Нет, ллвм это компилятор. А вот раст-огрызок - это огрызок фронтенда к нему. Почему огрызок? Потому что даже код сам не генерирует.

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

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

Т.е. в сознание домохозяек vm - это жава. Вот пришлось это отменять.

Кстати, clang тоже является фронтэндом к той же LLVM

Удивительно, кстати, как работает пропагандист. Т.е. шланг это фронтенд, а раст-огрызок - это не фронтенд? А там ллвм уже бек. Куда делся мидл?

К тому же шланг и есть часть ллвм. Поэтому это и есть ллвм. И даже если бы не был - это ничего не изменит. Потому что это родное для цпп.

я уж не вспоминаю что первые версии компилятора плюсов выплёвывали на выходе сишный код.

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

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

Но т.к. сишная среда исполнения она нативная - там можно статически(ну с кусками рантайма) транслировать это в код. Для этого ненужно в рантайме существования vm.

Поэтому ллвм так и назвали. Лоул-левел, либо без абстракций, либо зеро-рантайм вм. Это отличается от той же жавы.

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

Но твой код неправильный. Ты опять пытаешься замести мусор под ковёр. Я исправлю

Кстати, я не увидел даже этих откровений. Очевидно, что всё это чушь не имеющая отношения к реальности. В цпп таких проблем нет.

Но даже если предположим, что они где-то в параллельной вселенной есть. ЧТо нам несёт данный персонаж? По-сути то, что:

_ => {}//вот мы написали ветку, а потом бам поменялось - и всё просралось

Таким образом данный персонаж должен воевать в сторону против _ => , но что-то не воюет? Почему? «это другое»?

самая старая ветка, написанная ещё когда оптимизированную get(const Uuid&) функцию не написали. Раньше по Uuid искалось здесь, сейчас или вообще не используется и оставлена для универсальности, или используется для поиска по каким-то редкоиспользуемым полям с ключами хз откуда

Вот именно эти фантазии мусор. Здесь агитатор за сахарок попытается подменять свой мусорный язык, который не может в типы и выдавать это за свойства C++.

Т.е. в С++ ненужно писать to_string и прочий мусор. Поэтому:

findWithUniversalSearchStoredProcedure

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

Т.е. такой мусор на С++ не пишут. Его пишут на убогих языках(типа раста), которые не умеют в типы и не могут в типобезопасность.

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

И ты, с ним во всём согласный.

А что, он где-то в текущей дискуссии был неправ? Ты съехал со всех ответов в отрицание и «не нужно», никаких аргументов не предоставив. Почему я должен быть не согласен с ним?

Так что имеем следующую ситуацию: если ты не пишешь вариант

Если пишешь авто-ветку - аналгом цепочки ифов.

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

требует внедрения «клиентского» кода во все классы

Не требует. Если есть такое желание, можно написать […] А можно добавить еще один обработчик [](auto && x){ print(x); }, и бесплатно получить возможность добавлять новые типы в Identifier

А вот твоя проблема «это ж если в закрытое множество всё-таки придётся добавить новый тип» - она как бы по определению идиотская,

И опять «ненужно». Да что ты будешь делать. Есть проблема. Нужно решить. Но хрюндель считает, что ее решать надо редко, да и вообще можно копипастить.

и поэтому в современные языки (в отличие от старья) массово добавляют контроль полноты перебора.

Если бы ты внимательно почитал, ты бы увидел, что variant+visit как раз требуют полноты перебора. Передаваемый визитор обязан уметь обработать все типы варианта, иначе код не скомпилируется. Ты второй раз пишешь эту чушь, хотя я тебе уже ответил в сообщении Rust: преобразования указателя на трейт в конкретный тип (комментарий)

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

Более того, я специально выделил жирным слово предупредит. Ты опять попытался проигнорировать мой аргумент.

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

Там Роман привел тебе отличный пример с Value на тему боязни писать больше кода. Вперед, пиши, мешать не буду. Рекомендую перейти на построчную оплату труда.

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

Да. Более того, я уже написал, что в реальном коде никакие обработчики по типам не нужны, нужен только auto&&. Некорректно «разресолвить» новый идентификатор обработчик не может, это не скомпилируется, и тебе будет явно видно, что для твоего типа нужно добавить перегрузку resolve, чтобы visit начал работать как и раньше. Подчеркну, именно перегрузку, а не новый обработчик.

Но твой код неправильный. Ты опять пытаешься замести мусор под ковёр. Я исправлю

Наконец-то! Ты решил ввести тему контекстов обработки. Оказывается (!) обработка ведется не в вакууме, а с каким-то контекстом, зависящим от ветки исполнения, и для работы понадобятся все эти контексты, которые нужно будет хранить и ручками. И вот у тебя есть суперобъект, который тянет с собой N контекстов, по одному для каждой альтернативы варианта. Если бы только можно было использовать не сум-тип и match по нему, а в принципиально разных ветках исполнения обработать разные идентификаторы, не смешивая все это в кучу «мусора» на ковре или под ковром.

Ну да ладно, оставим это архитекторам. Мы не боимся писать «много» кода, поэтому проблема решается элементарно добавлением геттера

[](auto && id){ resolve(get_ctx(super_ctx, id), id) }

Тогда перегрузки придется добавлять уже две – одну для resolve, одну для get_ctx. А можно просто делать resolve(super_ctx, id), но тогда придется в каждой перегрузке этот контекст извлекать, что чуть менее красиво.

Так понятно?

А потом будет переезд на распределённую архитектуру и появится идентификация данных на соседнем сервере, через URL REST.

А вот твоя проблема «это ж если в закрытое множество всё-таки придётся добавить новый тип» - она как бы по определению идиотская,

Без комментариев. В принципе, можно закрывать тему.

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

Ему говорят что нахрен не нужен его полиморфизм

А почему тогда enum нет в публичных интерфейсах вменяемых крейтов? Все почему-то на трейтах пишут, странно как-то. Зачем-то вариадики хотят добавить, пишут HList’ы, макросы для реализации подобия visit?

В сишке не хватает не полиморфизма. Тем более, я хоть и сбоку, видел «полиморфизм» в проекте на сишке, запиленный через указатели на функции

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

Шаблоны, конечно, похуже дженериков будут

Без комментариев. Настолько похуже, что в rustc так и не осилили.

И всё ради того чтоб не проверять код и не написать 1 строчку.

Я устал повторять, сколько раз я уже писал, что это не ради написания 1x(число match’ей в проекте) строчек, а ради возможности расширять множество типов, не изменяя при этом код обработчика.

У плюсов в 90е было очень много фанбоев, побольше чем сейчас у Раста. Но почему-то его не пустили. Есть версии почему?

Плюсы в 90е были не С++, а С с классами. Еще вопросы?

LLVM - это такая виртуальная машина, которая, например, интерпретирует байт-код или эмулирует какую-то среду

Вообще-то, именно этим она и занимается – имитирует сишную среду для фронтов. Байт-код она не интерпретирует, потому что, как @right_security уже отметил, это zero-рантайм виртуальная машина.

LLVM создана по образу и подобию сишной модели для крестов. Rust был создан для LLVM.

Кстати, clang тоже является фронтэндом к той же LLVM

Я уже написал про то, что фронт фронту рознь.

Не, просто ты ничего не понял. Я сообщил задачу: реализовать тип-сумму.

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

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

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

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

Ты так ничего и не понял. Ни про множества типов, ни про расширяемость, ни про полиморфизм, ни про сахар vs нативные возможности языка.

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

Итого и там и там LMN строк кода.

Браво, до тебя дошло то, что я пытался объяснить тебе. Осталось понять, что с увеличением N на 1 для match придется в LM матчей добавить по 1 ветке, а для классического наследования – добавить LM реализаций. Пропорция сохраняется, но LM реализаций будут в одном месте, а не раскиданы по всему проекту.

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

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

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

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

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

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

А, я понял, т.е. ты, призывающий в свидетели Царя и eao197, не пытаешься доказывать что-то на чужими авторитетами

Если ты не заметил, я ссылался не на их «авторитет», а на их сообщения, на которые ты ничего осмысленного не ответил.

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

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

правило «не наследовать реализацию» написано кровью программистов

Да? Блин, не знал. Спасибо, что сообщил.

Вот когда он будет писать твоё нелюбимое его твоя лень укусит.

Как конкретно? Он нарвется на мифическую мину?

И даже когда он будет писать твою любимую […]

Тут тоже мифическая мина заложена?

причём без ветки auto&&

А, ну да.

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

Я уже написал про то, что фронт фронту рознь.

Кстати, да. Пропаганда прям это не учитывает. Да и в целом редко об этом говорится.

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

LLVM создана по образу и подобию сишной модели для крестов.

Скорее она реализует именно крестовую среду исполнения, но базой её является именно си. Кресты там про всякие исключения и прочее.

Почему сишной, дополню, чтобы пацанам понятнее было. Потому что только сишка в этой реальности имеет некую адекватную обобщённую модель исполнения.

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

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

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

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

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

А что, он где-то в текущей дискуссии был неправ?

Правильнее задать вопрос, когда это Царь хоть в чём-то был прав. Какую ахинею он несёт «std::variant придуман для сериализации полиморфизма».

std::visit(overloaded{
    [](const A& v){ print("a found");},
    [](const A& v){ print("b found");}
}, x)

Где ты тут видишь появление хоть какого-то полиморфизма? Или его «сериализацию».

До тебя так и не дошло, что пример без auto я приводил только для того,

Нет, это до тебя не дошло, тупица. Ты меня бесишь уже, как можно так тупить?

Ещё раз, для дебилов:

  • Если ты пишешь визит(оверлоадед) без auto ты получаешь кривой аналог матча. Кривой, потому что из-за приведения типов может неправильно провериться полнота.
  • Если ты пишешь визит(оверлоадед) c auto, ты получаешь семантический аналог цепочки if (x is Y), так как полнота никак не проверяется и всё падает в else, в лучшем случае получишь ошибку в рантайме. В худшем - некорректное поведение.

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

Если бы ты внимательно почитал, ты бы увидел, что variant+visit как раз требуют полноты перебора.

Если ты не написал ветку auto&&. Но ты же утверждаешь, что её надо писать.

Да и на самом деле хреново он это делает.

  std::variant<int, float, char> test = 'a';
  std::visit(
      overloaded {
          [](const int& value){std::cout << "(int)"<<value<<std::endl;},
          [](const float& value){std::cout << "(float)"<<value<<std::endl;}
      }, test);

Я сам такой срани не ожидал, кстати, думал что проблема возникнет если написать [](int value){...} и хотел подсунуть тебе [](const int value){...} и предложить заметить баг. Оказалось, даже требование в качестве параметра неконстантной ссылки не спасёт.

Более того, я специально выделил жирным слово предупредит. Ты опять попытался проигнорировать мой аргумент.

Как видишь, не предупредит.

Ты, конечно, можешь сейчас начать свистеть, что варианты с int/char никто не использует и нормальные пацаны кладут только пользовательские классы, но, тут я напоминаю тебе, что ты же у нас предупреждения GoF не слушаешь и активно агитируешь за наследование реализации. Так что ты наследуешься от MyClass, а твой коллега добавит нового потомка в variant.

Ну да ладно, оставим это архитекторам. Мы не боимся писать «много» кода, поэтому проблема решается элементарно добавлением геттера

[](auto && id){ resolve(get_ctx(super_ctx, id), id) }

Тогда перегрузки придется добавлять уже две – одну для resolve, одну для get_ctx. А можно просто делать resolve(super_ctx, id), но тогда придется в каждой перегрузке этот контекст извлекать, что чуть менее красиво.

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

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

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

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

А почему тогда enum нет в публичных интерфейсах вменяемых крейтов? Все почему-то на трейтах пишут, странно как-то. Зачем-то вариадики хотят добавить, пишут HList’ы, макросы для реализации подобия visit?

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

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

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

Как без проверок компилятора, дурак? Указатели на функции типизированы. Ёмана, ты и си с плюсами не знаешь что ли?

Без комментариев. Настолько похуже, что в rustc так и не осилили.

У фанатика плюсов всегда как что-то из наследия выбрасывается, так сразу «не осилили». Видимо не только в rustc не осилили, а примерно во всех языках последних 20 лет. Те же программисты, которые пишут в MS шлабоны для компилятора плюсов, сразу же теряют этот навык, когда приходится пилить компилятор C#.

Давай я ещё раз раздавлю тебя авторитетом. Знаешь такого Александреску? Большой авторитет по шаблонной магии. Так вот, он ушёл пилить язык D и потом подготовил целое выступление на тему «сука, какой дебил придумал эти шлабоны? Насколько же хорош язык go, в котором просто пишешь особый коммент с кодом на том же го, и он генерирует тебе код».

Я устал повторять, сколько раз я уже писал, что это не ради написания 1x(число match’ей в проекте) строчек, а ради возможности расширять множество типов, не изменяя при этом код обработчика.

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

Плюсы в 90е были не С++, а С с классами. Еще вопросы?

Мне тут писали, что всё что было сказано в 98 стандарте до этого описывалось самим Трупом в начале 90х. Так что 98 это тоже получается си с классами. Учитывая, что с 98 по 2011 развитие плюсов было околонулевым, я правильно понимаю, что C с классами было до 2011? А когда он расцвёл тогда?

Я уже написал про то, что фронт фронту рознь.

Мало ли что ты написал? Никаких аргументов ты не привёл, а твоё мнение, учитывая что ты просто фанатик безумный, вообще мало чего значит.

Но если хочешь, можешь разжевать, почему CLANG+LLVM не делает плюсы языком для виртуальных машин, а rustc+LLVM - делает.

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

Отлично, теперь ты утверждаешь, что задача «нужен тип-сумма» на плюсах до середины нулевых вообще никак не решалась?

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

Ты так ничего и не понял. Ни про множества типов, ни про расширяемость, ни про полиморфизм, ни про сахар vs нативные возможности языка.

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

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

Браво, до тебя дошло то, что я пытался объяснить тебе.

Не так всё было. Ты написал мне «Сколько веток придется дописать, добавь я N+1-й вариант? Ты там ранее что-то про удобство сообщал, не так ли, про локальность?». Я тебе возразил, что ровно столько же, сколько если делать через наследование, разве что ты - дебил и наследованием реализации занимаешься или разве что ты - дебил и будешь бездумно матчи копипастить вместо того чтоб нормальных функций запилить". Ты мне отвечал, что нет ничего плохого в наследовании реализаций, а GoF просто фигню какую-то написали. Если ты таким образом хотел согласиться со мной, что писать придётся одно и то же число строчек, так надо было так и сказать.

N на 1 для match придется в LM матчей добавить по 1 ветке, а для классического наследования – добавить LM реализаций. Пропорция сохраняется, но LM реализаций будут в одном месте, а не раскиданы по всему проекту.

Так это глупость. И я уже раза 3 тебе объяснил почему. Представь, что на 1 увеличивается не N, а M. Тогда и там и там придётся написать L*N строчек. Только с енумами/вариантами это будет локально, а с наследованием - куча строчек по всем файлам.

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

Что более вероятно, что придётся расширять тот набор типов, который ты всё это время считал закрытым, и поэтому поместил в енум/вариант, или то что ты будешь портировать свой проект на новую OS, добавлять поддержку новой графической библиотеки или новой версии, или нового формата сохранения данных?

Если ты не заметил, я ссылался не на их «авторитет», а на их сообщения,

Ну так и я ссылался на «сообщение» за авторством GoF. Тебя это не остановило.

Заметь, когда я «ссылаюсь на авторитета», я пишу конкретное утверждение, максимально коротко. Когда ты ссылаешься на авторитет Царя, ты пишешь что-то типа «тебе уже и Роман и я 10 раз пытались объяснить». Так что ты и тут соврал, это я указываю тебе на проблемы твоего понимания, а ты просто тянешь людей для массовки, видимо так тебе легче, 2 сумасшедших же не могут оказаться неправы.

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

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


  std::variant<int, float, char> test = 'a';
  std::visit(
      overloaded {
          [](const int& value){std::cout << "(int)"<<value<<std::endl;},
          [](const float& value){std::cout << "(float)"<<value<<std::endl;}
      }, test);

Ну, что ты этим хотел сказать? Давая я тебе помогу.

  • Ты умножил себя на ноль, потому как то что ты спастил никакого отношение не имеет к visit/variant. Это базовая семантика.

  • В базовой семантике есть преобразования типов. Это базовое поведение языка.

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

  • Даже если ты начнёшь рассказывать сказки иные, о том что ты не не смог, а не захотел - это так сразу мимо. Потому как тебе придётся обтекать за collect/into, которые так же являются преобразованиями типов.

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

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

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

@khrundel Я увижу ответ? Или конечная?

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

Правильнее задать вопрос, когда это Царь хоть в чём-то был прав.

Хватит «вертеть жопой». Ты ни на что не ответил, и теперь пишешь «ну это же он, он же всегда неправ, все знают».

Где ты тут видишь появление хоть какого-то полиморфизма?

Ты кретин. Тебе многократно написали, что должен писаться auto&&, но до тебя так и не дошло. Ты сделал из visit свой match, который не является полиморфным, и спрашиваешь: «а где полиморфизм»?

Если ты пишешь визит(оверлоадед) c auto, ты получаешь семантический аналог цепочки if (x is Y), так как полнота никак не проверяется и всё падает в else,

Ты кретин. Я многократно писал, что полнота проверяется/

Ты кретин. Я многократно писал, что ты не знаешь кресты, так как код ты так и не понял. Никакого else там не существует, потому что там не должно быть никаких конкретных типов кроме auto&&. Обработчик auto&& сам по себе является полиморфным, поскольку вызывается для разных типов. visit([](auto && x){ ... }, x) – этого достаточно.

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

ты же у нас предупреждения GoF не слушаешь и активно агитируешь за наследование реализации

Цитату и ссылку на сообщение, где я активно агитирую за это.

Кстати, а чем же так плохо наследование реализации? Или мидлу не положено это знать?

Нет, ничего не выйдет. Напоминаю легенду:

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

Так что даже не зная про YAGNI никаких контекстов ты, ленивая жопа, писать бы не стал.

Ты кретин. Контексты ввел ты, и уже активно их используешь для обработки в своих матчерах. Обернуть их в структурку и написать auto& get_ctx(SuperCtx& ctx, Id id) для каждого варианта – дело трех минут.


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

Ты лжешь.

Даю «приблизительную» оценку: ни одна библиотека из most downloaded на первой странице crates.io не использует в публичном интерфейсе enum ни для чего, кроме передачи флагов.

не заметил идеоматическую обработку ошибок в расте.

Идиоматическая обработка ошибок в расте – Result<T, Box<dyn Error>>. Знаешь, почему? Потому что enum не скейлятся. Каждый новый слой enum должен включать предыдущий, разрастаясь бесконечно в размере и приводя к лавинообразным изменениям в коде в случая изменения любого элемента обработки ошибок. Популярность anyhow – отличное доказательство тому.

Указатели на функции типизированы

Поработай хоть раз с таким API.

Видимо не только в rustc не осилили, а примерно во всех языках последних 20 лет.

Те же программисты, которые пишут в MS шлабоны для компилятора плюсов, сразу же теряют этот навык, когда приходится пилить компилятор C#.

«Все языки последних 20 лет» не претендовали на место С/С++, и никакого превосходства над ними не заявляли. А вот в Haskell например осилили, пусть и в крайне кастрированном виде (см. Template Haskell). Но они осилили и свой компилятор, до чего rustc как до звезд.

Давай я ещё раз раздавлю тебя авторитетом. Знаешь такого Александреску? Большой авторитет по шаблонной магии.

Не имеет никакого отношения к современному С++.

он ушёл пилить язык D

В который перетащил фишки, разработанные и предложенные в комитет, но в то время еще не принятые. С тех пор D сдох, никому не нужный, никакой конкуренции современному С++ по возможностям он не составляет.

Насколько же хорош язык go

В котором не нужно делать impl Trait for Type, а просто описываешь интерфейс – и проходить будут все типы, подходящие под этот интерфейс. Ты вообще понимаешь, насколько ты сейчас себя закопал?

пишешь то же самое что и я, просто я описываю твою лень и распиздяйство честно,

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

я правильно понимаю, что C с классами было до 2011? А когда он расцвёл тогда?

Да. Расцвел после С++03, что вылилось в публикацию С++11.

Мало ли что ты написал?

Все, что я написал, ты проигнорировал. Почитай еще раз.

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Во-первых, LLVM это компилятор, написанный для крестов и на крестах. GCC не целиком, но на большую часть для крестов, и на значительную – на крестах. Во-вторых, фронт фронту рознь, и это становится понятно, если сравнить количество работы, проделываемой clang и rustc. При на порядки более высокой сложности С++ порождаемый clang код вполне достойно выглядит, даже если не сравнивать его с гигабайтами мусора на выходе rustc.

LLVM создана по образу и подобию сишной модели для крестов. Rust был создан для LLVM.

Но если хочешь, можешь разжевать, почему CLANG+LLVM не делает плюсы языком для виртуальных машин, а rustc+LLVM - делает.

Не существует clang+LLVM, clang это часть проекта LLVM. Весь проект LLVM был создан для С++, от фронта до бэка, по модели С++. rustc это убогий фронт для LLVM. Нет LLVM – нет rustc, это сугубо вторичный язык. Вместо того, чтобы писать свой компилятор, бездарности пытаются портировать фронт на gcc – а ведь даже у маргинальных функциональных язычков часто бывают полностью самостоятельные компиляторы. Некто Drew DeVault написал для своего Hare компилятор в одиночку, и это уже полностью рабочий язык – меньше чем за год, если я не ошибаюсь, а ведь язык не из самых примитивных, примерно уровня гошки.

Отлично, теперь ты утверждаешь, что задача «нужен тип-сумма» на плюсах до середины нулевых вообще никак не решалась?

Ты кретин. Тебе уже много раз привели в пример Boost.Variant и объяснили, что это реализуется с С++98 – нужны лишь шаблоны и перегрузка.

Ты поехавший. Даже я так плюсы не решился бы обосрать

Это был даже не С++, а С с классами – а задача уже решалась.

со мной, что писать придётся одно и то же число строчек,

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

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

Представь, что на 1 увеличивается не N, а M.

Только с енумами/вариантами это будет локально, а с наследованием - куча строчек по всем файлам.

Бред. При соблюдении правил классического ООП код класса будет инкапсулирован, что по определению исключает «кучу строчек по всем файлам».

Когда ты ссылаешься на авторитет Царя,

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

Если ты не заметил, я ссылался не на их «авторитет», а на их сообщения,

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

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

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

бездарности пытаются портировать фронт на gcc

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

Там максимально очевидный сишный жит, который и использует раст-огрызок. Про ллвм они ничего не знают, плюс постоянно рассказывают про какой-то ir(который вообще к раст-огрызку отношения не имеет. Это внутренняя сущность ллвм).

А вот в гццжит там нет ir и уже сливаться не на что.

The library API hides GCC’s internals, and tries to be much more typesafe than GCC’s, giving something rather like Andrew MacLeod’s proposed changes - client code does not see «tree», instead dealing with types, rvalues, lvalues, basic blocks, etc. It is pure C, given the horror stories I have heard about people dealing with C++ ABIs.

The API deliberately uses C terminology, given that it’s likely that the user will want to be plugging the JIT-generated code into a C/C++ program (or library).

Так же можно посмотреть пример хеловорлда там прям по ссылке рядом.

У llvm +/- такое же апи. Там чуть больше своей специфики, но суть одна.

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

right_security
()

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

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

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

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

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

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

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

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

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

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

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

Насколько я понял по доке - это именно просто таргет для трансляции. Т.е. нужно как минимум написать транслятор в него. Это уже делает его выше раст-огрызка.

Но в целом это так же сишка-вм. Но там совсем лоулевел-операции, транслирующиеся по-сути 1в1. Это можно записать в то, что его нет.

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

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

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

Хватит «вертеть жопой». Ты ни на что не ответил, и теперь пишешь «ну это же он, он же всегда неправ, все знают».

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

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

Не, то что ты считаешь, что должен писаться auto&& я понял сразу, и именно поэтому я называю тебя дебилом. Вообще, странный ты. Я тебе с самого начала пишу, что ты - идиот, потому что предлагаешь auto&&. Можно было бы со мной спорить, наверное. Но чего точно нельзя - так это делать вид, будто я не понял, что ты предлагаешь auto&&. Наоборот, я с самого начала называю тебя дебилом именно за то что ты это самое auto && предлагаешь. Ты понял? Раз ты предлагаешь auto&& - значит ты - дебил. Надеюсь, из сказанного ты усвоил что-то, ну хотя бы то что я понял, что ты любишь auto&& ветку.

Ты кретин. Я многократно писал, что полнота проверяется/

Ты-то писал, но это не соответствует действительности. Полнота не проверяется даже когда ты не пишешь ветку с auto&&. А когда пишешь - ещё хуже.

Вообще, я тебе привёл код. Проверь его, клоун.

Я многократно писал, что ты не знаешь кресты, так как код ты так и не понял.

Как показала практика, я знаю кресты лучше тебя. При том что я их реально знаю шапочно. В последний раз на них писал более 10 лет назад.

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

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

Цитату и ссылку на сообщение, где я активно агитирую за это.

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

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

И ты опять соврал. Я всего лишь написал правдоподобный код извлечения данных из БД. Вообще, забавно как ты писал resolve(id) до того как я поймал тебя, и вдруг резко переобулся и добавил какие-то методики получения правильного «контекста». Так всё-таки, как ты собрался ресолвить айдишники? Через простую функцию, или через дополнительную функцию для получения контекста? Если второе, зачем ты врал мне, предлагая простую функцию?

Не имеет никакого отношения к современному С++.

Да уж конечно. Александреску знает современные плюсы хуже тебя.

Ты лжешь.

Не лгу, клоун, а не заметил. Ну что ж, ты обосрался и тогда. Вообще, заметь, что ты и тут соврал. Я задал тебе вопрос «как часто используются енумы». А ты что ответил? «Как часто енумы присутствуют в публичном интерфейсе класса». Это ответ на другой вопрос. Для примера, как часто в расте используются лямбды? Правильный ответ: постоянно. Однако в публичном интерфейсе горазо реже.

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

Идиоматическая обработка ошибок в расте – Result<T, Box>

Нет, конечно. Это ты, дебил, выдумал. Но даже если бы это было так: Result<T, Box> - это enum.

Знаешь, почему? Потому что enum не скейлятся. Каждый новый слой enum должен включать предыдущий,

Глупость.

Поработай хоть раз с таким API.

Ну да, такие как ты char* (*func)(struct MyStruct*, int); не осилят, конечно.

«Все языки последних 20 лет» не претендовали на место С/С++,

Какая разница, претендовали ли они? Все они отказались от утинной типизации плюсов. Заменили её нормальными интерфейсами. Это, в общем-то, приговор плюсам.

В который перетащил фишки, разработанные и предложенные в комитет, но в то время еще не принятые. С тех пор D сдох, никому не нужный, никакой конкуренции современному С++ по возможностям он не составляет.

Тут я с тобой согласен. D - бессмысленный язык, главным образом потому, что пытается хотя бы отчасти быть совместимым с плюсами. В итоге получился недоC#. Но это не отменяет факта, что плюсы - говно.

В котором не нужно делать impl Trait for Type, а просто описываешь интерфейс – и проходить будут все типы,

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

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

Какие твои слова я переврал? Ты пишешь «не надо писать дополнительные строки». Я пишу: «ленивая жопа не хочет писать дополнительные строки». Разница между нашими утверждениями лишь в том, что ты описываешь отсутствие необходимости что-то писать как некую ценность, а я делаю шаг дальше и описываю её же как нечто приятное твоей лени и халатности.

Да. Расцвел после С++03, что вылилось в публикацию С++11.

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

Во-первых, LLVM это компилятор, написанный для крестов и на крестах. Во-вторых, фронт фронту рознь, и это становится понятно,

И это всё? Да похер. Первые компиляторы C писались на ассемблере, и из этого не делаются никакие выводы. Первые компиляторы плюсов писались на C и опять же, никаких выводов не делается.

Ты жалок, клоун.

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

Не существует clang+LLVM, clang это часть проекта LLVM.

Нет, клоун, существует фронт clang и бэк LLVM. Они могут разрабатываться в тандеме, но это ни на что не влияет. Вон, тот же GTK когда-то был тулкитом для Gimp, и что с того?

Ты кретин. Тебе уже много раз привели в пример Boost.Variant

Кретин не я, а ты. Именно ты утверждаешь, что решения проблемы «нужен тип-сумма» C++ не предоставлял. Я же пишу обратное: C++ с самого начала, с 80х предлагал решение этой проблемы. Просто решение было плохое.

Это был даже не С++, а С с классами – а задача уже решалась.

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

Не строчек, а веток.

Неважно от слова совсем.

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

Ключ был в том, что ты в очередной раз соврал, подбирая удобный вариант.

Бред. При соблюдении правил классического ООП код класса будет инкапсулирован, что по определению исключает «кучу строчек по всем файлам».

Не будет он никуда инкапсулирован. Ты просто добавишь абстрактный draw(XxxCanvas) в базовый класс и потом реализуешь его в потомках.

В теории ты мог бы обернуть XxxCanvas внутрь класса MyXxxCanvas, который реализует интерфейс GenericCanvas, рисование в который у тебя бы было до этого реализовано. Это потребовало бы овердофига лишнего кода и именно поэтому ты бы не стал этим заморачиваться. Но, если представить чудо, что ты решил-таки действовать не через жопу, а через общий для всех библиотек интерфейс, на практике ты бы облажался просто потому, что реальный интерфейс XxxCanvas оказался бы несовместим с существующим на тот момент GenericCanvas. Оказалось бы что придуманный тобой до этого GenericCanvas синхронный, а XxxCanvas - асинхронный, или что XxxCanvas хранит свойства рисуемых объектов не так. Или ещё что-то. Так что тебе бы пришось бы либо менять интерфейс GenericCanvas и все его реализации, либо пилить отдельный уникальный путь рендеринга.

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

Нет, клоун, существует фронт clang и бэк LLVM. Они могут разрабатываться в тандеме, но это ни на что не влияет.

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

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

Вон, тот же GTK когда-то был тулкитом для Gimp, и что с того?

Причём тут гтк? Ты решил слиться на маня-фантазии?

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

И это всё? Да похер. Первые компиляторы C писались на ассемблере, и из этого не делаются никакие выводы.

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

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

Первые компиляторы плюсов писались на C и опять же, никаких выводов не делается.

Опять же, та же самая ситуация. К тому же цпп являются си и там нет никаких проблем. Даже если бы они хоть сейчас были написаны на си.

Давай я тебе покажу, как ситуацию рассматривает нормальный человек:

Не человек, а раст-пропагандист-фанатик. Не путай.

«компилятор раста

Никакого компилятора раста не существует. Существует огрызок фронтенда. Как и невозможно написать компилятор раста - у него нет модели исполнения.

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

Но у жавы свой байткод. И она в него собирается. Растоскам не имеет своего байткода, не имеет ничего. Просто нахлабучка на сишнымивм.

использует для кодогенерации существующую библиотеку llvm.

Нет, он существует потому что существует ллвм - это первое обстоятельство. Второе - он не может ничего кодогенерировать, потому что ничего не знает о коде.

И ему похер на каком языке она написана, хоть на бейсике».

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

Только для си существует более-менее полноценная переносимая модель исполнения. В очередной раз запутался в показаниях.

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

Спроси его ещё о том - почему он несёт херню про «файлы», а то он мне не отвечает.

Ты слишком многословен.

Файлы, если я правильно понял твой вопрос, это исходники. При полиморфном подходе они имеют свойство засираться виртуальными функциями.

Потом, когда ты будешь дропать какие-то либы, тебе придётся удалять лишние функции. Это гемор.

Т.е. что мне мешает даже в случае с наследованием/виртуальными функциями - положить все эти классы в одно место?

Ну вот, гипотетически, у тебя есть классы с графическими примитивами. Они лежат в одном месте, в директории graphics. Как это тебе поможет уберечься от необходимости добавления в них виртуальных функций getName(), getXmlName(), writeSvgElement(SvgElement& parent),getWhateverLibraryElementType(), draw(XxxLibraryRenderTarget&), save(DataTarget&)?

Никак.

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

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

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

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

И что? Rustc тоже не может работать без LLVM. Так какая разница между ними?

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

Ну давай, просвети меня, что такое llvm.

Причём тут гтк?

При том, что он отлично демонстрирует, почему вы с Siborgium идиоты.

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

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

Файлы, если я правильно понял твой вопрос, это исходники. При полиморфном подходе они имеют свойство засираться виртуальными функциями.

Т.е. ты мне впаривал какой-то жава-мусор? А теперь перешёл в манёвры?

Потом, когда ты будешь дропать какие-то либы, тебе придётся удалять лишние функции. Это гемор.

Чё ты несёшь. Какие либы? Откуда ты их взял? Какие функции. Что ты несёшь?

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

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

В твоих фантазиях. Если у тебя может не лежать - у меня тоже не лежит. Поэтому мимо.

Как это тебе поможет уберечься от необходимости добавления в них виртуальных функций getName(), getXmlName(), writeSvgElement(SvgElement& parent),getWhateverLibraryElementType(), draw(XxxLibraryRenderTarget&), save(DataTarget&)?

Какие виртуальные функции? Ты перед тем как нести свою чушь - пишешь код на своём мусоре, аналогичный той чуши, которую впариваешь.

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

Нет, меня не интересуют твои фантазии. Каким образом миллион мусора, который ты мне выше впаривал превратилось в «просто функцию»?

Где перечисление всего мусора, а именно «getName(), getXmlName(), writeSvgElement(SvgElement& parent),getWhateverLibraryElementType(), draw(XxxLibraryRenderTarget&), save(DataTarget&)?» И прочей чуши.

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

Не, меня мало волнуют твои фантазии. Либо конкретика - либо слив.

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

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

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

И что? Rustc тоже не может работать без LLVM. Так какая разница между ними?

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

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

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

Ну давай, просвети меня, что такое llvm.

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

И уже потом ты можешь спросить о том что такое ллвм, а никак не вместо.

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

И? К чему эти нелепые оправдания? Что ты этим хочшеь сказать? Что раз что-то было прибито и потом «разприбито», то это значит что всё что прибито может быть «разприбито»? Нет. Это так не работает.

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

Я ответил на все хоть сколько-то вменяемые утверждения.

Нет, ты ответил только на те, на которые было удобно написать «не нужно».

Можно было бы со мной спорить, наверное

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

Ты-то писал, но это не соответствует действительности. Полнота не проверяется даже когда ты не пишешь ветку с auto&&. А когда пишешь - ещё хуже.

Соответствует. Ты неспособен разделить полноту проверки вариантов и типизацию символьных литералов.

Вообще, я тебе привёл код

Ну давай разберем по частям тобою написанное.

Да и на самом деле хреново он это делает.

[код]

Ты в std::variant<int, float, char> записываешь символьный литерал. Символьный литерал имеет тип int. visit корректно обрабатывает вариант, в который записан int. На этом можно заканчивать. Ты – бездарность.

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

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

Как показала практика, я знаю кресты лучше тебя.

Ты сел в лужу только что – и многократно раньше. Rust: преобразования указателя на трейт в конкретный тип (комментарий) Rust: преобразования указателя на трейт в конкретный тип (комментарий)

факт есть факт: кресты не могут контролировать типы в варианте.

Факт есть факт: ты – бездарность.

Какая разница, претендовали ли они?

Запиши тогда python и bash в список. Они тоже не претендовали, но это ведь не важно.

Ты опять пытаешься смухлевать.

Ты ссылаешься на Александреску (ссылки я, кстати, таки не увидел) и пишешь, что он «большой авторитет». Александреску хвалит golang за его генерацию исходников. Ты согласен с ним или нет?

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

Ты сел в лужу.

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

Цитату и ссылку на сообщение.

И ты опять соврал. Я всего лишь написал правдоподобный код извлечения данных из БД.

Ты написал дерьмо. И ты снова лжешь – у тебя в твоем же коде есть s_dbAccessor, контекст операции.

Вообще, забавно как ты писал resolve(id) до того как я поймал тебя, и вдруг резко переобулся и добавил какие-то методики получения правильного «контекста».

Ты лжешь. Изначально речь шла про print, а не про resolve. Затем ты заблеял про ресолв, требующий каких-то операций с БД – и я показал, как это реализовать в полиморфном виде, не потеряв расширяемости.

Какие твои слова я переврал? Ты пишешь «не надо писать дополнительные строки».

Я пишу Rust: преобразования указателя на трейт в конкретный тип (комментарий):

Я устал повторять, сколько раз я уже писал, что это не ради написания 1x(число match’ей в проекте) строчек, а ради возможности расширять множество типов, не изменяя при этом код обработчика.

Да. Расцвел после С++03, что вылилось в публикацию С++11.

Я не то что бы копенгаген, но в общем слышал мнение плюсовиков, что 2003 - это минорщина

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

ты утверждаешь, что решения проблемы «нужен тип-сумма» C++ не предоставлял.

Цитату и ссылку на сообщение.

Я же пишу обратное: C++ с самого начала, с 80х предлагал решение этой проблемы. Просто решение было плохое.

Ты идиот. То, что ты называешь «решением» (наследование) вообще не является типом-суммой. Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Итак, до boost::variant была ли, и если была, то какая технология, для представления ситуации «переменная может быть типа А или Б»?

Boost.Variant это просто занесение в библиотеку того, что часто использовалось. Создание Boost.Variant ничего не добавило в язык, это не является «технологией» – это просто библиотечное дополнение, реализуемое всегда существовавшими средствами. Для реализации variant достаточно массива байтов, placement new и шаблонов. Для visit – перегрузки. Это механизмы языка, существовавшие с его появления.

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

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

Не будет он никуда инкапсулирован. Ты просто добавишь абстрактный draw(XxxCanvas) в базовый класс и потом реализуешь его в потомках.

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

оказался бы несовместим

Блин, а для трейтов/match оказался совместим. Хватит вилять.

LLVM

@right_security исчерпывающе ответил на твой бред.

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

А, и да

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

Как без проверок компилятора, дурак? Указатели на функции типизированы

Указатели на функции типизированы

Поработай хоть раз с таким API.

Поработай хоть раз с таким API.

Ну да, такие как ты char* (func)(struct MyStruct, int); не осилят, конечно.

http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html

Один из лучших таких API. Ничто не мешает передать void* вместо char*, флаг вместо хэндла и так далее. Где проверки компилятора? Не говоря уже о возможности записать void* вместо адреса любой функции.

Я задал тебе вопрос «как часто используются енумы». А ты что ответил? «Как часто енумы присутствуют в публичном интерфейсе класса». Это ответ на другой вопрос

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

% /t/ripgrep (master)> rg enum | wc -l
68
% /t/ripgrep (master)> rg struct | wc -l
309
% /t/ripgrep (master)> rg 'match \w+ \{' | wc -l
40
% /t/ripgrep (master)> rg 'impl \\w+ for' | wc -l
54

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

Позорище.

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

Ты не часть ллвм, не часть С++.

В LLVM есть flang: https://github.com/llvm/llvm-project/tree/main/flang

Что изменится если теоретически rustc добавят в LLVM?

dlang же добавили в базовый набор gcc: https://github.com/gcc-mirror/gcc/tree/master/gcc/d

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

Ты в std::variant<int, float, char> записываешь символьный литерал. Символьный литерал имеет тип int. visit корректно обрабатывает вариант, в который записан int. На этом можно заканчивать. Ты – бездарность.

Правда? А давай проверим.

  std::variant<int, float, char> test = 'a';
  std::variant<int, float, char> test2 = 1;
  auto visitor = overloaded {
          [](int& value){std::cout << "(int)"<<value<<std::endl;},
          [](char value){std::cout << "(char)"<<value<<std::endl;},
          [](const float& value){std::cout << "(float)"<<value<<std::endl;}
      };
  std::visit(visitor, test);
  std::visit(visitor, test2);

Догадайся, что этот код выдаст.

А потом закоментируй ветку обработчиком char.

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

Ты лжешь. Изначально речь шла про print, а не про resolve. Затем ты заблеял про ресолв, требующий каких-то операций с БД – и я показал, как это реализовать в полиморфном виде, не потеряв расширяемости.

Нет, конечно. Ты писал функцию «ресолв», которая магически всё сама сделает. Я написал тот код, который реально будет и объяснил, почему это сломается. И после этого ты придумал, что какой-то чувак 10 лет назад, имея в ТЗ только работу с БД, вдруг волшебным образом прозрит года и догадается, что вот тут надо дополнительное место для расширения предусмотреть.

А что если не догадается?

Цитату и ссылку на сообщение.

У нищих слуг нет. Иди по цепочке, клоун.

Создание С++11 – труд многих ле

Не пытайся замаскировать свой просёр словестным мусором. Я задал тебе простой вопрос: что конкретно превратило «си с классами» 90х в C++.

Ты идиот. То, что ты называешь «решением» (наследование) вообще не является типом-суммой.

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

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

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

Ты, кстати, как-то слился с проверки на балабола.

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

match x {
   A(v) => foo(v),
   B(v) => bar(v)
}

Напиши 100% аналог на цепочке if.

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

Как мне ответить на этот вопрос? Выкачивать гитхаб и грепать?

Нет, конечно. Я же просил от тебя приблизительную интуитивную оценку.

реализаций трейтов больше (!), чем использований match’ей, а ведь impl Trait пишется единожды, тогда как match на каждое использование.

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

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

Догадайся, что этот код выдаст.

Принимается, тип int у символьных литералах это сишная особенность.

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

Нет, ведь это ты думаешь, что обработчик const int/const int& не должен обрабатывать char-альтернативу. Не говоря уже про тот бред, который ты написал в Rust: преобразования указателя на трейт в конкретный тип (комментарий) , где ты показал свое незнание не только правил перегрузки, но и своей же «родной» Rust’овой типизации, а в следующих же сообщениях еще и механизма выведения типов в Rust. Клоун – ты.

И после этого ты придумал, что какой-то чувак 10 лет назад, имея в ТЗ только работу с БД, вдруг волшебным образом прозрит года и догадается, что вот тут надо дополнительное место для расширения предусмотреть.

Ты идиот, приведенный пример вообще не имеет отношения к какому-то дополнительному месту.

А что если не догадается?

Меня не волнуют проблемы идиотов.

Нет, конечно. Ты писал функцию «ресолв», которая магически всё сама сделает.

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

auto& get_ctx(SuperCtx& ctx, Id id) { return ctx.s_dbAccessor; }

auto resolve(DbAccessor& accessor, Id id) { return accessor.get(id).name; }

Написание остальных оставляю тебе в качестве упражнения.

У нищих слуг нет. Иди по цепочке, клоун.

Пойман на вранье и слит.

я правильно понимаю, что C с классами было до 2011? А когда он расцвёл тогда?

Да. Расцвел после С++03, что вылилось в публикацию С++11.

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

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

Я задал тебе простой вопрос: что конкретно превратило «си с классами» 90х в C++.

Ты заврался. Речь шла о периоде, и только когда ты понял, что ты слит, ты решил потребовать магическую фичу. Но я отвечу: constexpr, auto, вариадики и замыкания.

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

Ты идиот. Приведу лишь несколько ссылок, в которых я рассказываю о реализации типа-суммы в С++ на примере Boost.Variant.

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

Rust: преобразования указателя на трейт в конкретный тип (комментарий)

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

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

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

Не сахарок – плохо, а полная аналогичность. match ничем не отличается от цепочки if по расширяемости.

if let A(v) = u {
    foo(v);
}
if let B(v) = u {
    bar(v);
}

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

Достаточно было вспомнить про Result и Option, чтоб понять, что енумы в расте используются везде

Боже, ты реально настолько кретин?

Никто не реализует полиморфизм при помощи Result/Option, никто в них не хранит одинаковые семантически значения. Result/Option это позор раста, порожденный невозможностью родить разные пути обработки успеха и ошибки. Никто не делает match по ним, чтобы в одном случае сделать foo, в другом bar – максимум, чтобы извлечь успешное значение и вернуть ошибочное. А самое частое использование – это вызов unwrap().

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

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

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

В LLVM есть flang

flang

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

Что изменится если теоретически rustc добавят в LLVM?

Ты либо не понял контекст, либо даже не пытался.

  • Раст-методичка сообщает, что раст это какое-то своё, а ллвм бек(что чушь, конечно же. Никакого раста в том виде в котором они сообщают - не существует). Добавление его туда - рушит методичку.

  • Это будет номинальная часть. Точно так же как фортран. Это не тоже самое - это подмена понятий. Это даже не бастард, а что-то совсем непонятное.

Давай ещё раз. Есть наследие. llvm - реализован как часть компилятора C++, как его виртуальная машина. Это часть мира цпп реализациющая цпп для цпп. То, что она продавалась как возможность расширить это, а далее эпл и прочие - дали бабки. Это мало на что влияет.

Я уже приводил в пример жаву. jvm создана для жавы и жава для жвм. То, что жвм как платформа дала модель исполнения/таргет для многих других «языков» - это ничего не меняет. И даже если эти «языки» засунут куда-то - это ничего не изменит. Так же и здесь.

dlang же добавили в базовый набор gcc: https://github.com/gcc-mirror/gcc/tree/master/gcc/d

И? Во-первых дланг не настолько огрызок как раст. Во-вторых из этого ничего не следует. Это «просто засунули в репу, чтобы он не ломался». Это обычная практика.

Никакого отношения d к гцц не имел, как и гцц к d.

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

Напоминаю: ты утверждал, что матч - это «сахарок» над цепочкой ифов.

Как же врёт. Да хотя уже лень.

И из этого делал вывод, что матч - это плохо.

Нет, матч мусором потому, что днище не умеющие в типы.

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

Потому что в типы не умеет. Но ты слился, когда я тебе чётко продемонстрировал что такое настоящие сумтипы на примере ts, а что такое твой мусор.

А вот первая часть - это утверждение о факте и его можно проверить. Итак, вот тебе «сахарок» матч

Итак - это мусор.

Напиши 100% аналог на цепочке if.

Смотри. if(x.tag == a) foo(x as a) - дальше сам.

С ифами проблема только в том, что ифы куда мощнее. Поэтому твоя немощная скриптуха в них не смогла. Т.е. чтобы мочь в ифы нужно уметь в cfa. Что умеет тот же ts, а вот ты нет.

Поэтому что мы имеем.

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

  • Огрызок не может в cfa и как следствие не может использовать ифы. Поэтому пришлось тащить switch из сишки и обмазывать его break.

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

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

Никто не реализует полиморфизм при помощи Result/Option, никто в них не хранит одинаковые семантически значения. Result/Option это позор раста, порожденный невозможностью родить разные пути обработки успеха и ошибки. Никто не делает match по ним, чтобы в одном случае сделать foo, в другом bar – максимум, чтобы извлечь успешное значение и вернуть ошибочное. А самое частое использование – это вызов unwrap().

Option это вообще не про ошибки, тебя уже куда-то не туда несет.

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

Принимается, тип int у символьных литералах это сишная особенность.

Не «принимается», а «признаю, что сишный визит - говно и никакого контроля за полнотой там нет».

Нет, ведь это ты думаешь, что обработчик const int/const int& не должен обрабатывать char-альтернативу.

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

Нет уж. Коль скоро этот тупой std::variant обещает индексировать варианты по их типам, то путать их он не должен. Более того std::variant<int, int> не должно компиляться. Ну чтоб если кто сдуру запихает в варианты разные typedef-алиасы для одного типа, компилятор его бы предупредил.

Ты идиот, приведенный пример вообще не имеет отношения к какому-то дополнительному месту.

Нет, это ты идиот. Тупой как пробка. Любому вменяемому человеку понятно, что речь о «месте» не в смысле «строчки в файле», а месте в архитектуре, в твоём случае вот этом дурацком контексте, который заводится вопреки ТЗ «на всякий случай».

Меня не волнуют проблемы идиотов.

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

Пойман на вранье и слит.

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

Ты идиот. Приведу лишь несколько ссылок, в которых я рассказываю о реализации типа-суммы в С++ на примере Boost.Variant.

Дебилоид. Я писал о плюсах до std::variant. Причём явно это подчёркивал. Вот прямо так и писал, мол, если нужна тебе тип-сумма, то на старых плюсах ты делал её наследованием. Уж даже не знаю, то ли у тебя память золотой рыбки, то ли ты просто включаешь дурака чтоб спрятать твой позор.

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

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

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

Что и требовалось доказать, балабол слит.

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

Видишь, всё что ты в этой теме писал, либо бессмысленный бред, либо ложь.

Никто не реализует полиморфизм при помощи Result/Option,

Хмм. Полиморфизм? А теперь привожу твои цитаты:

Первая:

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

Где тут хоть одно слово про «полиморфизм»? Нет его. Сказанное вполне понятно, енумы неудобны, не расширяются, поэтому, все пользуются трейтами.

Вторая.

Даю «приблизительную» оценку: ни одна библиотека из most downloaded на первой странице crates.io не использует в публичном интерфейсе enum ни для чего, кроме передачи флагов.

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

Опять ни слова о полиморфизме.

Вообще, что за говно у тебя в башке.

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

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

enum Smth<T> {
    None,
    One(T),
    Many(Vec<T>)
}

с имплементацией функций для добавления/удаления.

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

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