mcguire 7 days ago

"When you implement an algorithm using C++, you can write it down without one second of pause, but you can’t do that in Rust. As the compiler will stop you from borrow checking or something unsafe again and again, you are being distracted constantly by focusing on the language itself instead of the problem you are solving."

Yeah...

On my last C++ project, one very productive co-worker kept disabling -Wall, etc., because "nobody has got time for that." I periodically fired up valgrind and chased down assorted memory issues.

So, yeah...

  • oscargrouch 7 days ago

    As someone who was following Rust since its inception, i got pretty fond of the first Graydon Hoare's vision to it. It looked a lot like Swift is now, but with a different syntax and more FP dialects.

    As a im a (mostly) C++ programmer, despite the fact that i liked the language, i feel that the balance between what the language was giving me, and the productivity, was not worth it when compared to C++.

    I feel much more productive in C++, the language is still faster, with a low memory footprint in the majority of cases, and with modern C++, smart pointers, move, a correct understanding of the ownership model .. the bad sides of it, the ones Rust did a better job shelving us from, from my point of view are not worth paying for the lack of productivity i felt in Rust as compared to C++.

    I know this is an unpopular opinion here in HN, but I decided to take a different approach .. instead of "one language to rule them all" i tend to use C++ for what's good at, and Swift for more application centered goals , because its nicer than C++ and Rust (in my opinion), release you from the burden of managing memory all around while being very fast at the same time.

    Swift for me is "the better Java" we were looking for, Rust does not seem appealing in this arena (and the same goes for C++ here), while you pay for what you use in Rust in terms of productivity, even compared to C++.

    The other thing that makes C++ a better option in my opinion, is the ammount of libraries and codebase you have access to, not only in C++, but in C. Very important codebases are either C or C++, even the newer ones like Tensorflow or V8, Chrome, LLVM, etc ...

    I understand the importance of what Rust provides, I like its goal, but your comment sounded like the OP was either stupid or lazy / incompetent by using your anedoctical evidence. (While in the same anedoctical example you are the hidden figure who are sensitive about security while still using C++, as the 'lazy guy', enabling -Wall, using Valgrind, etc)

    When I entered in the comments section here, I was just expecting the sort of comments in the spirit of "how could you even do that?"

    PS: Im not the kind of guy who tends to disable -Wall -Werror to have more productivity and i would not favor C ++ in exchange for Rust, if i feel the balance were better among what i pay in terms of productivity were fair in exchange for more safety as compared to what I have now with C++.

    • skohan 7 days ago

      I have taken a similar approach, although I tend to rely more on C than C++. I think Swift has somewhat similar advantages to Rust in terms of safety, but accomplishes it while being a largely permissive language rather than by putting the developer in a safety "jail" where it's almost impossible to make a mistake.

      I know this comes at the cost of performance when compared to Rust when compared to memory management, but the value proposition in terms of productivity is huge. And recently I've done some experimentation with optimizing Swift for performance, and Swift can actually do surprisingly well there too if you stick to certain patters.

      I think Rust has its place, and for things like kernel development, firmware, or software for a mars rover where you absolutely want the strongest compile-time checking of your code with respect to safety with a minimal cost to performance, it is a natural choice. I'm not convinced it's categorically better for all use-cases.

    • pjmlp 7 days ago

      I have a similar approach, just different languages.

      Java and .NET platforms, with C++ only when really required.

      So for me, and the people I work with, whatever alternative comes to replace C++, needs to fit into the same workflow and IDE mixed language development tooling that others are already comfortable using.

      And I do advocate both ways, managed languages getting features that reduce the need to reach for C++, safer C++ replacements that might eventually succeed long term (C++ took 25 years to reach where it is now), and exactly because C++, or even C, isn't going away tomorrow, ways to improve existing code quality.

      Because the ultimate goal is to improve our IT stack, and not celebrate yet another Morris Worm birthday.

    • Const-me 7 days ago

      Same here, only C# instead of Swift. Native interop through C API adds some friction, but despite that, I also find it easier to use two distinct languages.

      C++ excels at interop. As you mentioned there’re many libraries that only support of C or C++ but for me their set is different, most often I need to consume native OS APIs and GPU APIs. Also, C++ is good at number crunching, when performance matters, e.g. because first party SIMD intrinsics support.

      For everything else I use C#.

  • RcouF1uZ4gsC 7 days ago

    The issue is that code that the borrow checker flags is not code that is unsafe, but code that the borrow checker cannot prove safe. There is a difference.

    Until, you natively start thinking and writing code with idioms that the borrow checker is tuned for, there will be friction.

  • pjmlp 7 days ago

    I complain about C's safety all the time, but it isn't as if Dennis and others weren't aware of its shortcomings in that regard.

    > Although the first edition of K&R described most of the rules that brought C's type structure to its present form, many programs written in the older, more relaxed style persisted, and so did compilers that tolerated it. To encourage people to pay more attention to the official language rules, to detect legal but suspicious constructions, and to help find interface mismatches undetectable with simple mechanisms for separate compilation, Steve Johnson adapted his pcc compiler to produce lint [Johnson 79b], which scanned a set of files and remarked on dubious constructions.

    -- https://www.bell-labs.com/usr/dmr/www/chist.html

    C static analysis tools, being ignored since 1979, because "nobody has got time for that."

    • candiodari 6 days ago

      Perhaps it's more of a case of there being 2 issues:

        domain specific knowledge (e.g. 3d math, usability)
      
        correct program writing
      
      And you do them in sequence rather than in parallel (and then of course your boss declares phase 2 doesn't get any of your time).

      Lots of software engineers really emphasize the second part. But this is like insisting on correct shoelace tying in a shoe factory ... it's nice, but without making a shoe in the first place there is no shoe and no need for shoelaces. And when it comes to choosing between no shoe or badly tied shoelaces ... the choice is clear.

      This is why the neverending complaint of software engineers that no-one cares about correctness. Entirely true. You can do without correctness (if there's anything Microsoft taught us), but you cannot do without domain knowledge.

      And it's a bit self-serving: guess which one is most often missing in software engineers ?

      • pjmlp 6 days ago

        Actually, coming from a country where Informatics Engineering is an actual professional title, I think adoption of such practices around the world, instead of allowing somone to name themselves engineer after a six weeks bootcamp would already help a lot regarding the quality of work output.

        Any good certified engineers degree takes care that students have a concern for acquiring domain specific knowledge and adopt best practices.

        Another thing would be liability, people just need to sue more often IT companies, so that security is actually taken up seriously.

        Too many CVEs in the last couple of months? The servers get grounded, product recalls are required from state.

        • candiodari 6 days ago

          I'm not saying correct software has no advantages. Quite the opposite: I state and acknowledge the advantages. But it's an amplifier: without something to amplify (which boils down to domain knowledge) it's like owning a billion dollars buried on the moon : interesting, even cool but fundamentally useless.

          Software quality has advantages for companies that are very strongly in the "milking their 100% understood market where they have an overwhelming competitive advantage" phase. Large companies. And is between neutral and a disadvantage for nearly everyone else.

          That doesn't mean you can't take pride in good software. Or that it isn't an accomplishment. But you want to write quality software for money ? Get a job at Google/Facebook. Better yet, get one at Bank of America, Exxon Mobil or Boeing. Or research it at university.

  • lixtra 7 days ago

    Depending on the situation a write unsafe fast fix later maybe the more economic approach. Especially if the code is more exploratory, changes a lot and large parts will be finally discarded.

    • kbenson 7 days ago

      It seems to me that letting yourself work under the assumption something may be easy to fix later when you add the safety constraints back is just asking for major pains when it isn't easy. A wrong assumption at that level can render your entire algorithm unworkable if your plan was to make it safe in the end, since some patters just don't lend themselves to easy expression in rust. Then you're stuck with the choice, leave it unsafe and worry about it from them on, or rewrite it safely using an altered or entirely different algorithm. That doesn't seem like a gamble that's worth it to me.

      Even for exploratory code. Unless it's such a performance critical portion of the project that I'm willing to write it in a different language for speed, why bait myself so?

      If one of my goals for a project is to write somewhat functionally, I wouldn't start off with an exploratory approach using procedural techniques. I think we can all see what I'd probably end up with in the end, and it might work, but it probably wouldn't have some of the attributes I was hoping for.

    • bluesroo 7 days ago

      I've found that more often, it should be reworded as "unsafe fast, painfully maintain without the resources to ever fix later".

      • bluejekyll 7 days ago

        The number of TODO's that litter code in general, or issues file to "cleanup" are generally significant. You're making a great point that accruing technical debt at the cost of safety, is quite possibly technical debt, like all other, that will never be paid down over the life of the software.

        I completely agree.

    • mcguire 7 days ago

      What is this "fix later" you speak of?

    • pjmlp 6 days ago

      Usually the "later" part never comes, specially in consulting, where there is only one shot to implement each module.

  • anfilt 6 days ago

    Unabashedly, I think leaving in it pure C would have been better. Well, if that was of their main reasons. Although, it sounds like they wanted more "infrastructure".

    There is a lot of C infrastructure, almost anything can work with C too...

  • distances 7 days ago

    One-sided changes to build configuration sounds like an issue with code reviews though. It shouldn't be possible to merge something like that without others agreeing.

  • gdy 7 days ago

    >very productive co-worker

    He-he

__s 7 days ago

/r/rust thread: https://www.reddit.com/r/rust/comments/b0erei/why_i_rewrote_...

You'll notice the top rated comment, & majority of comments, agrees with their decision to switch to C++. Yet we'll persist that Rust is an elitist community..

  • ThrowawayR2 7 days ago

    > You'll notice the top rated comment, & majority of comments, agrees with their decision to switch to C++. Yet we'll persist that Rust is an elitist community.

    Having read those comments, many of them can be best characterized as politely dismissive, e.g. from the top rated comment "If the author is more comfortable writing this code in C++ it makes sense to use it, but I feel like there is a long way to go to make this code "safe" regardless of language. " , elsewhere "I get that this project probably values developer efficiency over safety or correctness, and probably makes sense in this use case.", etc. Still smells kind of elitist to me.

    • bluejekyll 7 days ago

      How would you describe the trade-off between safety and the developer productivity listed as the reason in the article?

      The comment seems to just be saying that it’s reasonable for someone to make this trade off when they are more knowledgeable and familiar with one language rather than another.

      I think your reading quite a bit into that comment to take it as elitist.

      • ThrowawayR2 7 days ago

        > I think your reading quite a bit into that comment to take it as elitist.

        "... there is a long way to go to make this code "safe" regardless of language." and "...values developer efficiency over ... correctness ..." are somewhat uncomplimentary additions to their main points, no matter how you look at it.

    • samirm 7 days ago

      perhaps you're projecting and just smell what you want to smell?

    • mlthoughts2018 7 days ago

      Exactly. A bunch of link spam to reddit or quora doesn’t add up to evidence that the Rust community is reasonable or fair in its evaluation of alternative language choices or trade-offs against other languages.

      • bluejekyll 7 days ago

        Are you suggesting that Rust is not as safe as it claims? Or that C++ is as safe as Rust?

        There’s a lot of research to disagree with either of those positions.

        • mlthoughts2018 7 days ago

          No, not at all. Rust is a very good tool and is useful in many situations. I believe it offers better automatic memory safety.

          However, there are many cases when Rust is not a good tool for the job, and when specifically having greater manual control of memory or thread safety is a better choice. Additionally, in many applications you can build almost everything in a fully dynamically typed language, often interpreted as well, and only choose small sections of code to target for a specialized compiled implementation.

          In those cases, avoiding the overhead of a compiler and using rapid unit tests with high coverage as an alternative to compiler checks may often be a far safer and superior way to develop code, leading to adequately safe and performant code that is easier to maintain, faster to create, easier to explain, etc.

          All I’m saying is that Rust is another tool in the toolbox. It’s not intrinsically or unilaterally better than any other tool, and other tools can inhabit parts of trade-off space that make them better choices than Rust, even for applications that need memory safety or high performance.

          In my experience though, most interactions with Rust community leave me feeling like a vocal and significant fraction are trying to seriously claim that Rust is categorically and unilaterally a better choice across almost all possible use cases, let alone across a wide range of practical use cases.

          • Retra 7 days ago

            A vocal and significant fraction of any community of reasonable size is going to be populated by blowhards.

            • skohan 7 days ago

              I think it's still fair to say that the Rust community either attracts, or doesn't discourage this type of advocate in a way that other communities don't. Personally I've encountered this type of behavior in a few situations:

              1. When Swift for TensorFlow was announced, the team released a document explaining that they had narrowed the language choice to 4 languages including Rust, and eliminated Rust based on the sharp learning curve. Once commenter unrelated to the project logged an issue on the GitHub page and went on for many multi-paragraph quotes about how Rust should have been the choice.

              2. In a thread about gfx-portability, which similar to MoltenVK brings the Vulkan API to Apple platfortms, when the original poster was questioned about the comparative completeness and and performance of these two implementations, they were completely unable to offer details (like come on, you can't even say what percentage of the tests are passing based on the Vulkan portability standards? You never benchmarked against the most similar product on the market?) and deflected to making totally unfounded claims about how MoltenVK is unsafe and even dangerous to use.

              3. In a thread about Rust syntax, I made a comment about how I personally lamented some of the choices made in the language, like going with snake_case as a convention, and naming dynamic arrays Vector. I was promptly downvoted and received several fervent responses explaining why my personal taste was objectively wrong.

              I think Rust is an interesting and promising language, but there does seem to be a somewhat tribal tendency in the community which is a turn-off for me.

  • johnisgood 7 days ago

    I am not going to draw the conclusion that Rust does not have an elitist community from <5 replies, just how you would not want me to draw the conclusion to the opposite based on a handful of people, right?

Barrin92 7 days ago

The first few comments here seem to argue against the article, as do comments below the post but I am very much with the author.

I strongly disagree with the Rust mentality, and the general mentality of statically typed languages with extremely prohibitive compile time checks, that seem to become more common.

Underlying that model seems to be a concept of software like a sort of renaissance master's marble statue, error free and perfect at time of production.

The downside that the author points out seem to be often neglected. Constant interruption and battling with the type system during development, when mental overhead is a problem. Coupling components by types propagating through software, increasing time and effort to make changes to your software, increasing the overhead for others to contribute.

In my opinion the dominant metric to evaluate the usefulness of a language's type system should be its overall effect on cost, time spent, productivity, ease of development and capacity to change. Everything else is very subjective or just an aesthetic concern.

  • loup-vaillant 7 days ago

    > The downside that the author points out seem to be often neglected. Constant interruption and battling with the type system during development, when mental overhead is a problem.

    Dunno about Rust specifically, but I have written a little Haskell, and a significant amount of OCaml. I found that the type system reduces my cognitive overhead, compared to looser languages like Python or Lua. The compiler is disciplined, so I don't have to be.

    In practice, with few exceptions, when the type system is refusing to compile something I just screwed up, and I'd better fix my mistake right away. I'd wager that with few exceptions, when Rust is refusing to compile something, you are making a mistake that in C++ would have bitten you down the line.

    What you call "fighting the type system", I call "fixing bugs".

    • blattimwind 7 days ago

      > you are making a mistake that in C++ would have bitten you down the line.

      Taking some C++ code from an explorative phase that "usually works kinda ok" to something seaworthy requires, in my experience, a huge amount of work (which usually neglects a few issues that will bite you later regardless). I'm not so sure the (probably) faster exploration in C++ compensates for this compared to more "strict" languages like Rust.

      Of course, if the functional requirement is only "usually works kinda ok", then you don't really need something like Rust.

      • loup-vaillant 7 days ago

        I found that strict compile time checks speed up my exploratory phase. That's because the type system provide an even tighter feedback loop than a REPL, and effectively cuts down the search space.

        Other people seem to have experienced the opposite, though. I have no idea why.

        • milesvp 7 days ago

          It might depend on the problem space. I dunno. But I suspect it depends a lot on the type system and type inferencer of the language you use.

          It is easier to write a true statement than it is to prove the statement is true, and getting a compiler to agree to compile quite literally requires proving a statement is true. This can be more or less difficult based on the language. I’ve read a lot of war stories, particularly in java, about having to do a lot of crazy convoluted code to get the compiler to realize that yes actually these 2 objects are interchangeable from an API/Interface point of view. I don’t know, but I suspect this may be a lot less common in languanges using hindley-milner type system, since that lends itself to very good type inferencing.

        • slavik81 7 days ago

          To me, the question is whether the time spent dealing with compiler errors is due to fixing real problems that the compiler is pointing out, or whether that work is mostly reworking a correct program to satisfy the compiler when it cannot yet see that the program is correct.

          • firethief 7 days ago

            I don't think humans have anything major in their toolkit for reasoning about memory management / aliasing that the Rust compiler doesn't; when non-trivial code cannot be expressed in terms of single-ownership at any given point, code loses correctness-at-a-glance. There are cases where a safe Rust abstraction is built on unsafe code, including most of Rust's collections; the API contract of every stdlib collection is: the collection owns its elements. Interestingly, such a contract can generally be implemented safely, but would have different performance characteristics; e.g. doubly-linked List could use indexes into a Vec. This example mirrors a pattern seen in languages that discourage mutation: break the rules internally for performance optimizations, but maintain the invariants at API boundaries to contain the cognitive overhead. Even when Rust's rules need to be broken, they are useful to contain complexity.

    • asdkhadsj 7 days ago

      Couldn't agree more. It was why my transition from Javascript (Node) to Go was very freeing - I had been so used to being constantly paranoid about my data types from Python and Javascript that even the most modest types of Go made a huge relief.

      Likewise, with Rust it is a relief after Go. In Go interfaces are a massive part of the language and they can only be pointers, which means much of your programming experience holds mental overhead needed to frequently answer "is this variable safe? Can I access it, or might it be nil?".

      There's definitely overhead in learning how to use the borrow checker, but I feel that's the same as any basic language features in any language. Once learned, I largely don't think of them, and I don't fear using variables or what is concurrently safe anymore.

      • mntmoss 7 days ago

        I can definitely see where the author was coming from in terms of new code. I've been of the opinion that it's probably better to greenfield new systems alongside a GC'd runtime(which makes Go a pretty good fit, but also D, Nim, etc. - and for the very experimental stages where the type layout is minimally understood - Python, Lua, JS, etc.), and to take on external dependencies to get a result working - and then rewrite parts with manual memory and custom libraries where the spec needs tightening.

        The main downside to this is that you're rewriting stuff, but the goal of the rewrite should be to express what is essentially the same functionality in more detail.

        Where I think the author might have erred is in switching between three different manual memory languages in the hopes of faster development. The algorithms needed for a 3D tool have a pretty high base complexity, making it hard to bootstrap the codebase - and I suspect that C++ will ultimately frustrate him just as much as Rust and C did before.

    • olau 7 days ago

      Ah, but in this case you have already done the spec, otherwise the type system couldn't have checked it.

      With a more loose way of going about things, you don't have to write the spec. Spec'ing is hard, sometimes harder than actually solving the problem.

      I feel like someone is going to point out that spec'ing is a lifesaver in a certain situation, and I would agree. But perhaps not all situations.

    • renox 6 days ago

      That is an oversimplification, very often you know something that cannot be expressed in the types, so escape hatch (cast/unsafe) are useful. That said, if you can wrap around these 'hack' in a 'sane' API, then it's OK if you canno/didn't the result is quite ugly..

    • mlthoughts2018 7 days ago

      I worked professionally in Haskell for a long time and I cannot disagree with you more. This is always the promise of strict functional languages but in a business setting where the very nature of what you build has to be arbitrarily mutable at the whim of competing interests between stakeholders, engineers, customers, etc., it just doesn’t work.

      You end up with the same spaghetti code messes, unexpected runtime errors, indecipherable crashes, etc. no matter what degree of strict verification tooling you use. The introduction of lazy evaluation, difficult to debug tail recursion implications on memory consumption, elevating IO into the type system, burying details deep in type class patterns, relying on dozens of special case compiler directives to enhance Haskell... it becomes the same shit code mess as any other paradigm.

      • tome 7 days ago

        Interesting. I would be interested to know more details about what you worked on and with whom. This hasn't been my experience in any of the four jobs I've used Haskell at.

        I don't deny that Haskell leads to spaghetti code messes, unexpected runtime errors, and indecipherable crashes, but the Java that I've previously worked with and the Python I currently work with suffer from those to a degree greater by an order of magnitude.

        • mlthoughts2018 7 days ago

          It was first for a bank, later for a data analytics start-up, and then also for an education technology company. I had many skilled functional programmers on my team too, including a few people who had done work on GHC itself.

          I’ve also see code messes in many languages. It’s a business culture problem, has nothing to do with the language or paradigm.

          I’ll greatly dispute with about Python though. It has been a language that facilitates notably cleaner and more extensible implementations in my experience. Seen messes in Python too, but absolutely no way it’s “an order of magnitude” worse. That’s simply ridiculous. The only way that’s happening is if the programmers are exceptionally bad to the extent that it would not matter which language they used.

          • tome 7 days ago

            Very interesting. I suspect we may even have worked for the same bank! I'd love to discover how we came to such opposing conclusions.

            To give you a Python example, it encourages stuff like:

                def send_email(recipients, contents):
                    if type(recipients) == str:
                        send_one_email(recipients, contents)
                    else:
                        for recipient in recipients:
                            send_one_email(recipient, contents)
            
            That is a flavour of convenience that people commonly implement in Python. People like it because it allows both

                send_email("tome", contents)
            
            and

                send_email(["tome", "mlthoughts2018"], contents)
            
            and saves them from typing two square brackets. The problem is when you call

                send_email(u"tome", contents)
            
            It tries to email "t", "o", "m", and "e". This kind of stuff is endemic in Python. Yes, this did happen in practice in a company I worked for (a company that was responsible for trading hundreds of millions of dollars of securities every day). Call the programmers exceptionally bad if you like, but they were among the brightest minds graduating in my country. It was Python that allowed them to be sloppy.
            • mlthoughts2018 7 days ago

              I disagree very much. The Pythonic way would be to do something like map(send_email, list_of_addresses), and have send_email raise an exception if not passed precisely a single string, and presumable raise exceptions when you validate that the email address is of an acceptable format, etc.

              It would not be Pythonic to make the function superficially handle different arities of argument through explicit handling on the list type with isinstance, precisely because you’d need to handle different meanings of different types that implement the Iterator Protocol. That’s not something Python generally encourages, it’s just a mistaken implementation. And particularly not making careless assumptions when basing branches on isinstance behavior (for example, you could always encounter custom classes that have overridden __instancecheck__ or __subclasshook__ special methods.

              • tome 7 days ago

                It's certainly a poor use of Python's flexibility, but I've seen that kind of thing written at two completely different companies by completely different, yet smart, people so I suspect it's prevalent. Haskell does a much better job of nudging smart people to write good code. Gabriel Gonzalez explained it better than I could: http://www.haskellforall.com/2016/04/worst-practices-should-...

            • olau 7 days ago

              This isn't really spaghetti code, though, it's a syntactic sugar optimization gone wrong due to the Python 2 str/unicode split.

              It's in the same league as people overloading operators in C++ to do silly things.

              While some people like to harp on that, I don't think those instances are prevalent enough to actually cause that many bugs. YMMV.

      • loup-vaillant 7 days ago

        > in a business setting where the very nature of what you build has to be arbitrarily mutable—

        I just don't use Haskell there. I personally use OCaml for my data in, data out problems (compilers, generators…), but for inherently interactive and mutable stuff I just do imperative programming. Of course the type system (and the performance characteristics of the runtime!) must be suited to the problem domain.

        > burying details deep in type class patterns, relying on dozens of special case compiler directives to enhance Haskell...

        Looks like someone went overboard. I think you (your team?) should have been more conservative with the compiler directives, and less abstraction loving with the type classes.

        • mlthoughts2018 7 days ago

          > “Looks like someone went overboard.”

          All these things are basically bare minimum table stakes to do anything in the language at all, particularly enabling dozens of compiler directives for language feature extensions. That is Haskell 101 practically, which is actually one of the hugest problems with the language.

          Saying this is “overboard” in Haskell is out of touch with the practical realities of using the language.

  • geezerjay 7 days ago

    > The downside that the author points out seem to be often neglected. Constant interruption and battling with the type system during development, when mental overhead is a problem.

    This assertion is just wrong. The author makes it quite clear that he doesn't know the language and is still taking his first steps ( "I am still a Rust learner, not a veteran" ), he implies that has problems with correct memory management and best practices while using other languages (core dumps heart attacks), and claims that one of the most important aspects of Rust is that "it's memory safe".

    Of course, memory safety is achieved through compiler checks.

    However, the author is still someone who does not know how to use a programming language and is still bound to not only the mental model of another programming language but also bad practices that lead to problems. If someone tries to write broken C or C++ using Rust and Rust's compiler starts to throw error messages pointing out the errors the programmer is making by trying to write broken C or C++ in Rust then obviously Rust is not the problem. It is im fact the solution, and a solution that's being ignored.

    Heck, the author praises Rust and it's memory safety, but then proceeds to criticise Rust's compiler because, as he puts it, the compiler will stop you from doing unsafe stuff again and again. Isn't that the whole point? Or is anyone expecting that your memory corruption problems will magically cease because you write your same old memory allocation and access bugs in Rust instead of C or C++?

    • coldtea 7 days ago

      >However, the author is still someone who does not know how to use a programming language and is still bound to not only the mental model of another programming language but also bad practices that lead to problems.

      Well, that's the same attitude ("the language is fine, you just don't know how to use it, that's why you have bugs") that led us to 30+ years of shitty unsafe C code.

      Now it's applied to the other side (Rust is fine, you're just not good enough in it yet to use it properly, that's why you're discouraged).

      Well, sometimes the language is not fine, and its ergonomics can be all wrong.

      In C it was the type looseness, bad standard library, and presence of many foot guns.

      In Rust it's the overt explicitness of the borrow checker, and the friction it adds to one's programming.

      I don't care if the author is a Rust expert or total newb. Someone who can write a 3D modeler in C++ is someone who should be able to use any new Algol-derived language with ease in short time, regardless if they hasn't seen a line of code in that language before.

      If they can't, something's wrong with your language's ergonomics.

      • geezerjay 7 days ago

        > Well, that's the same attitude ("the language is fine, you just don't know how to use it, that's why you have bugs") that led us to 30+ years of shitty unsafe C code.

        You've picked a very poor example to repeat that tired old addage. You're using an example of someone who admits struggling with memory management issues who has just started learning a programming language which he doesn't master, and after he grew tired of having the compiler warn him that he was writing broken code he decided to keep writing broken code but this time in a language which doesn't warn him about how broke his code is.

        How exactly is this case anything other than someone not knowing how to use a programming language insisting on writing broken code?

        I mean, the rationale of switching to another language was quitr clearly how the programmer grew tired of the compiler warning him he was making a series of mistakes, and he prefered keeping making the same mistakes without being bothered about pesky memory access problems.

        • kazinator 7 days ago

          > in a language which doesn't warn him about how broke his code is.

          Can you make a citation from the codebase to back up this claim?

          The classes in the various <blah>widget.h headers have members that are plain pointers; that might be one place to start looking.

      • Tuna-Fish 7 days ago

        > I don't care if the author is a Rust expert or total newb. Someone who can write a 3D modeler in C++ is someone who should be able to use any new Algol-derived language with ease in short time, regardless if they hasn't seen a line of code in that language before.

        This statement is absurd. It implies that you believe that there are only cosmetic differences between languages, that no language can ever introduce any useful new concepts.

        Rust is not hard to learn. However, it contains new things that require you to put in the time to learn them. None of those things are as hard as learning, say, recursion or assignment was when you did it the first time. However, unlike switching between other mainstream "algol-derived" languages, there are actual new things you have to learn. If you go into it just pretending it's a cosmetically different variant of C++, you are going to bang your head on every sharp corner until you quit in frustration.

        And having those new concepts is the price of progress. The current programming paradigms are not sustainable in a world where basically every line of code you write is going to end up as a part of the attack surface of some system that will, eventually, get attacked.

        • dasloop 7 days ago

          A junior did an interview with us for a C++ position. At the end he recognized that he had a very superficial knowledge and ask to do the programming test in Java because “programming is programming” (using imperative languages). And then we have developers using C as FORTRAN, C++ as C, Rust as C++... and maybe this will be passable if you are a solo developer but not if you are in a team.

          Then add knowledge of the ecosystem :)

        • coldtea 7 days ago

          > This statement is absurd. It implies that you believe that there are only cosmetic differences between languages, that no language can ever introduce any useful new concepts.

          Well, the fact that you've missed the whole "Algol-derived language" is more absurd to me. Rust, in the end, is C++-streamlined plus fighting with the borrow checker.

          Not some huge new paradigm shift in how we construct programs (as would be eg. going from C to Lisp or Idris) -- just making the lifetime aspect of memory management explicit and having the coder handle it (in lieu of e.g. a GC).

          In an ideal world, Rust's lifetime management would be automatically derived by the compiler (in several cases, when it's simple, it already is).

          Which is why I don't consider it some new paradigm of how to think about programs or how to structure programs (like OO or FP or logical programming are).

          • scott_s 7 days ago

            > Not some huge new paradigm shift in how we construct programs

            I think Rust is exactly that. It makes memory safety a first-class concern for the language. Thinking about it as "fighting the borrow-checker" is like trying to program procedurally in Java, only using classes as holders of static functions, and feeling like you're constantly fighting against objects.

          • bluejekyll 7 days ago

            > In an ideal world, Rust's lifetime management would be automatically derived by the compiler (in several cases, when it's simple, it already is).

            This is exactly the type of work that's gone into the language over the last few years. It's actually quite rare with non-lexical lifetimes (and the advancements before it) that you need to explicitly call out the lifetimes anymore.

            I think the language is moving in the direction you want.

      • ksec 7 days ago

        >Well, that's the same attitude ("the language is fine, you just don't know how to use it, that's why you have bugs") that led us to 30+ years of shitty unsafe C code.

        I have yet to see anyone jump to Rust on first try and fell in love or could immediately use it in production with no problem. There is a huge learning curve involves.

        More than often, ( Or pretty much in every case ) They gave up. It was way too complex, they hated it, it was the first time they actually had to "fight" the compiler just to get shxt done.

        And then somehow after 3 / 6 / 12 / 24 months later. On 2nd try it clicked.

        It wasn't just Rust 1.0 or Rust 1.2 being harder, and the newest version being easier. It is just, dare I say Human Nature? Or you have been learning Rust in your background thread for few months without you even realising it. And once it clicked, everything you hate about it seems to be God Send to programming and software development.

        For a lot of people they may never click, after all Borrow Checked is complex and hard.

        • andreareina 7 days ago

          Oh man this is me with so many things. I'll hear about some new-to-me concept, start reading up on it but get stumped by an avalanche of new information and drop it. Months later I'll get the same bee in my bonnet, but suddenly the same articles I found impenetrable parse cleanly.

      • 0815test 7 days ago

        > In Rust it's the overt explicitness of the borrow checker, and the friction it adds to one's programming.

        Most, and perhaps all of the "friction" that the borrow checker adds to exploratory programming can be fixed with comparative ease by adding a few well-placed `.clone()` calls (for immutable data) and/or changing some type declarations to `Rc<RefCell<…>>` - at a minor cost to performance, in both cases. One might think that Rust needs to do more to support this use case, but given the performance implications, this is one example of how explicit can be far better than implicit. Regardless, it's absolutely the case that you can write "ALGOL" in Rust, just as you can write FORTRAN in any language. The code might not be at peak performance, it might even leak memory in rare cases, but it will do what you expect it to do otherwise.

      • gameswithgo 7 days ago

        your final assertion implies that any new language that is a significant paradigm shift from c++ must be flawed.

        • coldtea 7 days ago

          I do qualify that I speak about languages that are still "Algol-derived".

          Rust is not some significant paradigm shift (like e.g. Scheme vs C vs Prolog vs Haskell, etc).

          It's the same concepts and programming styles as C, C++ etc, plus fighting the borrow checker.

          • nicoburns 7 days ago

            Actually, a lot of the issues that C/C++ programmers have when they are new to Rust seem to be precisely because idiomatic Rust code (which can help to avoid borrow checker issues) is often in a more functional Scheme/OCaml style.

            Rust is both algol-derived, and ocaml-derived. And arguably the borrow checker creates a new paradigm entirely.

            • mrfredward 7 days ago

              >The borrow checker creates a new paradigm entirely

              I don't think this can be emphasized enough. You can get deceivingly far in rust with an OOP style, only to come to the disheartening conclusion that it's impossible to do what you want with the architecture you spent months of work setting up.

              For example, how would you architect a simple single threaded emulator? The CPU is an object, RAM is an object, easy enough. Okay, the CPU needs mutable access to RAM at all times, so we'll make the CPU own the RAM, sure why not? Okay now we want to implement a graphics device that can mutably access RAM, so we just...put the ram out on it's own and make it a Rc<RefCell<T>>?!? Now it takes three lines of code to unwrap all the smart pointers to write a single byte of memory?!? And it's slower because we have to pay for runtime borrow checking!

              I went down exactly this road. I still use rust and love many things about it, but I've come to the conclusion that writing typical single threaded object oriented code in rust only looks like it works; it's an awful idea in practice.

              I think the reason C++ people have so much trouble with rust is the syntax makes it easy to do the things you've always done, but the mysterious borrowchecker tells you no later on.

              • Retra 7 days ago

                It is hard to think about program architecture. Most languages don't make you think about it at all, they just let you jam code together however you want and give you the tools to make it work.

                That was the biggest shock I had moving to Rust: I couldn't just do what I wanted, I had to figure out how to do what Rust wanted. But I also wanted to learn how to design systems better, so the fact that Rust makes me think deeper about it is an advantage for me. In an OO language, I'd just lazily cobble things together. The code would work, but I would learn nothing.

                And some people would rather do things that way. It is very hard to break habits, and Rust basically forces you to do that.

              • v_lisivka 7 days ago

                It's hard to implement unsafe patterns in safe language. It's hard like using ASM with Java, because Java is platform independent language, while ASM is platform dependent language. This impedance mismatch causes problems, which can solved by wrappers.

                If we are talking about emulator, why not just make clear communication between CPU, RAM, and graphic device? Memory can be split into rows (e.g. by split_at()), so graphic device can take ownership of a single scan line at a time, leaving majority of the memory unlocked. We cannot avoid problem, but we can make scale of the problem much smaller by splitting memory into pages, so CPU can take ownership of pages, it works with right now, while graphical device can work with it own pages.

                • mrfredward 7 days ago

                  I can't understand how using split_at() would work...if the CPU and the GPU both have a reference to the RAM, we're still using an Rc<RefCell<>>. If the slice gets passed into the CPU and GPU's run() functions, then how does this magical memory manager know what to pass ahead of time?

                  >It's hard to implement unsafe patterns in safe language.

                  I agree with this 100%. And I think that for certain problem domains, rust provides more safety than you actually want.

                  • v_lisivka 6 days ago

                    Split memory into pages. Then create two types: OwnedMem, and SharedMem. OwnedMem will own page(s), so access to memory will require no Arc. SharedMem will implement safe protocol to access memory from different threads using Arc or atomic operations. SharedMem must also implement .clone(), so both CPU and GPU will be able to hold it.

                    > And I think that for certain problem domains, rust provides more safety than you actually want.

                    If writing of unsafe Rust by hands is hard for you, then write code in plain C, then convert it into unsafe Rust using crust.

            • coldtea 7 days ago

              >Actually, a lot of the issues that C/C++ programmers have when they are new to Rust seem to be precisely because idiomatic Rust code (which can help to avoid borrow checker issues) is often in a more functional Scheme/OCaml style.

              Well, those are not the issues that concern me, or that most (in blogs/HN posts/comments/etc I've read) consider the hard parts. It's the borrow checker.

              • nicoburns 7 days ago

                Right. But if you use a data-oriented FP approach, then you will often avoid borrow checker issues entirely. It is people trying to apply OOP patterns with lots of mutable state that constantly run into borrow checker issues.

                The borrow checker might seem like the problem, but the solution is to learn to code in a new style.

            • kazinator 7 days ago

              You can easily implement borrowing in C++ classes.

              I worked on a large C++ code base (some 15 years ago, before Rust existed) which did this kind of thing: it had references enforcing single ownership that was handed on assignment or passing.

              Borrowing was of course done in the usual way, by passing down references (most often const ones).

          • xfer 7 days ago

            Rust has lambdas, ADTs, pattern-matching and typeclasses(although not as powerful without kinds). These things alone makes a significant paradigm shift than programming in algol style languages. You can just use ARC<T> for every heap-allocated value and rust will still offer a significant advantage compared to C/C++.

            • pjmlp 6 days ago

              C++20 has all those things as well, except for pattern-matching expected to arrive by C++23. :)

              So if it wasn't for the copy-paste compatibility with unsafe C code, there is already quite a few modern features available in the language.

          • baq 7 days ago

            s/fighting the borrow checker/enforcing rules of data ownership/

          • gameswithgo 7 days ago

            i think the borrow checker may indeed be a rather large paradigm shift, and im super interested to know if you can get used to it and be as productive as you are in c++ or if it is innately harder. to me it is still hard to work woth but i habe 30 years of being ised to C or garbage collection

            • nicoburns 7 days ago

              As someone from a JS background, I am far more productive in Rust than C++. C++ makes it really easy to accidentally break something that then takes ages to debug. And using libraries is a massive pain.

              However, if you have already learnt to be productive in C++, then I suspect Rust would end up being slightly slower to write the initial code, but not much. And it'd make up for it in ease of refactoring.

    • tsimionescu 7 days ago

      > Heck, the author praises Rust and it's memory safety, but then proceeds to criticise Rust compiler because, as he puts it, the compiler will stop you from doing unsafe studf again and again. Isn't that the whole point? Or is anyone expecting that your memory corruption problems will magically cease because you write your same old memory allocation and access bugs in Rust instead of C or C++?

      I think the biggest problem with advanced type systems and complex compiler checks is that they are only desirable when you know the code you're writing is the the right one. A lot of the time, you're exploring a solution and don't care about edge cases, since you're not sure you've even found the right happy path. At this stage, you don't really care if your code is handling all required inputs, if it doesn't have leaks etc. - you just want to run it and see whether it at least sometimes produces the right output. At this stage, you're often fighting the compiler.

      Once you know that you're on a good path, then you start caring about safety and all the other bits, and the compiler starts becoming a trusted friend.

      It would be really interesting to have a system that supported both modes, e.g. starting from Rust but setting a flag to turn borrow checker errors into warnings or something similar. I'd bet that would change many people's perspectives, like the author of this article.

      • pdkl95 7 days ago

        > you just want to run it and see whether it at least sometimes produces the right output

        Then use a dynamic language like ruby or python and enjoy not only data type freedom, but also features like easy introspection and code manipulation at runtime. Protyping and experimentation in a REPL is much faster, easier, and memory safe. If you are just experimenting, why are you wasting time and effort on e.g. C++'s complex type system? If you don't care about memory leaks, why waste any effort on memory management when the garbage collector can handle that for you?

        > starting from Rust but setting a flag to turn borrow checker errors into warnings

        Experience suggests the "we'll do it right in the next version" argument leads to "prototypes" being shipped as the "next" (only) version.

        The difficulties imposed by Rust is the goal. Actually writing correct and safe code is inherently a difficult problem. Rust is trying to force programmers into actually addressing that problem. Writing similarly correct and safe C++ is also time consuming and difficult. The difference is C++ lets the programmer shift that work and expense onto the user in the form of time-wasting crashes and expensive security vulnerabilities.

        • tsimionescu 7 days ago

          I never said anything about a release - I'm not even thinking about code you would commit. I'm talking about the kind of coding where you're exploring a new feature on your own machine - essentially doodling in an IDE instead of on paper. It makes no sense to me to make such code 'correct' - I don't even know if its useful to any extent, why would I care about its correctness?

        • kiriakasis 7 days ago

          Also I think that with enough .clone(), raw pointers and `unsafe` you can avoid almost all borrow checkers errors.

      • larzang 7 days ago

        I actually find strong typing speeds up green-field development rather than hampering it, because it cuts down on the little avoidable things that inevitably creep in when you're trying to architect and evaluate and code all at the same time. The kinds of things that make you smack yourself in the face for an hour wasted by the most trivial mistakes.

        In addition to my own personal experience this has been incredibly well illustrated to me because I'm overseeing two junior JS devs right now where one starts any new code with "any" types and tries to make Flow happy later and the other starts with real types. The former has a LOT more "this isn't working and I have no idea why, help" moments.

        • reificator 7 days ago

          > I actually find strong typing speeds up green-field development rather than hampering it, because it cuts down on the little avoidable things that inevitably creep in when you're trying to architect and evaluate and code all at the same time. The kinds of things that make you smack yourself in the face for an hour wasted by the most trivial mistakes.

          I want to agree with you on this statement, but I don't think your anecdote supports it.

          > In addition to my own personal experience this has been incredibly well illustrated to me because I'm overseeing two junior JS devs right now where one starts any new code with "any" types and tries to make Flow happy later and the other starts with real types. The former has a LOT more "this isn't working and I have no idea why, help" moments.

          To me it just sounds like the second junior has a stronger understanding of the language/type system.

          Some people come into junior positions because they've learned enough to pass a CS course. Some come into junior positions because they've spent their whole life programming in some way or another and want to get some professional experience on their resume. (And everything inbetween of course)

          Now, trying to push the Any dev toward specifying types upfront and watching the results might give you better evidence, and better performance to boot.

        • tsimionescu 7 days ago

          I don't have a problem with strong types, I agree with you. Dynamic types are usually too much hassle even for prototypes. I was talking more about stuff like Rust's borrow checker or dependent type systems.

      • viraptor 7 days ago

        > It would be really interesting to have a system that supported both modes, e.g. starting from Rust but setting a flag to turn borrow checker errors into warnings or something similar.

        https://github.com/thepowersgang/mrustc kind of does that. It assumes the input code is valid at the moment.

        But if you want to experiment first, you have other language pairs you could use. Python + typed Cython, or Ruby + Crystal, or other options...

    • blub 7 days ago

      That's a decent attempt at suppressing OP's message, but the thing which makes all of the above irrelevant is that C and C++ developers are the main groups of developers Rust is targeting.

      If they can't use the language, the Rust community should perhaps listen to them. Or should have listened to them 10 years ago, because let's be frank: the friction is coming from the fact that Rust can't be changed any more so that it becomes as ergonomic as other languages people are used to. It's also moved heavily in the direction of some FP concepts which have zero overlap with C and arguably little to do with C++.

      The big assumption Rust is based on is that people will recognise the benefits of memory safety and be willing to pay the price for it. Many outside the early adopter group won't be, that's how the mainstream works.

      • nicoburns 7 days ago

        C/C++ developers can't use Rust without learning new concepts. That's not a failure. If there were no new concepts, then there wouldn't be any point in the langauge in the first place.

        • dzdt 7 days ago

          Contrariwise there is huge demand for a language with a trimmed-down set of concepts from C++ and a much improved syntax.

        • kazinator 7 days ago

          > If there were no new concepts, then there wouldn't be any point in the langauge in the first place.

          Not so; the same concepts can be clarified and captured in a better set of requirements, leading to better implementations of the concepts.

          There can be a point in fewer concepts that are simpler.

      • viraptor 7 days ago

        > the friction is coming from the fact that Rust can't be changed any more

        The basic language as such doesn't change much, but what the compiler infers and accepts gets extended with almost every release. rustc from 2 years ago is a lot more strict than rustc now. And lots of lifetime annotations you had to do before, you can omit today.

        The experience is much nicer and the friction definitely goes down.

        • duneroadrunner 7 days ago

          Rust's usability is advancing, but I'll note that so are C++'s memory safety facilities. Arguably, modern C++ programming is becoming intrinsically more safe than more traditional coding styles (though arguably the use of string_views and spans outside of function parameters is a step backwards), but progress is also being made on the lifetime profile checker (C++'s borrow checker analogue), and there are libraries[1] that allow you avoid potentially unsafe C++ elements, to the degree that (memory and data race) safety is a priority.

          At present, C++ is significantly lacking in safety enforcement tooling and "community enthusiasm" for memory safety compared to Rust. But to me, it is not obvious that that will be the case indefinitely. It's even plausible that Rust and C++ will sufficiently converge in flexibility and safety that at some point automated translation between the two languages will be a thing.

          At the moment, I think the main relevant difference in fundamental (as opposed to not-yet-available tooling or whatever) capability between the two languages is Rust's lack of support for move constructors/destructors. I think it prevents the safe, efficient, unintrusive, robust implementation of a small but significant set of algorithms / data structures.

          But I guess my point is that I think that C++, and its existing codebases, are not necessarily condemned indefinitely to be memory unsafe in the way they have been historically. And that could be a factor that contributes to the justification of deciding to continue to use C++ in some cases.

          [1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus

      • pcwalton 7 days ago

        > the friction is coming from the fact that Rust can't be changed any more so that it becomes as ergonomic as other languages people are used to.

        What is your proposal, specifically?

        It's not that we weren't listening to C++ programmers 10 years ago. We put a ton of effort into making Rust as easy to use as possible. Rather, it's that the problem of memory safety without GC is fundamentally hard. If I could wave a magic wand and release an incompatible Rust 2.0 with memory safety and no new concepts to learn over C++, I'd do it. But it's easy to just say you want a new language. It's a lot harder to actually design such a thing.

        I generally think that if you want memory safety, you must either have a garbage collector or the mutability rules and borrow check. There is no other option.

        • blub 6 days ago

          My only proposal is that the Rust community spends more time coding and less time criticising other languages and praising Rust.

          Making proposals about the ergonomics of Rust is way overdue, but I will note that jumping through even more hoops to get correct code is not progress, nor the huge victory that the Rust community hails it to be. Humans use compilers to do work for them, not vice versa.

          GC for example is brilliant, Swift is also quite nice. Even if neither solution is applicable, they are both excellent examples on how a user-friendly solution can look like - almost zero user effort.

        • dan-robertson 7 days ago

          Do you think it was obvious that such mutability rules and borrow checks were sufficient before languages like rust were invented?

          What about a more impractical approach like e.g. ATS?

        • tombert 7 days ago

          Speaking out of genuine ignorance here...if the only ways to get memory safety without GC, how does Swift or Objective C do it with ARC?

          • littlestymaar 7 days ago

            Arc is a kind of automatic memory management that's included when people talk about GC in general.

          • pcwalton 7 days ago

            Reference counting is a form of garbage collection.

            • tombert 7 days ago

              Yes but this is done at compile-time, not runtime, isn't it?

              EDIT: Upon reading some stuff, apparently I am mistaken, and it's got runtime overhead. Silly me.

              • steveklabnik 6 days ago

                You're not totally wrong; that's the "A" in ARC: Automatic. It automatically inserts code at compile time, but that code has a runtime effect.

      • baq 7 days ago

        i'd say game developers aren't really the target audience, because they expect to move fast and not necessarily correct, just correct enough most of the time. other developers don't have issues with the compiler being more picky; compile times are more of a problem in adoption than language strictness.

    • slavik81 7 days ago

      > Heck, the author praises Rust and it's memory safety, but then proceeds to criticise Rust's compiler because, as he puts it, the compiler will stop you from doing unsafe stuff again and again. Isn't that the whole point?

      Rust ensures that all valid rust programs are safe, but this does not mean that programs that are difficult to express in rust are unsafe.

      Consider how future improvements to rust may make some previously difficult to express patterns easier. I think non-lexical lifetimes would be one such example. You could imagine that someone who learned on a future version of rust might be similarly annoyed at compiler errors when working with an old version of rust that's more limited in what things can be expressed and understood as safe.

    • kazinator 7 days ago

      > . It is im fact the solution, and a solution that's being ignored.

      If the coder's C++, that is written in flow without being distracted by borrow-checkers and whatnot, is in fact correct code, then no, there is no solution that is being ignored; what's being ignored is a "problem in search of a solution".

      > Or is anyone expecting that your memory corruption problems will magically cease because you write your same old memory allocation and access bugs in Rust instead of C or C++?

      That's a pretty good executive summary of the Rust cheerleading.

      In fact, what you describe is sometimes possible. For illustration, let's confine our attention to use-after-free bugs and memory leaks. If we make the free function do nothing, and stick in a garbage collector, then in fact you can write (some of) "your same old memory allocation and access bugs" yet they are mitigated.

  • edflsafoiewq 7 days ago

    I feel the opposite. Strong compile-time checks make it easier to modify a system, and especially make it easier for people unfamiliar with a codebase to contribute. Being explicit what the static properties of a system are makes them easier, not harder, to modify.

    Types serve as explicit documentation for facts about the system that would otherwise have to be reconstructed by every reader. Type checking ensures that any change to one part of a system still interfaces consistently with all the other parts.

    Writing in a dynamic language can be faster, since you can skip writing down information that you would have to be explicit about in a static language, but once that information has been purged from your mental cache, IMO that's when the system acquires the immutability of marble.

    (The other nice thing about dynamic languages is certain patterns are often syntactically much cleaner.)

    • sanxiyn 7 days ago

      Hot reloading is the critical feature, and dynamic languages usually have better support for it. (Lisp is a good example.)

      • adamnemecek 7 days ago

        Hot reloading doesn’t provide safety guarantees.

        • sanxiyn 7 days ago

          Maybe, but hot reloading is very very useful. It is mostly a development time only feature anyway.

          • loup-vaillant 7 days ago

            I believe we have seen Casey Muratory doing hot code reloading in C++, in his Handmade Hero stream. Compile the dll, reload & test the dll, without exiting the game runtime he's developing.

            The Yi editor, written in Haskel, I believe does hot code reloading as well.

            The XMonad window manager can be recompiled and reload while keeping your windows up (the configuration file is actually Haskell code).

            ---

            Yes, hot code reloading is bloody useful. It is also perfectly compatible with static typing. I see no good reason for statically typed languages to have worse support for it.

            • estebank 7 days ago

              It's only incompatible with Link Time Optimization and changes to static dispatch or structure, but anything that could have exposed as a COM object could be used.

          • blattimwind 7 days ago

            Unloading/reloading modules is perfectly possible, though in my perception relatively less common on Unix/Linux, while slightly more common in Windows land (e.g. DLL plugins, resource/translation containers etc.)

  • atoav 7 days ago

    I am probably more of a beginner when it comes to compiled languages. What surprised me most about Rust was that after understanding it, I liked it more than Python. I intended to learn it as a speedier more controlled alternative. A sharp tool to throw at slow code to make it go away.

    But once I got the hang of it progtamming Python became less and less attractive. The most interesting thing about rust is, how fast you can get up to speed with understanding what somebody elses code does.

    The thing however is: if you try to write Rust like Python or C, you’re not in for a good time. It took me 3 months to stop using ingrained OOP patterns I really thought I needed because this was the way how I did things back in Python.

    The moment I started to become interested into how to structure code in Rust, was the moment it made click for me. Seems it is much easier to program WITH the compiler than against it — who would have known!

    • xvilka 7 days ago

      You can try to use Elixir for scripting instead. It feels "right", after the experience with OCaml, Rust, and similar languages.

  • dahfizz 7 days ago

    I have started to see a worrying trend were developers focus more on how easy it is to develop X rather than how good of a finished product is X.

    It makes sense for developers to want development to be easier and for businesses to want it to be faster but it feels lazy and cheap to actively avoid tools that would help us produce better programs with much stronger guarantees in the name of ease of development.

    It's not like rust's checks are arbitrary. If you wanted Rust's safety and guarantees in C++, then you would still have to do all the things the rust compiler is doing for you.

    • raphlinus 7 days ago

      This. I believe the value proposition of Rust is that it decreases the cost of developing high quality software, much as the value proposition of PHP is that it decreases the cost of medium-quality software. It is not a magic bullet, but requires a nontrivial learning curve. If the goal is safe, performant code, then I think there's a good argument it's worth it. If that's not the goal, then other languages might be better choices.

    • edflsafoiewq 7 days ago

      There are plenty of ways to write a program where, eg. a mutable and immutable reference exist at the same time and there is no memory unsafety. You have to learn to write programs in the way that rustc can prove is safe.

  • sametmax 7 days ago

    I agree, but let's remember how young rust is, how little experience people have with it and its paradigms and how much they are used to code with c/c++.

    How course it's hard for them right now.

    Guess what, it was harder when they started c/c++ decades ago. There was less tooling, best practices were even less clear, all code bases looked different and the language ergonomics were way worse than today.

    Give it some time. Some time for the language to mature of course. But more than that, some time for the dev to actually reach fluency, not only it the language and ecosystem, but on the general philosophy of this way of producing software. It's even harder given many have to unlearn years of experience and patterns that made them productive, and adopt, discover, or even even new ones to replace them.

    We have hugely high expectations towards rust because of the amazing work the core team has already made in so little time.

    I see the same reaction toward the last 2 flight crashes. People are shocked this can happen. I'm just amazed it doesn't happen more often. The institutions have generally done a fantastic job.

    Now to say we should not fix what's broken in both cases.

    But let's be fair to the incredible result we already got.

  • ilovecaching 7 days ago

    I’ve had the opposite experience. Type driven development makes writing code easier, with less errors, and also makes refactoring significantly easier. For those of us where C++ is the optimal choice Rust is a major step forward in terms of better abstraction, safety, and yet maintains the efficiency requirements we need.

  • jayd16 7 days ago

    Its just temporary pain. Once you learn to use types properly, you stop having to constantly think about typing. I assume Rust pointer ownership is much the same way.

    The author was doing unsafe stuff and the compiler complaining. Once he gets in the swing of things, doing it right will become his natural flow. Verbosity of a language is a valid complaint that never goes away no matter how idiomatic your code writing gets but as written I'm not sure this was the author's complaint.

  • hawski 7 days ago

    There could be a --i-am-a-stuntman-and-i-spit-in-the-face-of-danger flag, that would disable some checks for compilation to be fast enough. It could be used when building known good packages or during design iteration. It would be an escape hatch.

    Of course the problem is: would people just add the flag to their configuration and never disable it? I think they would not. Because people mostly use defaults. That's why instead of -Wall -Wextra -pedantic with possible -Wereor for development, most places I worked in ignore most default warnings and just occasionally run some kind of static analysis. Even though many times the analysis often results with things that would be detected with additional warning flags.

    And yeah I hate it and I wish that warnings would mostly be treated as errors or silenced when applicable. Then there are always separate efforts to "clean the warnings". But afterwards new code just introduces new warnings, because people are trained to ignore them.

    I assume that Rust developers don't want my scenario to happen at all, but I feel that with defaults reversed it wouldn't.

    But maybe it's to great a risk? Of course as always it's a game of trade offs.

    • yoklov 6 days ago

      IIUC, for typical programs, most of Rust compilation time is spent waiting for LLVM to spit out results.

      There's a plan to use https://github.com/CraneStation/cranelift for debug builds instead of LLVM, which would make them faster at the cost of supporting fewer targets, and producing worse code.

    • Retra 7 days ago

      You're assuming those checks are a real bottleneck for compile times. Rust only does borrow checking at the function level, so it's easy to parallelize and not all that slow. Most of the compile time is spent on code gen, if I recall correctly.

  • sanxiyn 7 days ago

    I disagree, because Rust compile time checks are not prohibitive. I agree on all other points: you shouldn't try to write perfect software first time, mental overhead is a serious concern, battling type system is bad (but you don't do that in Rust). Overall, Rust is a productive language, especially compared to C++.

  • flukus 7 days ago

    > I strongly disagree with the Rust mentality, and the general mentality of statically typed languages with extremely prohibitive compile time checks, that seem to become more common.

    I think this is more post-hoc justification than anything else. There seem to be an awful lot of developers concerned about memory safety since rust started becoming trendy and I don't think many of them were coding in ada before rust existed.

    • Jach 7 days ago

      Rust's contribution is memory safety without a GC, so as a new approach it's somewhat exciting. But for most programmers before Rust and today, memory safety has been a solved problem not worth thinking about because most programmers use a GC language.

  • kurtisc 7 days ago

    I think the assumption that static typing means things take more time requires justification. Usually I see the assertion given from people who naturally take longer getting things to pass compilation just because they're not used to using it. When I use dynamically typed languages I find footguns in undefineds and empty strings where others wouldn't. I also have to write tests - which themselves may have bugs - for things that static analysis could do on its own. Why use expensive dev time for this instead of cheap CPU time?

    >Underlying that model seems to be a concept of software like a sort of renaissance master's marble statue, error free and perfect at time of production.

    Most of the time I'm writing code isn't for the first implementation of a green-field feature and, really, most programming problems aren't that hard in terms of logic flow. If I refactor and the type system and static checking don't complain, I can be reasonably sure it's going to work. And I've seen too many 'temporary hacks' that became forgotten and leaked to review or production.

  • vbezhenar 7 days ago

    That's true. Different projects require different quality. The projects I'm working on are tolerable to bugs. I just need to know that bug happened (from logs or user complaints) and I need to fix a bug in a timely manner. I don't need to produce bug-free code. I don't need to produce fastest possible code either, servers are seriously underutilized and there's a lot of CPU and memory. I'm using Java because that's what I know well. I like Rust idea, I'm tinkering with it because I'm kind of perfectionist and I like Rust approach, but I won't apply it to my current work in foreseeable future. Even switching to Kotlin from Java was a hard call, because so many people don't want to learn anything new and I can't really blame them.

  • 75dvtwin 7 days ago

    > I strongly disagree with the Rust mentality, and the general mentality of statically typed languages with extremely prohibitive compile time checks, that seem to become more common.

    > In my opinion the dominant metric to evaluate the usefulness of a language's type system should be its overall effect on cost, time spent, productivity, ease of development and capacity to change. Everything else is very subjective or just an aesthetic concern.

    I agree with your overall dominant metric. But I come to a different conclusion of what language/libraries bring me there.

    To me a type safe language, is a refuge, a comfort zone -- away from the wilderness, unpredictableness and punishing complexity of troubleshooting -- associated with untyped languages.

  • stunt 7 days ago

    That’s not necessarily a fair point to compare. Perhaps it just feels like that because C++ has been around for a long time. If you write production code without being a C++ master, you also have different struggles before getting it right.

  • adamnemecek 7 days ago

    > capacity to change

    Good luck making changes to a 100kloc Python codebase.

    • ignaloidas 7 days ago

      If you have good manners, Python codebases can easily grow over 100kloc mark. Static type annotations, using descriptive variable and class names, type checks on user input(esp. libraries) makes growth safe and simple.

      • arcticbull 7 days ago

        That’s a good observation, thing is, Rust just makes the manners mandatory.

    • pizza234 7 days ago

      I do something similar daily, and it works fine, as we have a strong test suite.

      You can't disassociate dynamically typed languages from (strong) test suites, so one needs to qualify:

      > Good luck making changes to a 100kloc Python codebase without test suite

      versus

      > Good luck making changes to a 100kloc Python codebase with a good test suite

      In context, the first case is no different from "Good lucking making changes to a 100kloc Rust spaghetti-coded codebase", and one can't meaningfully judge a something based on a poor use of it.

      • adamnemecek 7 days ago

        > In context, the first case is no different from "Good lucking making changes to a 100kloc Rust spaghetti-coded codebase", and one can't meaningfully judge a something based on a poor use of it.

        It's not the same. Type system provides certain guarantees. Also it's much harder to write spaghetti code in Rust.

    • gmueckl 7 days ago

      You could perhaps start by adding type annotation. They are not perfect, but they help.

    • Spiritus 7 days ago

      No problem. I do it every day.

      • adamnemecek 7 days ago

        Alright, now dive into a new codebase and report back.

  • mjburgess 7 days ago

    Static checking burdens the developer with thinking more, etc. -- for sure.

    The cost is requiring a developer with stronger cognitive abstracting skills. Those people tend to be academics (its almost a definition of a good academic) and also, perhaps, less pragmatic.

    The ease of programming is not merely a matter of knowledge or experience, base cognitive skills play a very significant part which are largely an at-birth and developmental factor (cf. The Neuroscience of Intelligence (Cambridge Fundamentals of Neuroscience in Psychology)).

    Probably languages requiring a proficiency at dealing with highly abstract relationships as part of the activity of programming are never going to be mainstream. Most people find that too difficult to do easily, and so too tasking to program.

    That isn't the general case however. Some people find it easy enough, and so do not see this tradeoff. For these people, the clear benefits in creating a statically "correct" program outweigh the minor difficulty in creating it.

    For the able, this "difficulty" is perceived as fun, and as frustrating by those who aren't. When something is beyond our basic capacity we tend to see it as "needlessly difficult" and not worthy of our time/attention (and of course, for us, it is).

    In otherwords: the unable are often snobs.

    eg. "Acting is stupid", "Rust is crap", "Painting is pointless" etc. -- all amount to, "i struggle to do that".

    • TomVDB 7 days ago

      > In otherwords: the unable are often snobs.

      Oh the irony.

      • mjburgess 7 days ago

        You'll find no value judgement in my comment.

        There are many axes of intelligence, as well as of human value in general. I only said that comfort-with-abstraction is one axis on which people vary -- and I'd say that's exactly what the previous comment relies upon.

        All it says is "this is needlessly hard", the only reply can really be: yes, for you.

        I was offering an explanation of why that is; or else are we really saying that this "hardness" is universal?

        One of the more important characteristics of a developer is pragmatism which has zero covariance with comfort-with-abstraction. And so, why not value those who have that more?

        That is, to be better at abstraction isnt to be a better developer. It is only to be better at one sort of development. Equally, to have more pragmatism is to be better at a different sort.

        There's no snobbishness in my comment, only in a person who reads into it a value judgement about this specific form of intelligence.

        Why read that into it?

    • kybernetikos 4 days ago

      > Static checking burdens the developer with thinking more, etc. -- for sure.

      I'm not sure I agree. Most type languages as implemented in common programming languages are bad at describing abstraction. This means that if you're programming in one of these languages, you are forced to reduce your level of abstraction (which is sometimes touted as an advantage).

      And just because someone's smart enough to find working out how to satisfy the type checker an enjoyable challenge, doesn't mean they're dumb enough to think that just because it's fun it is always a good use of their time.

  • Retra 7 days ago

    If you want to build the best code, you want it to be fast, correct, and maintainable.

    If you want to build the best company, you might not care so much about these.

    But then, not all of us are running businesses. And building your company on top of the best code isn't even a bad idea.

  • devwastaken 7 days ago

    Rust doesn't make much sense for this kind of project in the first place. You use it for things that need to be memory correct, and proveably so. Very useful for handling uncontrolled data.

  • woah 7 days ago

    Do you use a text editor that highlights errors inline or do you depend on errors in the terminal? Maybe your frustration stems from a lack of tooling.

  • petre 7 days ago

    This was my impression as well when I tried Rust - always fighting the compiler. None of this happens with D. You just code away and keep being productive without the annoyances of C++. In fact C++11 and 17 are less and less annoying.

    • atoav 7 days ago

      Fighting which stops eventually. I program Rust for nearly a year now and I found that there is a point where it gets quite smooth. The many mental guarantees that the code gives you can help you a lot to stop worrying about a whole class of things. I realized just how much this is the case when I wrote something in Python again and separation of which code affects what and which code is doomed to fail from the start became much harder.

      Rust initially has been a lot about fighting the borrow checker, but once you get the hang of it it happens quite often that you write pages of a complex functionality including tests – you hit build and it just works.

      I am certain that Rust prevents entire classes of problems I filed bug reports for, even with extremely experienced developers. I understand that the nagging voice of the compiler or cargo clippy is not just for everyone, tho.

    • isatty 7 days ago

      I believe you’ve not been on the receiving end of a 17 page compiler error while trying to compile a template heavy app, because you forgot to put an &.

      The important part is to realize _why_ you’re fighting the compiler as it’s trying to make _you_ write better code and improve.

      If you find non issues being reported by the compiler please report it and make it better for all of us too!

      • Const-me 7 days ago

        > as it’s trying to make _you_ write better code and improve.

        It’s not necessarily an improvement. When an algorithm processes complex data structures organized in graph or tree, no amount of better code allows to easily implement that in Rust. It’s either slow, or unsafe and hard to implement, or both.

        Even without trees, consider a simple LRU cache structure. Trivial to implement in most languages by combining linked list with hash map. Rust implementation is more than 1000 lines of code, many of them are unsafe: https://docs.rs/linked-hash-map/0.4.2/src/linked_hash_map/li...

        I never wrote production code in Rust. But based on my limited experience, the language is fine for projects that have few data structures, or they’re simple so you can stick to library containers, and a lot of code processing them. For many practical problems it’s quite the opposite.

        • baq 7 days ago

          > Even without trees, consider a simple LRU cache structure. Trivial to implement in most languages by combining linked list with hash map. Rust implementation is more than 1000 lines of code, many of them are unsafe: ...

          in this context, criticizing using unsafe in rust and comparing that to C++ is comparing apples to oranges. GC languages aren't even worth mentioning here.

          > It’s not necessarily an improvement. When an algorithm processes complex data structures organized in graph or tree, no amount of better code allows to easily implement that in Rust. It’s either slow, or unsafe and hard to implement, or both.

          here's the thing: all of the above are true in other languages, C/C++ included, it's just that no compiler besides rust will warn you that recursive data structures are hard - it doesn't matter if implementing them is easy, proving they're implemented correctly never is. rust tries to help you prove you did the right thing and it needs assurances (unsafe) where it just can't do that. C++ is all unsafe.

          • Const-me 7 days ago

            > criticizing using unsafe in rust and comparing that to C++

            In that comment I was mostly criticizing the amount of code. That code doesn’t need to be written in C++. std::list has stable iterators so you can put list iterators to the hash map. This way LRU structure becomes a trivially simple wrapper over std::list and std::unordered_map containers.

            Note how Rust developers implemented custom linked list on top of raw pointers, doing manual memory management with Box::into_raw(Box::new(Node::new(k, v)))

            C++ implementation doesn’t need a single new/delete, hence much safer than unsafe rust. LRU cache is simple, not too hard to implement correctly in C++ just because it’s very few lines of code.

            > it's just that no compiler besides rust will warn you that recursive data structures are hard

            In GC languages like C# or Java it’s both easy and safe.

            In C++ they can be challenging to implement correctly, but because it’s all unsafe, I get huge amount of help from all levels of the stack. OS debugger, C runtime, C++ standard library, compilers, they all evolved for decades trying to improve life of developers like me writing unsafe programs which use raw pointers. You can implement a recursive data structure without a single new/delete, relying on standard collections for memory management. It doesn’t guarantee pointer safety just like unsafe Rust doesn’t, but at least no need to worry about memory leaks.

          • guitarbill 7 days ago

            > proving they're implemented correctly never is

            Let's be clear: Rust is still far away from formal verification; the borrow checker won't save you from logical errors.

            Second, data structures like graphs, trees, hashmaps are well understood and have a lot of algorithms built on top of them. Algorithms with a lot of research behind them, and complexity analysis. While complexity analysis doesn't always equal performance, if I can't use these universal tools in your language, I'll probably think of it as a toy language which stops me from getting stuff done, which is still what most of us are paid for.

            • baq 7 days ago

              > Let's be clear: Rust is still far away from formal verification; the borrow checker won't save you from logical errors.

              completely agree.

              > Second, data structures like graphs, trees, hashmaps are well understood and have a lot of algorithms built on top of them.

              well understood, yes, by authors of textbooks and papers. your average programmer may have understood them once, before he made it to the enterprise and started passing buckets of bits between http endpoints for a living.

              > Algorithms with a lot of research behind them, and complexity analysis. While complexity analysis doesn't always equal performance, if I can't use these universal tools in your language, I'll probably think of it as a toy language which stops me from getting stuff done, which is still what most of us are paid for.

              you can write a recursive data structure in Rust in the same way you'd write one in C++ - use unsafe pointers, even the asterisk is the same. nothing is stopping anyone from doing that, in fact there are lots of examples on crates.io and in the stdlib.

            • unrealhoang 7 days ago

              Your argument doesn’t make much sense. You can use unsafe and raw pointer to do EVERYTHING you can do in C/C++ and it will be just as safe as you write it in C/C+. And then, you can (ab)use the type system to make sure you or your team cannot use it in the wrong way.

              • Const-me 7 days ago

                > and it will be just as safe as you write it in C

                C++ standard library containers have guarantees about iterators and pointers invalidation, e.g. std::list never invalidates any of these, unordered_map invalidates iterators when rehashed and never invalidates pointers to either keys or values. This allows building unsafe data structures on top of standard collections, and then compose custom unsafe data structures on top of each other.

                This makes C++ both safer (at least from memory leaks) and easier to use compared to unsafe rust.

              • guitarbill 7 days ago

                why would i use rust in the first place if i was disabling the borrow checker? isn't that the main selling point?

                because of the ecosystem? because it's easier to hire rust programmers than C/C++ programmers, or get more open source contributions from rust vs C/C++? unlikely with a learning curve or community like that.

                • Const-me 7 days ago

                  Rust only disables these checks very selectively.

                  The idea is good, MS did same in C# since the first version in 2002. Allows to do pointer arithmetic when you really need to, for performance or native interop.

                  What I don’t like about Rust is they use unsafe to workaround language limitations.

                  In C# I have only used unsafe code couple times over the course of 20 years. The standard library doesn’t use unsafe code either, at least in modern .NET all these collections are 100% safe code. The main, safe subset of the language is good enough for the majority of practical applications.

                  In Rust there’s tons of unsafe code in standard library, substantial amount of unsafe code in third-party libraries, and if your software is complex enough, your own code will likely contain usafe as well. This causes safety issues: https://medium.com/@shnatsel/how-rusts-standard-library-was-...

                  • steveklabnik 7 days ago

                    One of the reasons the standard library has a lot of unsafe is that the standard library is small, but one of the criteria for being in the standard library is “uses a lot of unsafe.” We’d rather these things get massive visibility.

                    In all my years with Rust, the only unsafe I’ve needed in any of my applications is when doing FFI, and my toy OS. YMMV.

                    • sanxiyn 7 days ago

                      On the other hand, Rust certainly could use a lot less unsafe in the standard library than it currently does. It just doesn't want to.

    • sanxiyn 7 days ago

      I agree D has much better onboarding for C++ programmers, but that's because it's similar, not because it is particularly easy to learn.

    • gmueckl 7 days ago

      Being able to use more D would be nice! But the binding issues remain the same there. There recently was talk about having the D compiler emit C++ headers for exports from D modules automatically. This would be an instant killer feature for me.

      • p0nce 7 days ago

        dpp is en effort that allows to include C++ headers, also there is ongoing effort to link with C++.

        https://github.com/atilaneves/dpp

        • gmueckl 7 days ago

          Yes, dpp has issues with C++ constructs according to its readme unless that changed recently. I am talking about the inverse: have dmd generate a C++ header automatically for extern(C++) declarations during compilation. This was discussed quite recently.

  • clanrebornx 7 days ago

    People are downvoting not because Rust is better choice for this project with the cons you mentioned but because Go is far better choice if you want less mental overhead and total cost

  • p0nce 7 days ago

    I'm 100% with you.

    There is often a debate in the D community how the defaults could have been better: pure, @safe, const by default, no GC by default etc.

    But not every bit of code need to be perfect. Code must prove its usefulness first and foremost, before the need to be reliable, safe, fast and beautiful even enter the picture.

    I'd go as far as to say, thinking of a nascent project as something perfect and beautiful likely leads to over-idealization and will delay the time to completion many-folds.

    Ability to write ugly code is - for me - a feature.

    • yoklov 6 days ago

      You can still write hacky temp code in Rust, although it does take some experience to get familiar with the ways you can do this without hitting borrow checker errors and etc (well, short of reaching for unsafe, which is generally not a good way to do this).

      That said, for getting code written fast, Rust for me has been better than C++ for a while now, even though for most of that I was better at C++ than Rust. The reason for this was largely Cargo, which eliminates the pain points of dependency and build management that plague C++.

