3 ms·
Things like this are why I don't get when anyone calls Rust "more difficult than C++". I don't think I've ever encountered a more complex and cumbersome languag
by andrepd 10mo ago
Things like this are why I don't get when anyone calls Rust "more difficult than C++". I don't think I've ever encountered a more complex and cumbersome language than C++.
- nurettin 10mo agoRust types can be very verbose, RefCell<Optional<Rc<Vec<Node>>>> And lifetime specifiers can be jarring. You have to think about how the function will be used at the declaration site. For example usually a function which takes two string views require different lifetimes, but maybe at call site you would only need one. It is just more verbose. C++ has a host of complexities that come with header/source splits, janky stdlib improvements like lock_guard vs scoped_lock, quirky old syntax like virtual = 0, a lack of build systems and package managers.
- andrepd 10mo ago> Rust types can be very verbose, RefCell<Optional<Rc<Vec<Node>>>> Anything in any language can be very verbose and confusing if you one-line it or obfuscate it or otherwise write it in a deliberately confusing manner. That's not a meaningful point imo. What you have to do is compare what idiomatic code looks like between the two languages. C++ has dozens of pages of dense standardese to specify how to initialise an object, full with such text as > Only (possibly cv-qualified) non-POD class types (or arrays thereof) with automatic storage duration were considered to be default-initialized when no initializer is used. Each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible, if T is a union with at least one non-static data member, exactly one variant member has a default member initializer, if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and each potentially constructed base class of T is const-default-constructible. For me, it's all about inherent complexity vs incidental complexity. The having to pay attention to lifetimes is just Rust making explicit the inherent complexity of managing values and pointers thereof while making sure there isn't concurrent mutation, values moving while pointers to them exist, and no data races. This is just tough in itself. The aforementioned C++ example is just the language being byzantine and giving you 10,000 footguns when you just want to initialise a class.
- 1718627440 10mo ago> > Only (possibly cv-qualified) non-POD class types (or arrays thereof) with automatic storage duration were considered to be default-initialized when no initializer is used. Each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible, if T is a union with at least one non-static data member, exactly one variant member has a default member initializer, if T is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and each potentially constructed base class of T is const-default-constructible. That's just a list of very simple rules for each kind of type. As a C++-phob person, C++ has a lot of footguns, but this isn't one of them.
- andrepd 10mo agoThis was a random snippet of complicated rules to illustrate what I mean. C++ has significant footguns and complexity when it comes to initialising an object. Even sticking by "Effective Modern C++" rules is a significant cognitive burden on something that should be simple and straightforward. Rust has (mostly) no such footguns; its complexity follows from the essential complexity of the problems at hand.
- 1718627440 10mo agoI see. But including a snippet that actually supports your claim would have been more useful.
- jpc0 10mo agoRust prevents the footgun, but also prevents shooting in the direction where your foot would be even if it isn't there. There are absolutely places where that is required and in Rust those situations become voodoo to write. C++ be default has more complexity but has the same complexity regardless of domain. Rust by default has much less complexity, but in obscure situations outside of the beaten path the complexity dramatically ramps up far above C++. This is not an argument for or against either language, it's a compromise on language design, you can choose to dislike the compromise but that doesn't mean it was the wrong one, it just means you don't like it. A relatively simple but complex example, I want variable X to be loaded into a registerer in thos function and only written to memory at the end of the function. That is complex in C/C++ but you can look at decompilation and attempt to coerce the compiler into that. In rust everything is so abstracted I wouldn't know where to begin looking to coerce the compiler into generating that machine code and might just decide to implement it in ASM, which defeats the point of using a high level language. Granted you might go the FFMPEG route ans just choose to do that regardless but rust makes it much harder. You don't always need that level of control but when you do it seems absurdly complex.