ilovecaching 7 days ago

Three problems with this:

1. You still have to fight with borrow checking in Rust as in C++, it’s just not automated. You have to consider moves and copies, borrowed references, etc. As the author points out, if you’re used to writing C or C++, it’s going to take a while before responding to the borrow checker is second nature. The point is that the borrow checker is a computer and doesn’t make mistakes the same way a human does, and that’s value added not detracted.

2. Having the benifit of actually having a package manager, Rust is much easier to download and use dependencies with. That said, I agree with the general premise of not using Rust if you have an immediate business need and it’s missing a core library. My issue is that it should be fairly apparent before you start a project what dependencies you need, so a rewrite back to C++ seems odd. Also, Rust is an open source ecosystem, and people using it should feel compelled to consider writing the missing pieces they need for the benifit of the community. It’s also odd to say that Rust doesn’t have what you need, it sounds like there are C libraries that already do what you want, and Rust can wrap C.

3. If something is written in C and you don’t have time to replace it, just wrap it in unsafe and make a safe interface over it. Rust is exceedingly good at interfacing with C, so any library you can use in C can potentially be used in Rust.

  • epage 7 days ago

    > As the author points out, if you’re used to writing C or C++, it’s going to take a while before responding to the borrow checker is second nature

    I see these comments and it feels so foreign to my experience. The borrow checker was second nature to me because of my C++ experience. These were things I already had to juggle mentally. On rare occasions, it complained about something that I could prove was valid but I understood why it couldn't tell. Usually, when I hit it, it is because I forgot a case and am grateful for it. I know of at least one optimization I've made that I would never have bothered with without the borrow checker. It would have been too much bother for me to reason about everything. Even if I did, it would have been even worse to maintain.

    • rcxdude 7 days ago

      I think it depends on your level of C++ experience. Very experienced and effective C++ developers often will have internalized a lot of the rules of the borrow checker, possibly without consciously realising it. Less experienced developers will not have run into the problems caused by not following these rules because a lot of the time you can get away with it, and/or they haven't associated these habits with the bugs they tend to cause. It's a fairly common theme for people who have learnt rust to report that it has made them a better C++ developer.

    • ilovecaching 7 days ago

      Personally, I had the same experience as you did, except the borrow checker also helped me unlearn a few bad habits and gave me a deeper understanding of references. Now it is second nature, and I rarely every fight the borrow checker. I think part of it is planning ahead.

    • pjmlp 7 days ago

      Were you trying to write GUI code?

      Because of my experience it was also plain sailing, while doing the tutorials and exercises from the books I bought.

      Then I tried to make a GUI application in Gtk-rs and had lots of fun with event handler callbacks, which are the main reason why Relm was created.

      • epage 7 days ago

        No, I have not written a GUI in Rust yet. I've been doing libraries and CLIs so far.

        But I find the standard approaches to GUI broken: inheritance and shared mutable state. i think Rust does a service by highlighting the brittleness of this pattern via syntax / libraries.

        I've not dealt with elm-like GUIs. Probably my natural inclination would be to use an actor framework. And to be clear, I am speaking from having written non-trivial GUIs with both GTK and Qt (I miss the Maemo days).

  • mrfredward 7 days ago

    >You still have to fight with borrow checking in Rust as in C++, it’s just not automated.

    It's not that easy. The borrow checker gives you memory safety and thread-safety. In C++, you always have to worry about memory safety, so here the ownership model and borrow checker is a pure win. However, in C++ you don't have to worry about thread safety in a single thread...there's no barrier to passing pointers around and mutating things from different places in your code. In rust, the borrowchecker disallows shared mutable state...that's a huge win if you want to parallelize your code later on, but it also means that things that are trivial in C++ take a lot of thought and effort in rust, especially if you're thinking in a C++ paradigm (as opposed to coming from a functional language).

    • shepmaster 7 days ago

      My counter argument is nicely summed up by The Problem With Single-threaded Shared Mutability (https://manishearth.github.io/blog/2015/05/17/the-problem-wi...)

      • mrfredward 7 days ago

        I like the blog post, and I mostly agree with you that shared mutability can cause problems in big programs. It's something I try to keep to a minimum in most code I write, and I'm better at avoiding it after learning rust.

        The thing is, getting rid of shared mutable state entirely is a huge paradigm shift. It means many libraries (GUI libs especially) can't be cleanly wrapped. It means throwing away common data structures like linked-lists. A C++ programmer can learn the syntax of rust is a week, but it may take years to get comfortable with the borrow checker.

        • duneroadrunner 7 days ago

          Yes, It's hard to deny the intuitive appeal, but what's notably missing from that blog post, and seemingly any other article about it, is a consideration of the cost/downsides of universal imposition of the "exclusivity of mutable references" restriction. Rust provides the RefCell wrapper to essentially circumvent the restriction on demand, but i) that also essentially circumvents the "invariant protection" benefits of the policy, and ii) you can just as easily use an equivalent wrapper[1] in C++ to impose the same restriction. At which point the difference between Rust and C++ just kind of becomes which policy do you want to be the zero-overhead default.

          I mean you could imagine a hypothetical future scenario where it is demonstrated that the optimizers are good enough to essentially eliminate the run-time cost of RefCell wrappers, and a lot of Rust programmers just start wrapping everything with RefCells by default.

          [1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus#exclusive-w...

          • shepmaster 7 days ago

            > Rust provides the RefCell wrapper

            There is also `Cell` (https://doc.rust-lang.org/std/cell/struct.Cell.html), which offers a different set of tradeoffs.

            > which policy do you want to be the zero-overhead default

            The one where:

            - The compiler can make more optimizations

            - I'm less likely to shoot myself in the foot my conflicting mutations

            is a good default for me, so I'm in favor of Rust.

            > a hypothetical future scenario where it is demonstrated that the optimizers are good enough

            This sounds like the sufficiently smart compiler (http://wiki.c2.com/?SufficientlySmartCompiler) argument. While I'd love to live in this world, we aren't there yet.

            Even in such a world, there would still be reasons to choose Rust over C, such as standardized dependency management or a rich type system.

            • duneroadrunner 7 days ago

              Oh yeah, there are plenty of reasons to prefer Rust over C++. I think it's also reasonable to favor Rust's "exclusivity of mutable references" default as a matter of personal preference. I'm just not sure the formal or technical argument has yet been made that universally applying that restriction is necessarily the "better" default overall.

        • shepmaster 7 days ago

          > It means throwing away common data structures like linked-lists

          It does not require such; the Rust standard library even has a LinkedList (https://doc.rust-lang.org/std/collections/struct.LinkedList....).

          > A C++ programmer [...] may take years to get comfortable with the borrow checker.

          One of my earliest / biggest revelations when learning Rust went something like:

          - Rust is stupid; I've been writing code like this in C for years, but Rust rejects it.

          - ...time passes...

          - Oh, I understand why Rust rejects this code now.

          - OH MY GOD I'VE BEEN WRITING CODE LIKE THIS IN C FOR YEARS

          A conceptual borrow checker is something that every C and C++ programmer should be running in their head for every line of code that involves references / pointers that they touch. I'm happy to let the automated algorithm provided by Rust do that for me instead.

          • yoklov 6 days ago

            Often when people [0] discuss the difficulty of writing linked lists in Rust compared to C++, they mean intrusive linked lists.

            These are still very difficult in Rust. I've heard pinning being stabilized makes them possible safely, but I haven't looked further.

            [0]: At least, when I was starting Rust, this is what I would mean when I complained about linked lists.

    • htfy96 7 days ago

      Another issue is that in real world types in fast programs usually can't be expressed and auto checked by a simple type system without mental/runtime overhead. For example, in many GPU kernels each thread visits patterns like (ax+b)%k, how do you ensure no data race in this example? The result depends on the coprimality between a and k. You will still need to check this at runtime and creating affine_mod_view for each access patterns like this would be overkill.

  • SamuelAdams 7 days ago

    > Also, Rust is an open source ecosystem, and people using it should feel compelled to consider writing the missing pieces they need for the benifit of the community. It’s also odd to say that Rust doesn’t have what you need, it sounds like there are C libraries that already do what you want, and Rust can wrap C.

    This sounds like a great idea, but not everyone has the time and resources to port libraries from one language to another. It should be trivial to wrap C libraries, but errors do show up, and a once one day task now takes a week to iron out. If you have 4 or 5 libraries that are missing, you've now lost a month of development work that could have been spent adding new features.

    Additionally, not everyone wants to maintain open source projects. There's a huge amount of responsibility that comes with being a maintainer, and the OSS community isn't always a friendly, fun place. Rachel has some great examples in her blog [1].

    [1]: https://rachelbythebay.com/w/2018/10/09/moat/

  • IshKebab 7 days ago

    > You still have to fight with borrow checking in Rust as in C++, it’s just not automated.

    This is so misleading. Sure you still have to think about borrowing in C++ but in C++ you only have to convince yourself that you got it right. You don't have to convince a dumb child that barely understands variable scopes.

    The benefit is of course that the dumb child is 100% reliable so if you can convince him then you are 100% sure you got it right...

    But please can we stop pretending that it isn't a massive pain in the arse to convince the borrow checker that your code is ok.

    Also as someone else pointed out, if you are only writing single threaded code the mutable borrowing rules are needlessly restrictive.

    I like Rust but it really irks me when people pretend it is as easy as C++. It isn't. It is much harder - it's just that when you're done you have (probably) a better result.

    • jamwt 4 days ago

      > I like Rust but it really irks me when people pretend it is as easy as C++. It isn't. It is much harder

      No it's not.

      "hard" is not single dimensional.

      "hard" to write your first hello world? No, both are easy.

      "harder" to write your first moderately-sized program that basically works? Yes, for almost everyone. You'll fight the borrow checker. The learning curve is real.

      "harder" to write your first large/medium, correct program? Definitely not. The safety will save you, here. It's not just memory. It's no nulls, it's no exceptions, pattern matching exhaustion enforcement, baton-passing session type patterns, race-freedom, and so on. The "it compiles, it works" dynamic is akin to OCaml/SML, if you've used those at all. Except it's even better because you get prompt resource finalization.

      "harder" to write your nth program after ~6 months of usage? Not by a long shot. Rust is actually an incredibly expressive language. Once you learn to shape code the way the language expects, you'd be shocked at how productive you are. It's in the same ballpark as go, perhaps a little better if you're doing something nontrivial due to the power of generic libraries.

      I spend almost no time "fighting" the borrow checker, as do most ramped-up Rust programmers. It's pretty much all win at this point. It's a different category of language than C(++). It actually gets a little exhausting hearing people talk about how hard the borrow checker when folks have barely used the language.

      These days, the only time I'll use a GC is if I'm writing something _very_ fast and short in Python. An experiment, a prototype, or a tool. A short REPL session. I really do not miss GCs otherwise.

      But yes, compile times are somewhat slow. If you go template crazy in C++, you'll be in the same ballpark. But the "equivalent" C codebase will smoke it.

jsiepkes 7 days ago

> As the compiler will stop you from borrow checking or something unsafe again and again, you are being distracted constantly by focusing on the language itself instead of the problem you are solving.

While anyone is obviously free to use any language he or she likes the whole article comes across to me as someone arguing why they dont want / need seatbelts: "They constrain my movement, I'm a good driver, etc.".

These are also the same kind of arguments one could make for wanting to use a weakly typed language instead of a strongly typed language.

Personally I like my types strong and my memory safe...

  • htfy96 7 days ago

    There are always trade-offs. I mean when I'm writing really low-level stuffs (e.g., optimizing matrix multiplication kernels) I frequently find type system annoying. In that case I would definitely prefer C/asm, because they are simply closer to bare medals.

  • fulafel 7 days ago

    Strong typing and memory safety are compatible with his wants. It's just that Rust isn't it. Any of Clojure, F#/C#, Python, or Go might be good here. (Ok, the nil-punning might make the strong arguable on Clojure's point... but otoh you have spec)

    • sanxiyn 7 days ago

      I agree. GC is a life saver, and I think if something can be written with GC, it should be.

    • adamnemecek 7 days ago

      Most of those langauges don’t have the perf of rust or cpp.

      • sanxiyn 7 days ago

        Most programs don't need C++ performance. Java is usually within factor of two and usually fast enough.

        • adev_ 7 days ago

          > Most programs don't need C++ performance. Java is usually within factor of two and usually fast enough.

          Meshing software is a typical program where you need C++ and where Java is a terrible choice.

          By nature, meshing makes you play with millions to billions of very small object with mutual interactions. A thing that Java GC absolutely hate. Sorry for the Java fan-boys.

          • fulafel 7 days ago

            The billion vertex objects might be a nice torture test benchmark for a gc or malloc implementation, but fortunately things aren't so grim in the real world:

            Performant mesh manipulation code as a rule deals with largish float arrays (or other similar contiguous layouts, like AoS or SoA or indexed versions thereof). So there are no per-vertex objects to malloc/free or to track in GC.

            In some algorithms, other data structures such as trees, may be used used as intermediate formats, but there too the options to use malloc/gc allocated nodes vs alternatives is similar in a GC'd vs a non-GC'd language.

            In general, good GC's often outperform malloc/free. Because GC's are amenable to parallelization in the background, and because malloc/free don't enjoy the bump-allocator style happy case that is used in generational GC's nursery objects.

            • 0815test 7 days ago

              > and because malloc/free don't enjoy the bump-allocator style happy case that is used in generational GC's nursery objects.

              Performance-optimized use of malloc and free involves using custom suballocators (often called simply "allocators" within user code) which are tailored to the "happy cases" that you know about in your code. A "nursery" of objects that can be bump-allocated and then freed in a single operation is known in this context as an arena/region, and you absolutely can exploit this pattern as part of using malloc/free.

            • gmueckl 7 days ago

              I never met a GC that can deal with millions of allocations per second while having several millions of objects in the young generations. Some mesh processing algorithms have a tendency to get you there very quickly if you do not employ custom allocators. At this point you already defeated the GC provided by the language.

              • fulafel 7 days ago

                You would have to be dealing with a very large number of meshes at once, if you were churning through millions of vertex and uv arrays per second. I can't say what you should use in this scneario. But this is a pretty niche scenario! And you would probably want to focus on parallelism, where C++ again is not the best.

                • adev_ 7 days ago

                  > And you would probably want to focus on parallelism, where C++ again is not the best.

                  Here again, this is wrong.

                  99% of highly scalable parallel code that run on supercomputers is C++ or Fortran.

                  And there is reasons to that, if you want parallelism, you want generally performance. If you want performance you want control on NUMA, SIMD, cache locality, etc... and C++ gives you that. Not Java.

                  • pjmlp 7 days ago

                    Yet Julia and Chapel are winning hearts of HPC researchers.

                    Java is not the only language with GC, there are others which offer control over NUMA, SIMD, cache locality, like .NET Native with C# 7/8, or D as two possible examples.

                    • gmueckl 7 days ago

                      But the GC is frowned upon a lot in the D community. A lot of D programmers try to make everything they write @nogc.

                      • pjmlp 7 days ago

                        A GC in a systems programming language is there as a productivity and safety mechanism, by no means as the only way of doing 100% of memory allocations.

                        A vocal sub-community of D programmers argue for @nogc due to GC phobia, as ex-C++ devs, and a GC implementation found lacking. A situation that might improve with the recently released GC pluggable API and a new precise tracing GC.

                        Many devs that prototype their apps in D without doing premature memory optimizations, end up realizing that for their use case it actually good enough.

                • gmueckl 7 days ago

                  No, I am talking about operations that alter the topology of single large meshes. Just creating a single tesselated sphere with full topological information gets you there easily.

                  • fulafel 7 days ago

                    Ah, we may be talking past each other then. So I reiterate my point from upthread:

                    > Performant mesh manipulation code as a rule deals with largish float arrays (or other similar contiguous layouts, like AoS or SoA or indexed versions thereof). So there are no per-vertex objects to malloc/free or to track in GC.

                    • gmueckl 7 days ago

                      Thia is true only if you have the foresight to write custom allocators. Unless you limit possible mesh topologies, you must deal with many tiny arrays for each vertex, edge and face and their lengths are not uniform.

                      • fulafel 7 days ago

                        Yes, depending on what you mean by custom allocator... but this is the same in C++ too, right?

                        To store custom vertex / face attributes, you can use a variety of sparse techniques to save memory from sitting unused in attribute arrays. Basically you want an interface of get_attribute(type, vertex_id). This sparse matrix, trie, or whatever can be backed by int or float array storage instead of many many tiny malloc'd/gc'd objets.

                        • gmueckl 7 days ago

                          Yes, these backing constructs essentially become special case memory managers for the problem domain. You may call then by different names, but the essential behaviour is the same.

          • gmueckl 7 days ago

            I have to second this. I tried to write a 3d modelling tool in Java. I got decent, but not stellar performance only once I consciously started to fight the GC in my code.

            I converted that code to C++ and recently added a custom allocator to improve performance even further. The result is now functionally equivalent, but about 5 times faster.

        • otabdeveloper2 7 days ago

          > Java is usually within factor of two

          No. That's on synthetic benchmarks. Run a real server and you see that Java shits its pants while a C++ service is running rings around it.

          That's because memory/cache fragmentation and usage is vastly more important in 2019 than CPU cycles.

        • adamnemecek 7 days ago

          Need is relative. If you can get the extra speed, why waste it? Life’s too short to spend it waiting for your computer.

          And in this case, the author does need cpp speed.

          • sanxiyn 7 days ago

            > Need is relative. If you can get the extra speed, why waste it?

            Because you can be a lot more productive if you are not extremely constrained by speed.

            • adamnemecek 7 days ago

              That’s a false dichotomy. A language can be both productive and fast.

              • sanxiyn 7 days ago

                In theory, yes. In practice, Rust at the moment is less productive than GC languages. I am hoping for autoclone mode in the future (sort of like Swift ARC).

          • fulafel 7 days ago

            I think the article didn't say anything about performance requirements.

            The app is Dust3D, a ease-of-use focused mesh editor which deals with simple meshes.

            Certainly from the blog post you get the impression that programmer productivity is a consideration in his choice of language.

            • gmueckl 7 days ago

              3d modelling is a problem domain where performance is the most important feature. Without sufficient performance, the tool.is not interactive. And direct interaction with immediate visual feedback is the whole point of these programs.

              • fulafel 7 days ago

                Having worked in 3D, including tools, it's my experience that features and productivity (=program is delivered on time) are the most important features :)

                The code needs to be "fast enough"¹. Though this often means more attention to speed than in other kinds of software. To rephrase, speed is often necessary but not sufficient to make good tools.

                ¹ I try to avoid using "execution speed" and "performance" interchangeably, since a crashing, late or incorrect fast program is not a well performing program!

                • gmueckl 7 days ago

                  Fair point. Let me rephrase my point of view a little: you haven't made the users truely productive unless the tools are able to provide responsive and accurate interactive feedback. Anything that causes feedback to be non-immediate makes it harder for the user to dial in the exact results they want. They have to spend more time and give up when they have reached an inferior result that meets basic quality standards. Smooth and direct interaction makes them go the extra mile while enjoying the process.

gmueckl 7 days ago

Doing game dev and digital content creation in anything but C++ and some python is simply a fool's errand. Any decent software in this area needs to use libraries written in C++ to have even a remote chance of being successful. These libraries are often written in ways that makes wrapping them for other languages impossible or at least force the exclusion of some desirable features in the bindings.

In other words, C++ is utterly entrenched in that space like Fortran is for HPC.

  • est31 7 days ago

    Unity, one of the most popular engines out there, is mainly about C# for the gamedevs.

    • gmueckl 7 days ago

      And it is a special snowflake because of that. Unity needs to pour a ton of resources into this to make it viable and competitive. IL2CPP and the Burst compiler are proof. A company with fewer resources would have to give up on this approach.

      • pjmlp 7 days ago

        The same was said about the game developers using Pascal and C instead of Assembly, followed by game developers using C++ instead of C.

        The industry always needs some pioniers willing to do the investment regardless of the naysayers.

        • mewse 7 days ago

          Note that the game industry avoided C++ for a long time because those early C++ compilers produced code which was very large and quite a lot slower than you'd get from C, so C++ was kind of a non-starter when you were writing code for the consoles of the day which had slow processors and only a few megabytes of RAM. You just couldn't afford the overheads of C++ or your competitors would eat your lunch.

          It wasn't about needing a pioneer to show us that we'd been wrong; we weren't wrong. C++ just wasn't ready for the particular set of requirements that games imposed, yet. Once the state of C++ compilers began dramatically improving in the late 90s (by the criteria of optimisation and executable sizes), most studios moved over to the language pretty quick. Or at least that was my experience.

          • pjmlp 7 days ago

            The pioneers were the studios using Watcom C++ on MS-DOS, while others were still being dragged into Windows with plain old C, while complaining about losing hardware access until Wing was released.

            And the studios that were forced to adopt C++ when the PlayStation SDK required it.

            So nothing speaks against other languages getting over the same kind of acceptance issues.

        • gmueckl 7 days ago

          I am not a naysayer. I just point out the resource investment involved in going down a different path.

          Also, Unity is built on a lot of 3rd party C++ code. From the top of my head, this is at least Mono, FMOD, PhysX, Enlighten and FBX.

          • pjmlp 7 days ago

            Sure, just like those C and C++ engines weren't re-writing the battle proven Assembly libraries unless required to do so.

      • jayd16 7 days ago

        Mono runs fine. IL2CPP is more of a work around to get AOT on iOS and Burst is just a nice linter but you could write the same tight loops now and mostly likely get very close. Plus, Burst isn't even out so its odd to bring it up as necessary.

        • gmueckl 7 days ago

          Unity makes it very clear in their blog posts that Burst is a special vectorizing compiler. It is not a linter at all. I am not sure where you got that notion.

          IL2CPP was required to be able to stick with C# and stay relevant for mobile gaming. They forced themselves into this corner by wanting to stay with C# and become relevant for mobile gaming.

          Compare all this to Unreal. By sticking to C++, they do not have to commit the same amount of resources to programming language related tooling.

          • jayd16 7 days ago

            Burst is basically an upgrade to Roslyn with some perf warnings set to errors.

            IL2CPP is literally required on iOS but the perf gain you get on Android was never very good. Because of its general instability, a lot of games just ship in mono mode.

            It's funny that you're saying both Burst and IL2CPP are required. Can't you see that Burst is an admission that IL2CPP wasn't the way to go?

          • pjmlp 7 days ago

            Actually they do, because Blueprints need to support graphical debugging and profiling as well.

            Some studios don't want to mess that much with Unreal's C++.

            Then Unreal has their own C++ runtime to allow for a tracing GC.

            • gmueckl 7 days ago

              Still, Epic does not have to commit the same amount of resources. That is my point. The Unreal Build Tool and Unreal Header Tool do not come for free, but this is still less than two sets of optimizing compilers in my book.

              • pjmlp 7 days ago

                IL2CPP resuses the platform C++ compiler, and Burst builds up on LLVM.

                It is not like Unity is building their compilers from scratch.

                And the fact that the Insomiatic guys felt it was a good project speaks for it, given how they are respected in the gaming industry regarding engine optimization.

                Also some of this work influenced C# 7.x features.

  • jayd16 7 days ago

    The first non Unity non Unreal game I thought of, Celeste, uses C# and XNA. Lots of games use other languages these days.

    • gmueckl 7 days ago

      XNA is dead. Microsoft officially recommends MonoGame instead.

      When a game seems to be written exclusively in a high level language like C# then there is almost always a massive framework underneath that integrates a lot of shiny C and C++ libraries for the real heavy lifting.

      • pjmlp 7 days ago

        Time travel 20 years back on some USENET forum.

        "When a game seems to be written exclusively in a high level language like C++ then there is almost always a massive framework underneath that integrates a lot of shiny C and Assembly libraries for the real heavy lifting."

        Time travel 30 years back on some BBS forum.

        "When a game seems to be written exclusively in a high level language like C or Pascal then there is almost always a massive framework underneath that integrates a lot of shiny Assembly libraries for the real heavy lifting."

        • gmueckl 7 days ago

          Except that games back then were limited in code size by what could be stored in memory on the target systems. All the game code that I have seen from the 80s and early 90s came in well under 100kloc and library dependencies weren't a thing because of the same resource constraints. This changed over time and now almost any contemporary and technically decent game sits on top of several hundreds of thousands or millions of lines of 3rd party code.

          • pjmlp 7 days ago

            Sure and that 3rd party code can be written in whatever language the library authors feel like using, it doesn't need to be necessarly C or C++.

  • alfalfasprout 7 days ago

    FWIW at least for a lot of major libraries in HPC now have C/C++ wrappers (eg; IMSL). But yeah, while it is possible to write rust wrappers for everything it's just not something you're going to do most of the time.

    Modern C++ is "good enough" where you'll potentially end up with some unsafe code but unless you're writing an SSL library it'll be OK.

sanxiyn 7 days ago

"As the compiler will stop you from borrow checking or something unsafe again and again, you are being distracted constantly by focusing on the language itself instead of the problem you are solving."

This is very much true while learning, and very much not true once you finished learning. It would be very concerning indeed if it were otherwise. As is, it is very concerning for Rust adoption, as this post evidences.

JabavuAdams 7 days ago

This is why I gave up on Haskell. Code is still (currently) written by humans. Sure the code was more terse, but I had to expend more time thinking about every tiny piece of that terse code. I've been programming for 36 years. Just as some people think out loud, I think by shaping and reshaping code. Top-down doesn't work for me, although I know there are other developers for whom it does. I like to build bottom-up by fooling around with little pieces. I have no experience with Rust, but fooling around in Haskell just took all the joy out of programming, for me, while adding frustration.

EDIT> I would rather have better CASE tools / an AI pair-programmer than be straitjacketed into a top-down correct-first then code way of working.

  • sjcoles 7 days ago

    Even with a top down approach you can end up with insane type level machinations or group/category theory that only the best Haskell developer can decode. Sure it's elegant, but damn near indecipherable.

gcc_programmer 7 days ago

I wonder how many of the Rust defenders in this article actually know C++ and have written a production used Rust system, instead of a side-project on github, so that they can compare in an informed way? The author certainly has, but who else has? Step forth priests of Rust! As for me: I use C++ at my job daily but have never done Rust so I cannot compare. What I do know about is "memory safety" in C++, and to be honest, the tools available are enough to make you figure out any issue: gdb/core dumps/valgrind, when combined with good software practices and unit tests seem to work ok for the rest of us. The compilers now have sanitizers, and new versions of gcc actually tell you what your template errors are. It's 2019, not 2005 for C++. Smart pointers are now available: use them! Finally, if a Rust veteran could let me know: how does Rust deal with general resource management in the presence of exceptions? Not everything a program uses is memory: we sometimes need sockets! In C++ using RAII works well, does the Rust Type System statically error/type check non-memory resources automatically, or is that out of scope?

  • ekidd 7 days ago

    > I wonder how many of the Rust defenders in this article actually know C++ and have written a production used Rust system, instead of a side-project on github, so that they can compare in an informed way? The author certainly has, but who else has?

    Hello. :-) I started writing C++ around 1992, and was lead programmer on various C++ production systems from 2002 until 2011. I worked with valgrind, unit tests, and boost/std::tr1 C++, but not C++14 or 17.

    For the past three years, I've been writing production systems in Rust. Here are some things I've observed:

    - If your C++ code relies heavily on complicated webs of objects that all mutate each other (as found in many game and GUI designs), you'll have a bad time translating that code to Rust. If your C++ code tends to be more functional, idempotent, or transaction-based, and if it has clear ownership of objects, then translating to Rust will be much easier. For example, Rust seems to work better with ECS-based games and React-like GUIs.

    - Rust is significantly weaker than C++ for designs which use integer template parameters (e.g., "vec<3>") or partial template specialization.

    - Modern C++ allows you get ownership 99% correct, if you throw enough tools at it. Rust gets ownership 100% correct by default. If you're dealing with situations where that 1% matters (complex threading, or decoding hostile data), then it's a much bigger difference than you might think.

    - Not counting Rust IDEs (which are only borderline OK by static language standards), Rust tooling is great. Dependency management is solid, linting is good, automatic formatting is good, etc.

    - I've been working with nightly and experimental builds of Rust async code, and I think that Rust will soon give C++ a real run for its money in this space. Multithreaded async executors (where you mix "green" threads with OS threads) rely very heavily on precise tracking of who's allowed to mutate what, which Rust is excellent at.

    > Finally, if a Rust veteran could let me know: how does Rust deal with general resource management in the presence of exceptions?

    Rust does not have exceptions. Instead, it uses `Result<T,E>` and the `?` operator to propagate errors. Ownership and RAII are 100% idiomatic and fully checked by the same systems as memory management.

    • happyweasel 7 days ago

      > If your C++ code tends to be more functional, idempotent, >or transaction-based, and if it has clear ownership of >objects, then translating to Rust will be much easier

      That's exactly the kind of c++ code you probably don't have to refactor/move to another language at all

  • sanxiyn 7 days ago

    I can. I (well, it's the team effort, so we) rewrote production system written in C++ with Rust. Even before the rewrite, C++ codebase was in modern C++17.

    Re: general resource management. It works exactly the same. Rust also does RAII. Rust also doesn't use exceptions for error handling.

    One easy to state advantage of Rust over C++ is that it checks your threading design.

  • arcticbull 7 days ago

    Rust memory management is just RAII, and there are no exceptions, just nice Result types and syntax that makes returning them and handling error cases simple and pleasant.

    If you want to handle closing a socket, it’s as easy as implementing the Drop trait on your type. Without an unsafe block there’s no way your destructor won’t be called.

    struct Socket(u16);

    impl Drop for Socket {...}

    To answer your question there’s no special casing around memory vs non-memory resources. Your socket is backed by a kernel ID which must exist in memory, of course, so by adding a Drop implementation you can then define the special treatment yourself. If threading considerations exist you can explore the Sync and Send marker traits too.

    It’s largely a much simpler language than C++, you just have to learn how to write it. A lot of the friction/confusion IMO is that it looks so similar to languages you use at first glance you just start writing the code you used to in a Rust-y way, instead of Rust, then are frustrated as to why it won’t build.

    In some ways it’d be clearer if it looked “foreign” like prolog — it’d be a lot less popular though haha.

    • 0815test 7 days ago

      > ...Without an unsafe block there’s no way your destructor won’t be called.

      Unfortunately, this is not correct. Resource "leaks", involving failure to drop a resource which is no longer in use, are possible in Rust, and the borrow-checker won't protect against them. They're most likely very rare in idiomatic Rust (the case I know about has to do with RC-cycles) but they're possible.

      • CDSlice 7 days ago

        You can also use the (safe!) function std::mem::forget

        > forget is not marked as unsafe, because Rust's safety guarantees do not include a guarantee that destructors will always run. For example, a program can create a reference cycle using Rc, or call process::exit to exit without running destructors. Thus, allowing mem::forget from safe code does not fundamentally change Rust's safety guarantees. ... Because forgetting a value is allowed, any unsafe code you write must allow for this possibility. You cannot return a value and expect that the caller will necessarily run the value's destructor.

        https://doc.rust-lang.org/std/mem/fn.forget.html

bsder 7 days ago

One thing that I don't see pointed out is that Rust is a nightmare if you are dependent upon mutable algorithms.

I suspect that mesh generation is very much a mutable algorithm domain and probably a high impedance mismatch with Rust.

For example, simple things like mapping a struct of three elements to a vector of three elements were, at one point, very difficult if not impossible in Rust.

dvnguyen 7 days ago

My hypothesis is a software growth, like a business or an economy, is fueled by debt. We create technical debts, both deliberately and accidentally, to write software faster. And when the software proves itself as a viable project, we could (ideally) start paying the debt.

Rust forces users pay certain kinds of debt upfront that makes Rust attractive for rewriting, but I don't think it's that much attractive for greenfield projects. You'd want to fight your problems, not your problems plus Rust. On top of my head right now I couldn't think of any famous Rust projects which aren't a rewrite.

Personally I don't think Rust is that hard to learn and some of my side projects are being written in Rust. But if I ever had a business with Rust as a main language, I'd be worry I could find enough Rust programmers. Fortunately the community is addressing its ergonomics and hopefully one day its approachability and learning curve will also gain more attention.

  • adamnemecek 7 days ago

    > On top of my head right now I couldn't think of any famous Rust projects which aren't a rewrite.

    Wut? Piston, actix, Amazon Firecracker, Alacritty, Xi, the list goes on.

Dowwie 7 days ago

One day, social anthropologists will read these Hacker News message forums to learn about tribal warfare among programmers. What will they say, considering their entire new world was based on Rust?

Kidding. Stop fighting, people. You're all on the same team.

  • Verdex 7 days ago

    My theory is that there are two basic ways of understanding the world around you and solving problems. Statistically and structurally.

    Everyone can do statistical problem solving. At least everyone who can talk. What you do is that you start making sounds when you're an infant and then you receive positive or negative feedback. This continues until suddenly you know how to talk.

    Similarly, in industrial chicken raising you need to differentiate between male and female chicks right after they're born. However, there isn't any guide to determine the difference. Instead what you do is that you take one person who knows how to do it and pair them with someone who doesn't know how to do it. The person who doesn't know how to do it will guess at the sex of the chick and they will be corrected by the person who does know how to do it. After enough time you have two people who know how to do it.

    Sounding familiar yet?

    Most people learn programming languages in a statistical fashion. They try a bunch of stuff and get positive or negative results (compile fails, runtime errors, etc). However, just like determining whether a chick is a male or female in the chicken raising industry, nobody can really give you the specification of how to program. All they can do is tell you that you are doing it wrong or doing it right for any given scenario.

    Now of course there are problems with the statistical method (also benefits, but we're interested in failure right now). 1) You can't say why you're right [in order to do that you have to sit down an analyze what you've been doing in a structural fashion]. 2) The only teaching method you know involves telling people they're wrong when your gut tells you they're wrong. 3) You'll have a terrible intuition for any situation that only causes a failure after a period of time or some of the time (think undefined behavior in C).

    If you have only learned programming statistically and haven't sat down and reflected on what the structure of what you're doing actually is, then when you are faced with information that is contrary to what you know your natural reaction is going to be to listen to your gut (even if your gut is wrong) and provide the same negative response that you got when you were first learning.

    Additionally, the only "reasons" that you'll be able to give are paper thin metaphors and thought terminating cliches that don't stand up to even the smallest amount of examination.

    The end result? You get a bunch of programmers that freak out every time a new language comes out.

nnq 7 days ago

...hasn't Swift become a viable alternative in this space by now? I see it's getting used in ML a bit, and looks nicer than D and easier to learn than Rust.

  • pjmlp 7 days ago

    Just like Objective-C, Swift is mostly a thing on Apple platforms.

  • nazka 7 days ago

    What's really missing in Swift it's all the multithread tools you can have with Rust like channels, MPMC... Anything from the "Fearless Concurrency". Personally I will love to see that happening for Swift to be able to really use it for the backend.

  • adamnemecek 7 days ago

    Swift is somewhat higher level than Rust. You don't think much about allocations in Swift, whereas Rust is DSL for reasoning about allocations.

fooker 7 days ago

Yeah, Rust seems to have an ergonomics problem and the only response we are seeing is "you're holding it wrong".

I would rather work on interesting projects than use interesting tools for not-so-interesting projects. So far, for things I am interested in, C++ seems to be the tool of choice.

  • steveklabnik 7 days ago

    > the only response we are seeing is "you're holding it wrong".

    We had such a huge push last year for ergonomics that there's a segment of the community that's still upset about it. We're very interested in improving them; if you have good ideas about it, you'll get heard out.

    • fooker 7 days ago

      Can you point me to a document listing the changes from this effort?

      • steveklabnik 7 days ago

        Probably the closest is https://blog.rust-lang.org/2017/03/02/lang-ergonomics.html, which laid out the plans to do so. That being said, there wasn’t a single real document I can point you to: it was a label attached to a number of RFCs, and not really tracked as one thing. Some stuff that ended up landing under this banner was:

        Non-lexical lifetimes

        “Match ergonomics”

        Implied lifetime bounds

        The anonymous lifetime

        The question mark operator

        Async/await (this one is still in progress)

        The removal of “extern crate”

        ... and some other things I’m sure I’ve forgotten. I also said “last year” but that blog post is from 2017, and that’s because it took a long time for RFCs to be created, accepted, implemented, and stabilized; a lot of this stuff landed in the latter half of last year, though some before then too.

adamnemecek 7 days ago

"As the compiler will stop you from borrow checking or something unsafe again and again, you are being distracted constantly by focusing on the language itself instead of the problem you are solving. I know the friction is greater because I am still a Rust learner, not a veteran, but I think this experience stops a lot of new comers, speaking as someone who already conquered the uncomfortable syntax of Rust, coming from a C/C++ background."

To be honest, this article seems somewhat ingenuous. The author wasn't comfortable with Rust, and it seems like he missed the point of the borrow checker. This article will now be circulated whenever Rust is discussed.

Here is a good article that arrives at the opposite conclusion: https://kyren.github.io/2018/09/14/rustconf-talk.html

I've been writing Rust full time for the last month and a half or so and the language is a joy to use. The main difference is that the code I write feels very sturdy and permanent. I've heard other people say the same thing.

  • nraynaud 7 days ago

    XML didn't work? use more XML. Everybody has a breaking point, and they reached theirs.

    I have been studying rust for embedded since January and I am not really impressed by what I have seen. I am mostly hacking around the deficiencies of the libraries, the crazy organisation of the stack, and the issues with the community.

    I am sticking with rust for now because I feel like there is a bandwagon and there might eventually be money in it, but I am certainly not a convert.

    • adamnemecek 7 days ago

      > XML didn't work? use more XML. Everybody has a breaking point, and they reached theirs.

      This argument could be applied to anything.

      What's crazy about Rust stack organization? What are the issues with the community?

      • sanxiyn 7 days ago

        There are lots of issues with using Rust for embedded development, most of them long standing, which are often felt to be neglected, and some suspicion that progress is slow because it is not the highest priority for decision-making people. https://github.com/rust-embedded/wg/issues/64 details some of these technical issues. Personally issues with Cargo are the most pressing, and math/compiler_builtins is very annoying.

      • nraynaud 7 days ago

        Basically you have some kind of hierarchy of crates according to the abstraction level, and those crates are owned by some loose organisation.

        The trick is that the those crates are new and there is only very few MCU features exposed in them (and modern MCUs are so "big" that there is no real hope to get out of the situation quickly), so when you're doing a project, you either have to send a PR upstream and have it die there immediately or argue for days before it dies, or you have to fork the crate yourself. I couldn't find a way to add code in the namespace of a crate without actually re-compiling it.

        It was extremely naive to split the crates horizontally and have only a limited group of people able to access the register they want to use, and not expose some kind of extension mechanism.

        some examples: STM32F103 doesn't expose DMA, there is no provision for async SPI, no provision for changing the speed of any communication device (nor any bus for that matter). Which we could attribute to the thing being new, but drivers are already being written in such a way that thing are getting calcified like that, and the task of exposing all the functions of the MCU in rust is infinite, it has to be open to outsiders and that involve having a different slicing of API, and always making sure that from any configuration we can call release().

peatmoss 6 days ago

As someone who never learned C++, I keep hearing about how today’s C++ is much better than the C++ of a few years ago. Can anyone recommend a resource for learning some C++ basics using today’s modern C++?

galooga 7 days ago

but rust is supposed to make everything better? surely this is just conservative propaganda?

Vogtinator 7 days ago

Rust is still completely unusable as you can't use dynamic linking as there's no stable ABI.

  • sanxiyn 7 days ago

    Rust supports stable ABI with extern C. I agree it is highly suboptimal, but it works well enough that there are multiple production Redis modules entirely written in Rust, for example.

  • adamnemecek 7 days ago

    You can use dynamic linking but you have to recompile.

  • galooga 7 days ago

    rust is trash but the kind of person who puts stickers on a laptop thinks it's a good thing, so hey let's drop C++ for it.

alexnewman 7 days ago

I was a fan of rust when it first started. i wrote some consensus algorithms and metrics packages in rust. i also hosted a rust podcast. I now believe Rust has failed. Mostly because of the arrogance of organizations like the rust community and the inability to form stronger relationships with companies like apple. I now think that people should focus on swift and soon it will have the same native code support and a borrow checker. I think we all learned a lot but it’s time to realize people still don’t understand why not go and swift. C programmers continue to prefer c and more and more people are shifting back from rust to c++. rust will never provide enough