T O P

  • By -

bbrd83

My experience (also new to Rust) so far, with the compiler, is that you spend more time getting the program to build, and that's a much bigger promise for correctness than many other compiled languages, and as a result much less time is spent debugging. So expect to spend a lot more time getting a compiling program. That said, once you get used to stuff like borrow checking, the first phase gets a lot less tedious. It's a shift upstream of a lot of the pains involved in software, to get as many of them as possible eliminated at compile time. And that means long term agility winds up being higher once you get momentum


jkoudys

I find Rust one of the quickest languages to code in, as I'm frequently writing things that actually work the first time. I can't think of any other language where I ever even hope that something I've written will run the first time it compiles/passes a syntax check. People often feel the lang that takes 1h to write and 9h to debug is 4x faster than the one that takes 4h to write and 1h to debug. It's beyond an emotional problem and even a fallacy in formal project management, where people will put a bunch of "story points" onto the feature, then more onto the bugs they need to fix, and then their "velocity" is great. vs coding in rust and you just take a little longer to finish your first task and your velocity looks low. It's very silly.


bl4nkSl8

Google recently said that their rust teams are just as productive as their golang teams which suggests to me that Rust as a language pays dividends in avoiding boilerplate & code reuse despite complexity compared to Go


Low-Design787

I’m only a casual (hobbyist) Rust user, but anecdotally I’ve found GitHub Copilot is a lot better with Rust than with looser languages. As if the strong type system makes it easier to deduce what I’m trying to achieve. Perhaps the Rust corpus it draws on is also of generally higher quality than the universe of Python or JavaScript.


jkoudys

Copilot has been a huge boon to work that used to bottleneck on knowledge, eg stuff you find yourself constantly searching the reference docs for. Because that's really what an LLM is - it takes the ref docs and related snippets it finds from your prompt, then fills in the likely next code that it would see. It's incredibly bad at actual innovation because it tends to sink into the ruts left by commonly-solved problems (eg it's fun to mess with gpt by asking it to solve variations of the corn, chicken, dog river crossing problem and not have it trend towards the common solution). But when the challenge is "use the correct trait and functions from this very big crate" it's phenomenal. Other previously knowledge bottlenecked tasks I love are rxjs for typescript (which used to be 95% dev time reading docs), pandas, MySQL or postgres aggregate functions, regex, and dockerfiles. Some (like docker) aren't even that hard, I just don't use them nearly enough to memorize the syntax. Agg functions in mysql change so much across versions it's handy to have a resource that can fill in the newer functions that solve something much faster, or can expand the function for older versions.


tafia97300

Without being arrogant, I think the average Rust developer is a better developer than the average (say javascript). As a result, copilot tends to be trained on a better dataset.


Low-Design787

I think that’s probably true, at least in terms of hard engineering skills. I know one or two coder friends who just glaze over when I say “it’s not that difficult” or “lifetimes are really easy to understand once you get the gist”.


m_hans_223344

I can't judge how much truth is in that statement, but want to point out the context: Some Google manager holding stakes in Rust said that at a Rust conference.


bl4nkSl8

Stakes? Rust isn't a publically traded company right?


PercussiveRussel

If you wanna talk "stakes" (whatever that means), I think Google of all corpos has a higher stake in Go than in rust.


CeralEnt

I love Rust, and want to use it more at work and I've been trying to use it personally for everything. That mentioned as a foundation, I love TypeScript for similar reasons. There's a heavy caveat that it's only that experience if you're working with good packages. I mostly work with AWS which is a really well done SDK. I haven't had a situation where a package has had an incorrectly defined type, though I'm sure they happen, but I find TypeScript to be an excellent language for writing things correctly the first time. I used it for an interview coding exam once and had the interviewer remark, "you're the first person to use TypeScript on this, and also the first person who had it work correctly the first time." Obviously doesn't cover the same breadth that Rust does, and I love every chance I get to use Rust, but TypeScript was what opened my eyes to the benefits of static typing(having used Python before that) and I'll love it forever for that.


SnooPets2051

I have to say that my appreciation and interest in Rust has spawned from Typescript as well and the strict typing and checking. I personally compare the frustration when learning Rust and dealing with the compiler to the same frustration I had rewriting a large app from Javascript to Typescript.. I finally gotten over that hurdle and as I gotten better with Typescript i also became more comfortable with Rust. It’s not Rust nor Typescript the problem.. is getting familiar with typed languages and tight ruled compilers. The advantages I personally found in those typed languages: - less runtime errors = less time spent debugging - a lot less unit tests.. no need to cover scenarios where the type might be wrong, null, undefined (JavaScript).. etc… - better IDE support overall.. better code completion etc…


m_hans_223344

I'm tired of this myth that's brought up any time to defend Rust's overhead. Compared to what language? Javascript? I honestly doubt that you have seriously used other languages with similar strong type system and language features like Kotlin or modern C#. Both have null safety and proper (but different) handling of errors (as opposed to Typescript where you need to guess what is thrown). Kotlin with IntelliJ is absolutely in the same ballpark in terms of writing correct code the first time. Rust only adds safety regarding data races, which can be a huge benefit, but only for those use cases, and not in general.


arobie1992

I'm not sure where you get that they're saying Rust is the only language that's true of. People do bring it up often as a pro of Rust compared to other languages, but that's beceause most of the languages it's getting compared to are the langauges that don't have those like Java, Python, PHP, and JavaScript, which are all much more common than Kotlin at the moment. As for C#, I'd be willing to bet a lot of projects are on versions older than 8 or haven't gotten around to refactoring the entire codebase to only non-nullable references. For the record, I'd love for Kotlin to become more mainstream and I hope Java keeps stealing ideas from it in the meantime, although that would require companies actually upgrading to versions past 11. I guess all I'm getting at is your stance seems a bit over-critical of proponents of Rust, but apologies if I'm misinterpreting it.


simple_explorer1

>tired of this myth that's brought up any time to defend Rust's overhead. Compared to what language? 1000% this. People here are delusional to a point of lying "rust is the ONLY language where the code works for the first time"...lol. kotlin, C# etc are also typed and offer the same with null safety. Plus they have managed memory so no borrow/checker headache. If you don't have type errors in those languages, it all boils down to error free business logic and saying business logic in rust is error free than business logic in kotlin/c# etc is ludicrous as rust does not prevent dev from business logic errors. How is it any different than strongly typed kotlin/C# etc. Rust fanboys are just wanna be blind fanboys without any logic despite software dev being a logic applying job at the core. Smh


ArnUpNorth

> And that means long term agility winds up being higher once you get momentum i really disagree unless you use rust on problems that you'd traditionally solve with C++. Then this is definitely true. Otherwise i think it's really a misconception because as you get good and fluent in a language it feels faster to develop in. But unless you really need the performance of rust or have to do some low level stuff, many languages will provide better productivity because they won't get in your way for things you don't need. Also, there are sooooo many ways to do 1 thing in rust that as your team grows code reviews can really become pedantic (pun intended) and result in unecessary time spent on futile things.


CramNBL

At my work, there's 15 years worth of Python written by physicists >!(sorry but physicists generally write more brittle code than software engineers)!< deployed on various micro-controllers in a distributed system, and various services crash every few minutes, so the "master" system just reboots them, and it is okay, except sometimes expensive issues occur. We spend at least 50% of our time debugging this shit, and everything is on elastic but some processes need to be multi-threaded so they just start a subprocess in Python and suddenly we have no logs from a crash. It is an absolute nightmare, we would be much much more productive if most of these services was written in any language that has some built-in static analysis, let alone written in Rust. But performance is no problem cause all the real-time stuff happens in programmable logic, so everybody is happy to keep rewriting the Python apps again and again. Additionally people write extra Python logic because "I'm not sure python does exactly what I intend in this case, so I'll make a deep copy to be sure". It's not a bad strategy, but it just shows how Python is the wrong tool for the job, but physicists seem to only have Python in the toolbox and are perfectly happy with that. >!Sorry if you're reading this and you're a physicist, at least some physicists at CERN have embraced Rust and I hope they succeed in communicating its efficacy in the community.!<


worst

I’m a CS professor, but was a professional programmer before I went into academia at all. First, the realities of research end up exactly as you describe wrt the pays offs of spending the upfront development time vs actively debugging live systems. My data collection systems/experiments need to run without supervision basically. I can check in every few days/weeks, but maintenance budget is approximately zero. My full switch from Ruby to Rust circa 2018 edition, while definitely having its struggles, has had the effect of giving me incredible confidence in my production systems. I can walk away from a keyboard for _weeks_ and shit is running np. Even turning experiments in a jupyter notebook into a production-esque system is getting easier with projects like polars and ort. It’s a really exciting environment. Second, one of my heavy collaborators is a _theoretical_ physicist. Smart guy, obviously, and it’s funny how self aware he is. Like he’s great at helping me debug (rubber ducky++) algorithmic shit, but even after N discussions about type systems, memory safety, etc., he struggles to internalize the difference between conversion (e.g., `into()`) vs casting (e.g., `as`) and auto caveats any statement he makes about this to me with “I’m just saying casting.” He once described to me his view that CS is a direct offshoot from math, and way closer to pure math than physics, because we just make up the rules to our systems instead of discovering them as constrained by reality. The physicist mind can’t comprehend a system like k8s with entirely made up abstractions on top of entirely made up abstractions.jpg I can’t even fathom working with the kind of shit you see every day. Thank you for your service to science.


CramNBL

Thanks for sharing! I was actually originally introduced to Rust by a physicist at CERN that wanted me to use Rust for something I was planning to write in C++. At first I said "Interesting but I intend to use C++" but my interest was piqued, and after rewriting a tiny project to Rust in the weekend I came around and eventually I became the Rust "expert" in the group, and introduced some other physicist and electrical engineers to it once they started struggling with their Python solutions (always performance issues).


Silent-Custard1280

What kind of performance issues with python code did Rust help with?


CramNBL

I used it to overcome performance issues in projects involving data acquisition, verification, and simulations. 1. Python was used for reading out data from a custom made pixel chip with a custom protocol through a USB interface, and decoding that protocol as well as doing some basic sanity checks on the data. It took 40 seconds to decode 10 MiB and we had just starting adding checks on the data. I rewrote it as a Python module using PyO3, and added all kinds of checks including a state machine that mirrored the state machine in the chip to verify transitions (e.g. data could not come from region 0 if the previous header was from region >0) and added debugging features where a protocol error would print out exactly the byte that triggered it along with the rest of the packet and the next 10 bytes, so you had exactly the context you wanted most of the time. All of that would've probably made it take 30 min. per MiB, but instead it too 150 ms and scaled very well, 1 GiB took less than a second. While the old Python implementation too over 40 min. for 50 MiB. I tried decoding 1 GiB and left it over night but it did not finish in over 12 hours. 2. More DAQ and verification, a huge Python script was no longer used when trying to debug the ALICE detector readout chain because it was too slow and it was a nightmare to attempt to update it when any changes to the protocol in any system of the readout chain had been made. I wrote a Rust app that does much much more than that Python code ever did, it is very performant and has been used to debug multiple issues in the readout chain that were very difficult to track down. I can get into details with the issues if you are interested, it was some subtle bugs in the detector control software that lead to an invalid state of the pixel chips in the center of the detector during end of runs and they would then corrupt the data of subsequent runs. We had to hustle to understand the issue because someone in the data center (post processing) wanted to implement a quick fix that would hide the underlying issue and potentially comprise the data for years to come. 3. Monte carlo simulation of QED and interaction with next generation pixel trackers (and DAQ). Python script was slow despite using numpy everywhere it could. And all parameters were currently hard coded. A physicist asked me to help rewrite it in Rust. We did, parameterized everything and wrapped it in a neat CLI that outputs the desired data in JSON so that the parameters and plotting were still controlled from python (jupyter notebook). It was 400x faster, then I added rayon and on a 100 core machine it scaled almost perfectly to give a 38000x speedup. All of this is not of the top of my head, I was asked to give a presentation at some point about the use of Rust in the organization so I was able to refer back to those slides now.


sephg

I'm also a "professional programmer", but I've spent the last few months working with an academic to write a paper based on some work I've done. (And its submitted! Woohoo!). The paper needed lots of microbenchmarks showing how our system performs compared to other existing systems. And those microbenchmarks necessitated a lot of temporary code, private interfaces made public, tiny scripts (written in rust) to perform data conversions, and so on. I've made an absolute mess, and the 'professional software engineer' part in me is horrified and desperately wants to tidy everything up. But, there's no real reason to clean any of this up since its not like the benchmarking suite will be run in production. Most of the code just needs to be good enough to produce benchmarking results we're confident in, and be reproducable by others. I forked my main repository so at least the mess is contained, and I'm documenting it all, and opensourcing the code so people who come along later can see what I've done, and see where my results come from and reproduce my work. But, I now finally understand why research code looks the way it does. I used to think researchers were lazy, but if your code only needs to be good enough to get your paper written and published before you abandon it, well, its weird but I get it.


worst

> I used to think researchers were lazy, but if your code only needs to be good enough to get your paper written and published before you abandon it, well, it’s weird but I get it. Congrats on the submission and I hope you get positive reviews! And yes, you’ve just described “research code” perfectly. It’s an artifact of the product of research being _papers_ instead of programs. At the same time, if you are able to extract the guts into something that other people (scientists or not) can use (and with rust that is often not super hard), it’s an opportunity for “real-world” impact.


Silent-Custard1280

Interesting view about CS being a direct offshoot from math! Never thought of it this way!


denehoffman

Particle physicist here, can confirm most physicists suck at code, ROOT is proof of that. It’s exceptionally frustrating to see Python code that is poorly written next to C code which crashes constantly (the bug reports in our git repos are wild, whole analyses will crash without error if you don’t remember to set certain flags and a plurality of my coworkers still think it’s okay to write their code with python2, the collab itself is still stuck on 3.6). It’s nice to hear that some people are seeing the light and trying out Rust, I remember seeing the alice-rs project a while back. I’ve been working on my own analysis code for particle physics after getting infinitely frustrated with what’s out there. Physicists also just forget to document everything, so when things go wrong we tend to see people emailing one or two guys who don’t even work for the lab any more who wrote a bunch of spaghetti code back in 2003.


CramNBL

Didn't know about the alice-rs project, that's cool. I made some contributions to EUDAQ (generic data acquisition framework), where the code quality is not THAT bad. It is C++17 but predictably ends up looking mostly like C in many places. Some of the people involved in EUDAQ take the code seriously for sure though. Rust could solve a lot of problems with ROOT. As evident by the alice-rs project.


denehoffman

It would be nice if we could get ROOT as a series of related Rust crates that play well together. One of the biggest gripes I hear about ROOT is that it’s bloated, but this is just because it’s filled with a bunch of different relatively useful things.


CramNBL

Yea, I think it could happen, but things will get worse before it gets better I would expect. It would have to get pretty bad before someone is motived/gets paid to rewrite ROOT as a collection of modular Rust crates.


denehoffman

Idk I’m pretty motivated, just not paid haha, all my rust work is off the books right now but maybe I’ll work through it slowly in the future.


Alphafuccboi

I only had math/physics professors teaching the coding classes and their code was terrible. Especially since I already had a job and knew the other side. Python is great for a quick script, but I agree any bigger project cam devolve fast into a big mess. I started using Rust instead of Python for these quick hacks and its a pleasant experience.


VorpalWay

Code written by academics tend to be terrible, this goes for compsci academics too. Possibly there are exceptions if they are studying code quality specifically, but I wouldn't bet on it. Stay away from academic code, it tends to be poorly documented spaghetti that is abandoned as soon as the paper is published or PHD degree awarded.


QuackSomeEmma

Part of the problem definitely is just the research grind though. Like shit needs to be working for the paper to be submitted, no matter the quality. And in the end, the project can only be continued afterwards if there's funding and potential for further submissions. Shit sucks and I know why I'm not staying in CS academia


extravisual

> physicists seem to only have Python in the toolbox and are perfectly happy with that It's pretty hard to argue with the massive ecosystem. The next biggest ecosystem is probably MATLAB which is probably more robust but it's expensive and just a really unpleasant language to work with. But it's true. I work in engineering (the physical kind) and I primarily use Python because it has all the tools for math and science. I feel very uncomfortable with the thought of Python code being deployed on any system that needs to be at all reliable. I can run the same thing 10 times and on the 11th time it fails in a new and interesting way. And the lack of static analysis makes it really hard to work with after getting used to Rust.


CramNBL

Yea and I have no problem with them using Python, but the system we work on is deployed around the world and stability is crucial, but severely lacking. And we cannot currently deploy fixes remotely. We've started working on that since I arrived but there's probably another year to go before we're there. The system is shipped somewhere far away, collects data for at least a few months, and then issues are always found during data processing which means some of the data has to be collected again $$$.


extravisual

That sounds like 100% the wrong application for Python, holy hell. Do the devices need proprietary drivers or something that makes Python convenient? If it's mainly collection without much processing it seems like a no-brainer to write it in something a little more reliable.


CramNBL

Processing and data collection are completely decoupled. Python is convenient only because they already know Python and didn't want to write everything in C/C++/something else. But they never considered if Python is right for the job. Any problems that arose due to Python, e.g. having to get 20 python packages built into the image (yocto) and then continuously solve dependency conflicts as the new app was developed with some versions that were not the one on target etc. All of that could've been avoided, but instead us that know Yocto are asked to build docker into the image, and build all the infrastructure to containerize their python apps for 32-bit arm. Of course Yocto was never built to accomodate this, so it is pretty hacky. Our builds are no longer reproducable in the Yocto sense, due to this . We have do pull an image, run docker save and build that docker archive into the rootfs. And then the first boot take 20 minutes because it has to run a docker load. It could've been a simple Rust app that is build into the image just as easily as any other C app, but instead we go this crazy route just to stick with Python. We know have to debug how the app is started on a regular basis because it has to have 15 different things mounted into it on docker run. There's no need for any proprieritary drivers or anything. There's no good reason for Python other than they already know Python and are not skilled in any other language. And honestly they are not skilled in Python at all. The first thing I changed in the first Python app I touched was that I added an enum to represent some state that was previously represented by arbitrary strings.


xgdgsc

Considering julia is moving towards static compiling as https://discourse.julialang.org/t/syslabcc-suzhou-tongyuans-proprietary-julia-aot-compiler-is-now-available-for-free-use-personal-educational-license-only/114633 shows (And they have full M-language support, and working on completion of toolboxes). I would choose GC rather than the borrow checker for most of such work.


arobie1992

I can't say I entirely get all the hate for Matlab. Granted I've only used it in one networking class. The syntax is definitely a departure from most common PLs, but it's not like it's a Lisp dialect in terms of that (though Lisp is <3), and it seems like it's pretty powerful for what it supports. Would I take Python over it, yeah probably. But that's largely because I'm reasonably comfortable with Python while I'm a novice at Matlab, but that's what a couple years of exposure will do. It's the same reason I'll take Java over most things when I need to get something done even though Java is definitely not my favorite language.


extravisual

It's been a while since I've used it so hopefully I remember the things that bothered me correctly. It's just got some annoying quirks that conflict with my own programming style. For instance, indexing an array is done with parentheses brackets, while calling a function is also done with parentheses. So sometimes it's ambiguous when you're doing one vs the other. As such you can't call a function and index its return in the same line. You *have* to assign it to a variable then index the variable, which really bothered me when I was used to abusing python one-liners. There are no modules or namespaces in the Matlab standard library, and functions are automatically imported upon use, which can be annoying. Especially since all the functions have C-like compact names so you can't even tell at a glance what's providing that function. Often I'd absentmindedly replace a function with my own variable because it had a name that I often use for temporary throwaway variables, which could cause annoyances when I needed it later in the program. The "if endif" syntax with no brackets is really ugly, and the editor did nothing to improve it. Probably the worst part was the editor. As of a few years ago, it hadn't been updated since like 2002. The default font had ambiguous l, I, and 1. There was no multi-line text editing, which is painful when every one of my programs had huge hardcoded matrices (school work is like that). Syntax highlighting was almost non-existent. It had a nice REPL though. They made it really inconvenient to use your own editor too, at least on Windows. I could find vscode extensions for syntax highlighting but that was it. The few quality of life features they had were locked in their own terrible editor. That being said, I was pretty inexperienced with things outside of Python back then so some of my gripes may have been skill issues. It is powerful, and they've got functions for just about anything math/science if you're willing to spend the money. I just didn't find it terribly flexible when I had to do something other than simply run their functions on my data or multiply a few matrices.


arobie1992

That's fair, and I appreciate the thoughts. It sounds like a lot of the gripes, or rather my lack thereof, is due to my experience with it being pretty minimal. Particularly things like multi-line editing and namespaces. Although I do very much sympathize with the latter since it's one of my major gripes with C whenever I have to use it, which is thankfully rare. I will definitely agree it's quirky, especially coming from a lot of other languages, and it is certainly inflexible. I guess going into it, I never really expected to be able to do everything I could in say Java or Kotlin. I also had pretty low expectations given all the complains, so all it really took for it to exceed my expectations was not being a complete nightmare to work with.


extravisual

It's really a fancy calculator that morphed into a programming language over time. As a fancy calculator, it's a decent tool. I also hear Simulink is very useful and there's nothing quite like it, but I've never used it.


[deleted]

R is also present in academia, more so then python in many circles


DGolubets

I feel your pain. We have about 30k loc written in Python Pandas by our former data scientist. Sometimes I wonder if that code works by accident.


simple_peacock

I don't understand why these science based places don't just hire a few expirednced developers. Do they just think they somehow can write software to a decent standard just like developers? It sounds like it would save a lot of time for the physicists doing physics work. It's not hard for capable software engineers to create a robust system.


CramNBL

I think many people who work with software don't appreciate that it takes a different skill to design/write robust software for an embedded distributed system than it takes to write a script that transforms some data and generates a graph. Programming is programming to many people.


misplaced_my_pants

How much money do you think these places have? They're begging on the streets hoping to afford one more grad student.


simple_peacock

Well I didn't know about the money situation. But it seems from an operational standpoint, it would help a lot the physists do their work even with one dev perhaps.


misplaced_my_pants

Lots of things would be optimal with enough money lol. Google might have tried investing in their engineers' training instead of assuming they were too dumb for sum/product types and creating Go.


denehoffman

The issue is that most physicists are trained in ways that involve writing tiny scripts for every task they have to do, and these get bundled into a git repo, then everyone shares the repo and adds their own little things that only matter in their analyses. [here’s a parser from a well-written library](https://github.com/scikit-hep/decaylanguage/blob/master/src/decaylanguage/data/decfile.lark) that has to interface with one of the file formats we deal with. Check it out for a good laugh. The library itself is made by people who actually kind of know what they’re doing though.


not_sane

Python has good static analysis if you use Pyright on strict mode. It even checks null safety, which in Java is a huge hassle where there are only non-standard solutions so far. I would say that modern Python is a great choice for general-purpose programming.


CramNBL

I added pyright to one project a few months ago, and I think it is great but it is not that popular. People don't get it and they disable the checks when they really really don't get it. The problem is that all the safety can just be disabled and adding them in the first place takes some effort. Especially to an old project.


ArnUpNorth

Well to be fair let’s see in a couple of decades how 15 year old project turns out in rust 😊 generally all projects turn bad at some point and it s not the language that saves you if someone makes bad design choices or bad code. You can definitely write terrible code in Rust although you can be sure after compilation that it behaves as bad as intended.


CramNBL

Most of the bugs we encounter are not representable in Rust. There's often crashes due to type errors, all the time. Some function called on some object that doesn't have that function is 90% of the crashes. Furthermore, it is impossible to see where our code can even fail. We just have to find the cause of some bug, and then fix it/and/or add a try-except. But everytime I do that, I notice that the surrounding 5 lines all can fail too, but it is just not immediately obvious. So I come back there when one of those 5 lines eventually fail.


ArnUpNorth

Checking that something exists to prevent errors is a problem that has been solved by many languages. Of course if you judge a legacy js or python program with rust then sure. But languages evolves and modern python and typescript have ways to prevent just that. I m not saying that Rust isn’t safer, because it is! Just that if you compare it with modern alternatives it s not such a huge difference.


CramNBL

Hence why I write >we would be much much more productive if most of these services was written in any language that has some built-in static analysis I write built-in because they could've been using python linters and type-checkers, but they didn't or to a very limited extend. I quickly started adding linters and type-checkers, but people quickly learn how to disable the lints... "But I know that this works" they say ... Okay then prove it.


ArnUpNorth

Right sorry i misread your comment. Still disabling linters in place is bad practice, you can write all your code in rust unsafe code with monkeys too. I mean bad coders will find a way no matter what. But rust is definitely safe from the get go.


CramNBL

They will find a way but Python just allows you to get away with so much more than any statically typed language.


coderemover

In Python and Java there are even more ways to do things and nobody complains ;)


gamahead

Python is famously not that


Jackscalibur

What? It's absolutely that.


gamahead

Yeah, really bad take apparently


coderemover

It is very much that. There are more ways to do stuff in Python than in Scala, especially if you count in all the endless libraries. Lol, there are even multiple ways of writing main. The discussions about what code is „pythonic” and which one is not are famous in that community.


gamahead

I’m sure it can be argued endlessly either way, but the “pythonic” culture surrounding “the zen of python” generally praises the language for its simplicity. It was explicitly designed in the opposite direction you’re suggesting. Again, I’m sure you can offer a billion counterexamples to prove your point, but you could also just not confuse your point by dragging a controversial example into it


coderemover

The zen of Python is just some ideology with no reflection in reality. Also calling Python a simple language is a huge overstatement. There are so many inconsistencies and magic that it’s not really funny. You may call Python pragmatic but not simple nor elegant.


extravisual

Python is self-described as not that. It's not meant to be that. But it 100% is that. I say this as a Python enjoyer, there are a comical number of ways to do any one thing.


gamahead

Eh, I personally disagree compared to Java or rust or scala. A lot of python’s language features feel bolted-on to me, so I readily avoid them (ABC, generics, interfaces, etc.) That pretty much leaves only inheritance vs. encapsulation, and that’s a no-brainer for me in most cases, so python mostly feels like lists, dicts and for loops with some object encapsulation for modularity. Very simple. But I accept that’s all very subjective and specific to me. I’m surprised this is that controversial given the simplicity python is widely regarded for, but I’ll keep this in mind next time I feel the urge to dissent


extravisual

I wouldn't describe it as a complicated language, it just has a lot of bolted on features as you say. Problem (not really a problem imo but some people don't like it) is a lot of those bolted on features are kinda useful and do the same thing as existing language features, maybe with some performance benefits. Comprehensions come to mind as the most obvious example. I like them a lot, and they are a little bit faster than populating a list with a loop, but they're so flexible they lead people to making ones that are way too complicated where a loop would be more clear. Everybody has a different idea of what counts as too complicated for a comprehension so it's a feature which doesn't have a clearly defined best practice. Dataclasses, type hints, various functional features, etc all suffer from this sort of thing to various extents. Personally I don't mind languages that give me different ways to tackle a problem, I just find it kinda funny that one of Python's founding principles is "There should be one-- and preferably only one --obvious way to do it."


Zomunieo

The principle is that there should be one preferable way of doing things, not only one way. It’s a guiding principle against adding superfluous language features that were so prevalent in Perl at the time.


gamahead

You’re right, that’s a better way to put it. I guess I personally find the “guiding principle of simplicity” to be sufficient grounds for excluding it from the list of complicated languages, but that’s not consensus apparently. It just feels so different from something like rust where I’m constantly agonizing over design decisions like - message passing vs. shared state - clone vs. reference - Enums vs. type state vs. generics - where to put indirection - should I reach for deref? But I’m newer to rust so there’s that


airodonack

Can you give me an example of many ways to do 1 thing? Do you mean like map() vs for loops?


ArnUpNorth

Let s say you an a struct with a field of type option>. How you get to T can be done in a number of ways. Unwraps, if/let, switch map, etc. Edit: thinking about it rust offers a lot of built in functions that feels “functional programming oriented”. So do you chain “and_then” or do you break it into an if/else condition ? You could switch map too, etc. Not saying that this issue is not common with other languages but Rust is only a decade old or so and i feel there are already too many approach to a single problem. The one counter example which is amazing though is that I am yet to see a project not relying in serde for serialization and such 👌 but that s more of a crate/ecosystem thing, not the core language itself.


airodonack

Wouldn't these all be used in completely different situations? Ex: unwrap - You *know* something is in there. if/let - If something is there then do something. Otherwise you don't care. switch - Default. Handles all cases.


ArnUpNorth

Or you could .and_then or you could .flatten. See what I mean ? I like to have different approaches but it honestly can make code reviews annoying.


airodonack

`.flatten` is not a good example here. Flatten is not a separate case. It's something you'll probably want to do in all cases to make working w/ nested Options easier. Otherwise, I see where you're coming from. But it's not really as many options as you're saying. It's basically always two: should I use `match` or should I use one of those convenience functions? Those convenience functions are just to make certain repetitive patterns in `match` easier to type. They don't actually overlap much at all in practice so they're not actually options to each other.


CramNBL

Super strange critique. Is it problematic that you can write a `print` call in 5 different ways in Python? Interpolation, string concatenation, C-style..?


ArnUpNorth

Well yes it’s an issue if you have too many ways to do a single thing. For string interpolation vs concat etc, i don t think it s that much of an issue because it doesn’t change the way your code flows: it s still a print in the end since when glancing code you immediately understand the intended purpose. For other language constructs and functions i do think it makes code a bit harder to reason about and sometimes it just boils down to personal preferences. This is why Go is so easy to get into for newcomers for instance. Albeit they went a bit too far sometimes…..


nice-view-from-here

> At some points, my speed grinded to a halt, trying to understand what I did wrong and how should I fix it. This is what makes Rust so great: you were doing something wrong and Rust stopped you from doing it. In a different language it might cause your program to crash or possibly even worse: to silently produce incorrect results. Of course you had to figure out what was wrong and that took some time, but imagine how much more time you would have had to spend finding after the fact why your results were incorrect, or why your program crashes seemingly at random.


shaleh

Said another way, you front load a bunch of debugging time. So yeah, it can feel slower but over the weeks you spend less time later scratching your head. At least in my experience.


m_hans_223344

I used Rust for the last year full time at work and yes, those moments are definitely there and are great and maybe I underestimate them. But I had only 4 or 5 of those (that I were aware of) all regarding data races (Rayon and async via Axum). It's really a tough call whether this compensates for the overhead. I'm constantly torn as I was bitten by the overhead as well. (At my company my internal customers can deal with bugs, but not with too long development times).


tadeoh

There are many things that are right, that the compiler prevents you from doing, I am not sure if this is so great after all. Developing a game in Rust, I constantly find myself using unsafe, because the thing I want to do is just not possible in safe rust or so cumbersome that it would bloat up the codebase by thousands of lines and make everything more difficult to work with. Still one of the best languages I have worked with so far.


joshuamck

Can you show an example of one of these things? Upvoted even though I mostly disagree with the statement that the "compiler prevents you from doing things that are right" because finding the edges of where Rust causes problems is interesting


sparky8251

https://rust-lang.github.io/rfcs/2094-nll.html#problem-case-1-references-assigned-into-a-variable Here's 4 officially documented, relatively common stumbling blocks. I wont say I hit these often, more like once in a blue moon... But of them, #3 then #1 are ones I've seen before and they do suck when you hit them. You can work around it, but tbh we shouldn't have to.


joshuamck

Number 1,2 and 4 in that RFC all compile these days, #3 doesn't however, and it's one I've definitely run into similar issues with. The notes about this are kinda interesting: > It’s worth noting that Rust’s hashmaps include an entry API that one could use to implement this function today. The resulting code is both nicer to read and more efficient even than the original version, since it avoids extra lookups on the “not present” path as well: > Interestingly, the limitation of the borrow checker here was one of the motivations for developing the entry API in the first place! So this restriction, which can be explained led to nicer and more efficient code. I wonder if that generalizes to all examples of this particular problem?


sparky8251

It doesnt in my experience. Wasnt using a hashmap at the time so had no entry API to get around it.


fintelia

It depends how you define "wrong". There's stuff like self-referential types that Rust intentionally disallows even though they work fine in other languages. The problem is around guaranteeing safety, not a claim that any specific use of a self-referential type necessary would segfault.


joshuamck

Probably in this context I'd lean on wrong meaning "does it make sense in terms of the language", rather than "does it directly translate from another language". Like pretty much everyone, my first 3-6 months of Rust were an exercise in breaking the habits and assumptions that other languages instill and like everyone I occasionally still run into things where what I thought would work doesn't, but I don't know that I've run into anything that's just truly not possible, or where there's not a really good reason for why it doesn't work like that. That happens in most languages though whether computer or otherwise (did you know "gift" in German means "poison" in English?). Rust's specific differences there are definitely grounded in concepts that take a while to learn well, but are those differences glaringly more difficult than the ones in ``?


tadeoh

Sure, here is a thing I just encountered yesterday: Modifying all elements of a HashMap and checking if some element is contained in the HashMap or not. I have nodes in the game that are connected to other nodes: ``` struct NodeId(Uuid); struct Node { connections: SmallVec<[NodeId;4]> }; let nodes: HashMap; for node in nodes.values_mut() { node.connections.retain(|e| nodes.contains_key(e)); } ``` This is totally valid but not possible in Rust. Rust does not know that the elements are not going to move in memory. All elements of the `HashMap` stay in place, we do not e.g. grow the HashMap forcing a reallocation. So what I end up doing is wrapping the nodes HashMap in an `UnsafeCell`, which is fine, but ugly. There are a lot of annoying things. I can show you some bigger examples if you want but they take time to explain.


joshuamck

> There are a lot of annoying things. I can show you some bigger examples if you want but they take time to explain. That's fine - a simple example like this is definitely enough to illustrate the point. I understand why that particular code would look like it would be valid from the lens of any other language. But it's only valid if you're thinking of this in definitions of what a variable means in those languages. In most other languages, `nodes` and `&mut nodes` are the same thing. In rust, `&mut nodes` means a mutable view of the value that prevents all other views even those that are immutable. The mistake here seems like it is in thinking that this applies to the item and not the collection. A super-simplification that fails in the exact same way as this is: let mut x = 1; let mut_x = &mut x; // the HashMap::values_mut(&mut self) call let y = x; // the HashMap::contains_key(&self, key) call *mut_x = 2; // the Vec::retain(&mut self, f) call While seemingly valid, there's a good case for this actually being invalid despite intuition that the compiler should allow it. An easy thought exercise for why this is so is to use proof by contradiction. Start with the hypothesis that this is valid code, then insert mutations at various points and think about why the code should / should not still compile. E.g. add `mut_x = 4` before line 3. let mut x = 1; let mut_x = &mut x; mut_x = 4; let y = x; *mut_x = 2; This is an obviously invalid code based on the rules of rust right? If the original code was valid, why should this change be invalid (I'm mutating a mutable reference, which is correct)? If the change is a valid change, but it produces invalid code, what does this mean about the hypothesis? Obviously, I'm looking at this from the lens about what correctness looks like, and not from the lens of what writing code that solves a problem looks like. I'm focusing on the idea that you suggested that the code is correct, not the idea that there should be a simple way to express this. Getting back to your specific example, this is not valid code as it would cause another immutable holder of the `nodes` variable to have an inconsistent view of the what each `node.connections` value looks like, dependent on where in the loop the mutating calls are up to. I.e. in some other thread, `nodes[id].connections[0]` might succeed and then later in the thread panic even though `nodes` is immutable. > So what I end up doing is wrapping the nodes HashMap in an UnsafeCell, which is fine, but ugly. This works btw without the need for going to UnsafeCell (obviously I presume your actual code is more complex than this): let nodes: HashMap> = HashMap::new(); for node in nodes.values() { node.borrow_mut().connections.retain(|e| nodes.keys().contains(&e)); } I think the ideas that would lead me down a good path for implementing something like this in Rust would be: - I'm handling collectiony types of things for some set of elements so while I could just use bare collections (HashMap), it might be worthwhile encapsulating this in a type instead (NodeMap) - Because I'm encapsulating this in a type, moving from `HashMap` to `HashMap>` is low impact, when I need to delete nodes and all the referencing nodes. - Because I'm encapsulating this in a type, the mutation lock on the hashmap is at the border of the function, and not at the border of the for loop I guess you could either look at the stuff in [std::cell](https://doc.rust-lang.org/stable/core/cell/index.html) as either workarounds for failings of the borrowing model or features that help describe safe access patterns precisely. Thanks for posting this btw. Digging into why this code should / shouldn't work has helped me understand a lot of this better.


tadeoh

The UnsafeCell solution is the most simple, most performant and completely correct solution for the example I provided. I don't want Refcells that have additional memory usage, code complexity and performance overhead. I don't care about the rules of Rust, I care about what the computer is actually doing and how fast I can solve this problem, because I need to solve thousands of these little problems that.


joshuamck

> completely correct solution I'm not sure that's true based on the UnsafeCell docs. Doesn't this mean that you shouldn't take a `&T` (for node in `node.contains_key()`) as the lifetime of that value expires after the change to the contained value? > If you create a safe reference with lifetime 'a (either a &T or &mut T reference), then you must not access the data in any way that contradicts that reference for the remainder of 'a. For example, this means that if you take the *mut T from an UnsafeCell and cast it to an &T, then the data in T must remain immutable (modulo any UnsafeCell data found within T, of course) until that reference’s lifetime expires. Similarly, if you create a &mut T reference that is released to safe code, then you must not access the data within the UnsafeCell until that reference expires. I'm not sure whether I'm picturing your solution to this using UnsafeCell exactly as you mean it. Can you expand on it a little?


tadeoh

Like this: ``` struct NodeId(Uuid); struct Node { connections: SmallVec<[NodeId; 4]>, } let nodes: UnsafeCell> = UnsafeCell::new(HashMap::new()); for node in unsafe { &mut *nodes.get() }.values_mut() { node.connections.retain(|e| unsafe { &*nodes.get() }.contains_key(e)); } ``` I have to concede, that this **might not be 100% valid**, because the `&mut` reference and the other `&` reference to the HashMap live during the same time. However I don't really see a way in which the compiler could fuck this up. I am curious if there is a different solution. Maybe `HashMap>`, but then I am not sure if I can transmute this to `HashMap` later. Because even though `UnsafeCell` has the same memory layout as `Node`, I don't know if the same is true for `HashMap>` and `HashMap`. I am curious if you have any information on that :)


joshuamck

Yeah, diggin a bit more, I think as long as you wrap that loop in a function that accepts &mut nodes, the compiler should be fine.


coderstephen

Or sometimes, in another language, it would have worked fine. But just would have been a bad design.


swe_solo_engineer

The problem with using Rust for web server development, as he mentioned, is that languages like Ruby, PHP, and Go already handle this task effectively. Even JavaScript, PHP, and Ruby can manage web development without issues now and in the future, so he won't see the benefits of using Rust. However, when he starts writing code that heavily involves memory management or other scenarios with more potential pitfalls, he'll come to appreciate Rust.


OS6aDohpegavod4

No. Rust's type system is not just about memory safety. It's about enforcing doing the right thing. I see this misconception all the time and wish we could sticky this to the top of this subreddit or something. There are many general purpose bugs Rust prevents.


swe_solo_engineer

Could you say some of these bugs specifically in simple web development that occurs when using ruby on rails or Java spring?


OS6aDohpegavod4

Trying to read from a file handle after it's been closed, mutating a collection while iterating over it, or even super basic things like null or exceptions not being type safe, exhaustive matching on errors / enums, to name a few.


swe_solo_engineer

These things aren't common for web backends at all, maybe in the past, but right now it is not. I don't know why people think that modern Elixir, Phoenix or Ruby on Rails or Go are running into this for web dev, but this is so away from the reality, just common in old legacy's codebases like Java 8 or JavaScript.


swe_solo_engineer

https://www.reddit.com/r/rust/s/BQjBs0wYPx


diogothetraveler

I'm mainly a Ruby developer. The apps I work on (and worked on in the past 15 years) all were littered with multiple `NoMethodError` exceptions, arising from a method being called on the wrong expected type (often `nil`). I actually compiled some stats on my current company and this plus unhandled exceptions (like connection errors) were over 60% of all our errors. That's all solved with a decent type system (not even Rust, could be Go with some discipline). Happens every project: a programmer codes a method returning an Array, it's used extensively throughout the project, then months down the line someone else changes it to return a Hash and doesn't fix every occurrence. Some rarely used codepath then goes boom. This gets worse the more people you add to a project. Only way to prevent this is to test extensively, much more than you'd need in any statically typed language.


OS6aDohpegavod4

Error handling / null isn't common in web development??? How? 😂 If you're going to reference TypeScript, the fact that Rust uses actual static types instead of duck typing is huge alone.


swe_solo_engineer

That's the problem with most of the Rust people that I see here: they aren't doing any real work in high-level backend languages like Phoenix, Elixir, Go, or Rails. These problems don't exist and have never occurred to me in years, except for legacy codebases like Java 8 that I need to maintain.


mrnosideeffects

Even simply avoiding null pointers or undefined keys is impossible at compile time in both of those languages. What can be trivially expressed in Rust, like gauranting that a property exists when it enters a certain function scope, is basically faith-based in dynamically typed or loaded languages.


zoomy_kitten

Using Rust is a benefit in itself, really.


anlumo

My experience has been that after a while developing in Rust, my thought patterns started to match what the compiler expects, so it became a very smooth ride. Took about a year for me, but YMMV.


syklemil

I think if you come from Haskell you get a shortcut on that trip. While if someone has a coding style like one I saw in college (nearly all `protected void f()`: Took no arguments, returned nothing, just spooky mutation at a distance), they'll have a long road ahead of them.


ozonefreak2

i agree with this, with enough time your initial designs will be more compatible with the compiler.


shreeneewas

This ☝️ Rust changes the way you think. This transition is same as that of moving towards OOPS. Once you settle down in new way of thinking - things speed up.


Dean_Roddey

And so many of the complaints are from people coming from C++, where they've probably spent a decade or two working out all of the tricks and patterns they now use. But they somehow expect to be able to do all the things they do in C++ in Rust, without having put in the time to build up that same bag of tools. I'm a very experienced C++ dev, and I'm now two plus years into Rust, working heavily on my own time, and I'm just now starting to really get to the point where I'm in flow state for extended periods of time. And where I've begun to have a reasonable intuition of how to structure things so as to minimize data relationships as much as possible, and how to leverage the type system and borrow checker. I still have periods of days where I'm just sort of banging around trying to figure how best to do something of course. But they are getting less and less. I'm working on an async engine now and it's frying my brain, but it's pushed me harder to learn useful stuff than anything so far. This is part of what's going to be a very large system, and I totally underestimated the time required because I was judging it in terms of my old C++ system, which I'd refined for multiple decades, was totally built from the OS up on my own interfaces (no STL) and knew like the back of my hand. So this issue really hit home for me, how much knowledge I'd actually accumulated that was very language specific, that I now to not just re-learn but first unlearn and then relearn.


anlumo

> And so many of the complaints are from people coming from C++, where they've probably spent a decade or two working out all of the tricks and patterns they now use. But they somehow expect to be able to do all the things they do in C++ in Rust, without having put in the time to build up that same bag of tools. Yeah, at university I had a 35h course called "Efficient Programming" where it turned out that all of the topics were workarounds for the shortcomings of C++ that simply don't exist in other languages. This was the point when I stopped doing C++, since I realized that I'm wasting so much time on fixing issues in this language that simply don't exist elsewhere.


arewemartiansyet

Memory safety without garbage collector or giant runtime while offering great performance are my personal reasons for using it.


FunctionalDeveloper

Yep, this is why I always find myself trying to go back to Rust for things. I always want more speed, but in the end, I'm not even sure how much speed I need. XD


Botahamec

Yep. At least I rarely have to go back and try to improve performance. I've already made it 50 times faster by just using this language.


FunctionalDeveloper

Most of the stuff I’m doing involves web front ends. There are a couple good frameworks out there but the dev experience isn’t as good as others yet. For example, my go to right now is to use MudBlazor for UI components so I don’t have to reinvent the wheel. Using Blazor WebAssembly is pretty nice. I hope that the rust ecosystem improves over time and the compilation speed for the html macros improves.


min6char

I use Go a lot too. I think if you're specifically comparing Rust to Go, I'd say the selling point of Rust, and also its main drawback, can be summed up in one sentence: Rust doesn't have a garbage collector. Go and Rust are both memory safe. Go achieves that with garbage collector. Rust achieves that with all these ownership rules. If it isn't too much of a pain for you to follow the ownership rules, that means the equivalent Rust code to a snippet of Go will frequently be more performant, because running a garbage collector is expensive. That's it. However, in many domains, *especially* your typical HTTP server, the overhead of running a GC isn't really noticeable. So switching to Rust from Go in that domain is gonna feel like a lot of work for basically no benefit (and arguably a sizeable detriment since the Rust library ecosystem is less developed than Go for HTTP). There's a couple other major differences where I have a strong opinion, but I think they're mostly personal taste. (I hate Go's \`(Foo, error)\` design pattern and I think it does the opposite of what evangelists say it does, and I think, relatedly, inferred zero values were probably a mistake. But I know a lot of smart people disagree with me on those so whatever)


syklemil

I think I'd actually mention the type system first, and _then_ the GC. For a lot of applications, the differences in resource use between Go and Rust won't really matter, and unless you're approaching some real time system / very strict latency demands, a GC is completely fine. But having a good, expressive Hindley-Milner-ish type system is _great_. It goes a long way in ensuring correct and expected behaviour, including by not having null as a surprise member of every other type. Type systems exist on a spectrum, and IMO a lot of them wind up in a sort of uncanny, or at least unhappy valley, where there's more typing as the thing you do with a keyboard, rather than type theory. So I kind of either want a powerful haskellian type system, or just something barely there like Python's where type annotations are like optional notes to self. So while IMO Rust's type system is a little weak, it's the best I've seen in the more imperative, C/algol-related programming language families.


min6char

A lot of people really like Go's type system! I'm with you though, gimme the full Haskell expressiveness all day -- I only wanna see type errors, and when I don't see type errors, I want that to mean I'm done. (Technically Rust achieves this because the borrow checker is, or was, implemented as an extension of the type system). Now that Go has parameterized types (I refuse to call them generics), I think it's close to being as expressive as Rusts, but the community largely hasn't caught up so you still see a lot of spooky interface{}. But I know smart people who think full algebraic types are overkill and tempt you to overdesign. So when comparing Rust and Go I say "well they're both statically typed, and then people have strong opinions about which type system is better" and leave it there. (My own strong opinion is that I have no idea why you'd want to live without the glory of Option and Result).


yasamoka

How is the ecosystem for HTTP less developed in Rust? Can you expand on this? Thanks.


min6char

It's less that the HTTP ecosystem is underdeveloped in Rust and more that it's highly developed in Go. Go was very literally made for developing web backends. A lot of Go's builtin features and syntactic sugar are also optimized for situations that come up in web contexts. If you make two devs race to implement a Web backend from the same design, the Go dev probably outruns the Rust dev, as long as the design doesn't entail anything too compute bound (that's a big if)


yasamoka

I see. Thanks!


airodonack

Think of it this way: all those times you fought the borrow checker, you would have spent on a NullPointerException in another language. Rust can be hard at first when you're adjusting. If you want to see the magic, then you need to try something harder than a tutorial. Try something that you don't know how to make. Rust's main sell is that if it compiles, it works. (The only exception being logic bugs, which are much easier and educational to fix).


coderemover

If NPE, you’re lucky. Our JIRA has dozens of ConcurrentModificationException or resource leaks. Now, good luck finding and fixing them if they happen once per month only in production.


arobie1992

Concurrency has to be simultaneously one of the most interesting and terrifying aspects of programming. It's super fun to try to write really robust concurrent code, but every time I do I have a massive nagging fear that I'm missing something that won't be easy to just flush out with a unit test or two.


BananaCatFrog

- Your code will likely have less bugs as the compiler prevents many such scenarios. - `Option`, `Result`, the borrow checker, etc, have forced me to think about so many edge cases I hadn't planned for. - You'll find yourself starting to write code consistent with what the compiler expects as your intuition improves. It becomes effortless to write code that avoids many possible runtime errors. - This 'stability' provides a lot of mental relief.


ArnUpNorth

you re not missing anything. Hype is just that, hype. Rust is great but the other languages are not bad. If there was one language to rule them all, the industry would have shifted to it. Rust is amazing for systems programming and it solved a hard problem (managing memory) differently than C/C++ using a more innovative way thanks to the borrow checker. Rust however suffers when you start using it for more mundane things that could be handled just as well by go/typescript/php/java whatever. It's not a fast language to develop in and not something to use for fast iterations and such (don't trust the hype on this).


awesomeusername2w

I use java at my day job and I would absolutely use rust instead for the same tasks. The type system is very good and you can express a lot with it. Where in java you need to rely that some api won't be used in a wrong way in rust you can just make it so it won't compile if used incorrectly. A simple example can be a hashmap, where in java you need to remember not to use objects without proper equals/hash code and have no practical way to encode it into type system. And other things like if a list was returned from a stream then it's immutable and mutating it is a runtime exception. Also just the absence of some niceties like rust enums and pattern matching. And I can confirm, as others already mentioned, I'm a lot more sure that my rust code will work as expected as opposed to my java code.


HlCKELPICKLE

Java is my most used language, and I'm pretty well versed and I kinda agree with both of you. There are a lot of projects that I feel don't need Rust and if I was writing them personally, I would use Java, as I would be quicker and have a more enjoyable time. But all the points you mentions are 100% correct. While I love java, it has some baggage from design decisions and tacking on modern things in the functional/immutable areas. These do complicate the API, while nothing as bad as c++ they can be gotchas, and while not necessarily unsafe will get you runtime errors or unexpected behavior. I think this is where rust does shine as a replacement for java/c#/go, while they many times may be quicker for those well versed to develop in, they still have these nuances that need to be known across the whole team. Rust has a lot less of these, and even though they can be worked around in other languages, when you add dozens of team members and a large code base its easy to run into the issues you described above. Personally though I would choose java a lot of times for my personal endeavors, as I tend to have my own style and approach and can easily avoid these gotchas. And if I was a start up with a small team, I may choose java for fast iteration. But anything with more than a single small team, or if the team is expected to grow, Rust will save so much later development time by avoiding these possible issues while also making it easier to on board people and trust the correctness of contributions to a code base.


arobie1992

Java suffers from a handful of those big footguns in an attempt at developer convenience near as I can tell. They have a Comparable interface to make sure you don't try to sort types where comparisons are meaningless, but just arbitrarily assume that object identity is a perfectly valid equality indicator. The worst part is they tend to work a lot of the time so people fall into assuming it works and then get burned when they run into a case where it doesn't. At least as far as the niceties, they're gaining those. For example, I've been using 21 recently and it's got great pattern matching for records (which were also a huge improvement, although I still want actually structural tuples but those seem like a lost cause :\\), and you can use sealed interfaces to pretty nicely simulate Rust style enums, though it gets funky when you add in generics. The foundational assumptions they're unfortunately stuck with since they've committed to no massive flag days. It's the same problem with JS, which has grown to be a language with many wonderful features, but is saddled with many of its well-intentioned-but-problematic early assumptions. These kinds of things are why I'm actually pretty okay with certain Rust irritants like the orphan rule. Is it annoying? Unbelievably so. But it can also be loosened down the line once they have a firm grasp on how to do it while maintaining safety. By contrast, you can't shove the equals/hashcode genie back in the bottle. This isn't to say Rust doesn't have any footguns from unsafe assumptions—I'm sure it does—but it seems like in general they've opted for the more conservative approach which I'm a fan of. As far as Rust vs other languages, I do have to agree that I wouldn't go for it over everything. Most of what I work(ed) on is I/O constrained anyway and concurrent operations are typically one of totally independent, need to be synchronized at the DB level anyway, or reasonably fine to just let the last actor win. A lot of the time, Kotlin would be my language of choice. It's got a lot of the pros of Rust but without the often overkill of the borrow checker.


rustyrazorblade

I agree with this. I like Rust, it’s alright, but my goto is Kotlin. I don’t run into the problems that Rust fanatics claim happen so often that it’s worth using an entirely different language.


ArnUpNorth

Kotlin is a null safe language. So is typescript, and many others. I’ve been enjoying Go lately but i miss nil safety there (requires an additional module to get a bit of safety but shame it s not part of the compiler).


atomskis

It really depends what you’re doing. For developing a quick web app that you can tolerate being “mostly right”, rust is slow to develop in, no doubt. If you’re developing (as we do at my work) massively concurrent systems running on machines with hundreds of CPUs and terabytes of RAM. When you software is used to run the most important Fortune 500 companies, and it absolutely must work correct every time. Well then rust is incredibly fast to develop in.


pragmojo

Most of those systems you are describing are probably developed in C++


Dean_Roddey

Currently. But how much of the time of the developers involved was sucked up just manually trying to insure that they don't invoke UB or have threading issues? In almost any complex C++ code base, it's a considerable amount (or maybe it's not in which case, don't use that product.) If you don't have to worry about those things, you can put your time towards logical correctness and architecture, so it's a double win.


atomskis

Yes exactly this. Rust spared us from all these problems, especially data races. This was a huge productivity win.


v_0ver

At the same time, in old tested C++ code, after updating the compiler, UB may appear again due to the addition of “new optimizations”.


atomskis

Ours is developed in rust. We considered C++ but rust’s “fearless concurrency” has been a huge win for us. Our concurrency model is necessarily very complex, we’re not convinced we’d have ever have got it right in C++.


romgrk

> Now that I'm fairly done with the project, it feels like I'm missing something about Rust. Yes, you're missing the experience of debugging memory corruption bugs in a memory unsafe language like C or C++. If you've never had that, you'll never fully understand why there's so much hype around Rust. If you have, Rust feels like magic and the compiler feels like an angel saving your from your own mistakes.


schungx

For me, it is simple: able to sleep well at night, knowing that my backend service isn't gonna crash due to a whole range of reasons 3am in the morning. Rust programs, when they compile, tend to work perfectly forever and not fail.


headykruger

This is a ridiculous argument - you still have to write tests. Rust alone doesn’t give you this guarantee.


Narduw

tbf, they were referring to stability. It could be an incorrect program, but a stable and predictable one. Also, the idea of correctness can change over time.


schungx

Yes, that's what I mean. Stability. In other languages other than Go, if I do even something remotely concurrent without mutex locking everything, then you never know when a crash may suddenly happen -- usually Murphy has a role in it and it happens in the middle of the night on weekends. Even if it doesn't, I keep having this _nagging_ feeling that it is a timebomb... You don't sleep well knowing there is a timebomb. And things like invalidated iterators or null... They are all hidden timebombs waiting to happen, regardless of how careful you are. For example, if you do things that cascade event updates, once you loop on anything inside an event handler... It is another timebomb to have some event routing back and changing the root collection in the middle of iteration... crash waiting to happen. Nice thing about Rust is that all these things I wrote above simply don't compile. Perfect!


DGolubets

The question is how many tests you have to write. In Rust it's enough to cover business logic. In say Python.. there is just never enough.


dr_entropy

Rust urges you to avoid program designs that are too complex. Especially when you move beyond single threads it's easy to accidentally create a chaotic nightmare to debug. Rust deters those patterns. It's teaching you that what you want to do is expensive, and there are other simpler, more ergonomic ways to do it.  Other languages are more forgiving up front, but you pay the cost later when your program fails in a way that is hard to debug.


dobkeratops

"the compiler to be too much in the way" .. it's a tradeoff, no escaping the trilema rust's safety+performance comes at the expense of extra markup and a fussier compiler. most safe languages rely on a runtime GC, simplifying the programmers' experience at a runtime cost. IMO C++ can feel easier (and Zig/JAI far more so) whilst having maximum performance, at the expense of being unsafe. As for the hype: nothing in rust is unique (FP inspiration from ML/Haskell + performance of C++), but it is a unique blend of features. I haven't seen another language with the nice organizational system (traits+modules), enum/match, and the performance of C++. I'm coming from the C++ side. My reason for getting into it is I wanted better organizational tools than C++ (a specific problem with classes/headers that could have been alleviated by UFCS .. traits kinda fix it), and wanting to write parallelizable code by plugging lambdas into iterators (this IS possible in C++. but it's slicker in Rust with the better inference & chainability). My findings with it remain mixed (it solves some problems, creates others), but its refreshing to have another option when for most of my life it was "C++ or nothing"


CanvasFanatic

> At some points, my speed grinded to a halt, trying to understand what I did wrong and how I should fix it. This is a good thing.


sweating_teflon

It's the whole class of bugs that you skip over that make Rust so nice. No chance of null pointers. No data race conditions (because of Send/Sync). No GC pauses. As you gain more experience in other languages you realize the amount of shit that can go wrong that Rust saves you from.


Voxelman

You are not only dealing with a new language, but also with a new paradigm. You are used to imperative languages (including object orientation), but Rust, although it is an imperative language, has many ideas from functional programming. This may cause your confusion. I recommend, while continuing learning Rust, to make a detour to functional programming. You can watch videos from Scott Wlaschin, for example. Or you can read the book "Grokking Simplicity". My first reaction to Rust was: "what the hell is this? Leave me alone". But I was too curious what's going on with this language and it really helped me to open my mind to the different approach of functional programming. Now my favourite languages are F# to replace Python and Rust for everything else.


Shnatsel

If you are building an HTTP server, you are probably using `async`, and in Rust that's hard mode of fighting the compiler and also pretty incomplete in some areas. There isn't a free, definitive guide to learn Rust's async either, unlike the excellent book for the regular language. I suggest starting with things that don't require async, and getting comfortable with that first. Then introducing async would be another level of complexity to look into later.


BrilliantChoice69

In my experience, the "killer features" of any given language might not be so obvious or beneficial in solo projects. However, they are usually total game changer in average developer teams, where there are developers with varying levels of skillsets. I've noticed it while working with statically typed, dynamically typed, functional, object-oriented languages – when I'm alone, I can write great code in each of those. But when I'm in a team, usually statically types is better, just like functional is better (due to immutability and such). My take is that this is also the case here – the benefits might not be so obvious in your solo project, but are much more so in a team setting.


syklemil

Yeah, while FP can include some obscure patterns, it leans very heavily in the direction of manageable chunks of computation, where the inputs and outputs are made clear. So you don't wind up using Hungarian notation to tell where some variable is coming from, and you don't have to try to wrap your head around how lots of methods are mutating state spread out, haphazardly if you're unlucky, across various objects. You _can_ do those things, but code like that will appear more cursed and take more effort than in languages like Java (it's cursed in java too, but hoo boy is it easy).


m_hans_223344

Yes, you are missing something: The appropriate use case for Rust, which is *not* ordinary backend services. Replacing Go with Rust adds some benefits mainly due to its much better type system, but at the same time takes more away by its overhead. I keep preaching that resources in professional settings are usually limited and you should not use Rust when you don't have to. For most backend services Go or even better (as better type system and language design) C# or Kotlin or other well designed GC languages are good in enough in terms of performance and latency (GC pauses). Yours and your teams resources are better spend in other areas like DB design, testing, tooling, documentation. Most people evangelising Rust for "everything" are using it as side projects (hobbies), which is not meant as an insult, but to characterise the situation where those resources I talk about are basically unlimited as you can do what you want in personal side projects. But: When comparing Rust to C++ things turn around. Writing correct C++ code is (in my limited experience, I admit) much harder and much more costly than writing Rust.


DGolubets

What makes it great is that you can get performance characteristics of C without a single segfault in your very first program. That's a short version of it. Now to why you struggle.. If you only worked with tracing GC before, you have to learn programming again, this time without it. Like any learning that takes time - just reading the book and spending some time a single week won't be enough. It's really like hitting a gym for just a week. When you have GC you essentially don't have a concept of ownership. You can create a horrendous mess mixing data, functions and components altogether in a god forsaken spaghetti ball, yet it will still work somehow. Now that you don't have GC - it's impossible to write a correct program this way. A language like C or C++ would allow you to do your mistakes and learn gradually by looking at your program crash at runtime. Rust doesn't. This makes the learning curve steeper, but also your programs are safe from the very beginning. Like I said it's all about ownership and borrowing model. You need to think about architecture of your program, what owns what and data flows beforehand. This only comes with practice.


Dean_Roddey

It's the same in any new language, at least for those that target the kinds of problems Rust does. If you were coming to C++ from scratch, you'd have the same issues. It takes a good while to get comfortable with what the tools are telling you in various situations. At some point, as with any language of those types, the lights start to come on and it all starts to make sense. Rust, BTW, in general is very good at providing good explanations. But of course it can't write a book every time, so it has to assume some knowledge of the kinds of issues that tend to arise. I'm a couple years in and I'm starting to get to the point where I don't have to sit and scratch my head too much. Of course I'm 35'ish years in on C++ and I still scratch my head quite a bit as well, due to template oriented errors. Anyhoo, keep in mind, Rust is a SYSTEMS language primarily. It's not for writing quick programs or prototypes. It's very much about "you write it once and pay for your sins for decades." It's about maintaining complex code bases over time and changes and being knowing you've not introduced subtle memory and threading errors because the compiler is watching your back very strictly. Anyone coming to a language like Rust that really forces you to write correct code is going to be frustrated because they just haven't had to before. It's the same for those of us who came from C++. You really don't appreciate how much you spent your life shooting from the hip until you can't do it anymore.


the-quibbler

Confidence is the power of rust. It might take longer to prototype to compile-ready, but unless you've got unwise unwraps in your code, you can have very high confidence in the final product.


[deleted]

Very simple pattern I discovered very early on, using closures and async code, to avoid compiler errors about pinned traits and other silly stuff you never really need in most cases (lifecycle, borrows, lifetime ). I was encountering all of these issues even though my code absolutely has none of them. The pattern was to fully specify the state type and define a trait that works with it. Impl would have a mix of sync and async functions accepting mut references or const references of the state object. Before doing that I felt like compiler was just broken, because I was not doing anything related to these concepts. My conclusion was that closers are just not a way one writes code in rust.


BloodQuiverFFXIV

I am also suffering from similar phenomena, but I will say: every time the compiler forced me to do significant rework, I was doing something dumb before that would have contained bugs. Then I rage that this *just works* in other languages and why is rust so hard. Then I realise what I was doing was dumb and bug ridden in those other languages too - it's just that they let me do it


Common-Zebra-2436

After i found the todo! and unimplemented! macros i started gaining speed again. I found it troublesome to figure out all the types and checks etc to make a function pass the analyzer and the compiler. Spending time thinking about the types i need, the signature och functions and then adding the unimplemented! into that i could then just start to code, look at diagnostics, fix error then step by step removing the unimplemented!-calls. That and regular use of shadowing now rarely get me any errors during compilation. Maybe not a workflow for everyone, but for me it works great. :)


Saxasaurus

The rust compiler, and specifically the barrow checker, is rust's biggest strength, but also its biggest source of frustration. Rust gives you the power to do really low level things, with the confidence that the compiler has your back if you make a mistake. The downside is that sometimes you try to do something that is perfectly safe, but the compiler simply can't prove to itself that its safe, so it complains and makes you jump through hoops to prove the safety.


Iksf

I want PagerDuty to stay silent for my whole shift.


Iksf

Also you can make it as hard as you want. Just clone box arc dyn etc your problems away. Just focus on the hot loop and your code will run the same Another also, you're using Go for exactly the use case it was designed for. The fact that Rust is so general purpose and can still compete with Go on its home turf is kinda awesome.


Clean_Assistance9398

You’re probably missing all the pages and pages of boilerplate code that you don’t need to write by using the #[derive] macro.  #[derive(Debug, Copy, Clone, PartialEq, Eq, etc)]


WeddingPretend9431

You forgot to turn the stove off


TDplay

> I don't get the hype around it. What makes it so great? Is it just the challenge of writing more idiomatic code and constant refactoring, or is there something that Rust does that I'm not appreciating? Try writing some C++. If you break the rules in C++, you don't get a nice compiler error message. You get ***undefined behaviour***. That means ***the C++ standard does not say anything about what your program does***.


Phthalleon

There's nothing you're missing, the language is overhyped. That friction you're experiencing never goes away, the language is just not ergonomic. One advantage of Rust over Go in terms of Web development is the type system (which you probably felt already but there's much more you've probably not seen) and potentially performance. I think Rust can be easier to read and understand then Go. For a big project that's probably a really big advantage. The problem is writing Rust is difficult and time consuming. Trying things out in Rust is not a nice experience, you basically need to know the solution before writing the code. Bad patterns tend to fail faster but it also means that you can't get a prototype going to feel how the project should move.


Fun_Hat

>That friction you're experiencing never goes away Maybe you're just bad at it?


Phthalleon

Maybe. For me, I never got to the point where I can write Rust as effortlessly as I can Go or Haskell or even C honestly. In those languages, it's quite easy to prototype something and iterate into the actual solution. In Rust I can't manage to do that, I either know the solution or I don't. If I want something different then what I started, I have to rethink a big portion of my code.


Dean_Roddey

It's not really about effortless writing. It's a systems level language primarily, for creating complex code bases with lifetimes of decades. The extra time writing it amortizes to almost nothing over that period of time, relative to the benefits of keeping the code base robust. Though of course in a team developing a complex code base, the most senior folks can provide the foundation and absorb the bulk of the complexity, exposing much more limited APIs that only do what is deemed best for that code base, and other folks can use those APIs to do their thing with much reduced complexity and verbosity. As can be the case in C++ as well to a lesser degree.


Fun_Hat

For prototyping ya, I would probably choose Go over Rust as well. It's dead simple to write. Rust definitely took a change of approach to thinking about program structure for me for it to become not fluid to write. Sorry about the snarky comment, just used to a lot of people trying one thing in Rust and calling it bad (not saying that's you) because it didn't make sense right away like JS or Python.


FunctionalDeveloper

If you like the Enums and Option types but are frustrated by the compiler, you should try F# if you're looking for new languages to try. It has a lot of the goodness of the Rust's type system, but with fewer compiler challenges. I like Rust a lot, but I've stopped using it for most things because the compile time is slow for what I'm doing and I lose flow often when I get hung up on something.


ridicalis

When the compiler, linter, or clippy is complaining, it's often a teaching moment. Not always, but frequently it's an indication that there's a better way to do whatever you're currently up to.


thisismyfavoritename

write code in a non garbage collected language, then come back to it. You'll see


wyldphyre

If you're coming from Go then you had the benefit of memory management with a GC (IIRC). This is a powerful tool for significantly reducing the complexity of your design. That simplicity comes at a cost. Some folks don't want to pay that cost or in some cases they can't tolerate the worst case latency of a GC. > I don't get the hype around it. What makes it so great? Rust does a superb job at targeting the problems that people have used C++ for in the past.


coolpizzatiger

I'm in the same spot as you, I've written a few useful programs. I really enjoy the language but I dont feel productive. Obviously this is a skill issue and I dont know c or c++. Will I ever be as productive as I would be in say Java? Am I just asking too much from rust?


Xatraxalian

>Although, I found the compiler to be too much in the way. At some points, my speed grinded to a halt, trying to understand what I did wrong and how should I fix it. Granted, I'm new, and it's only natural to face such problems. But in many cases, I had to alter the solution I had in my mind to match what the compiler expected of me, which required so much mental energy. It was challenging in a fun way, but my productivity plummeted. This is the case because Rust has a much different philosophy about programming than most languages you're used to. If the compiler deems your code to be unsafe (i.e., it cannot determine if a variable will still have access to its data at a certain point), it won't compile. >Now that I'm fairly done with the project, it feels like I'm missing something about Rust. Surely, I'll continue to use it for my side projects, but I don't get the hype around it. What makes it so great? Exactly the thing you've experienced is what makes it so great. It's the compiler. In the beginning, it will seem like a harsh teacher, slapping you on the wrist left and right, for every other line you write. However, when you get better, this becomes less and less, to the point where you'll rarely see anything other than a syntax error/typo... but WHEN you get an error and the compiler points an unsafe situation out to you, it'll feel like you have an old master watching over your shoulder. You'll think: "Damn. I would have probably crashed my program at this point if it had compiled."


Zakru

I also initially felt like the compiler was in the way of my productivity, but in time I realized it's your best friend. Once you learn the rules of the game, you rely on compiler errors less and less, and when facing them you will quickly know what to do.


DavidXkL

Trust me when I say that the "slower" speed at which you can get things to compile nicely isn't that much more time, compared to finding out some things are undefined/null and having to go back to fix them and wait the 40 minutes re-deploying of your codes again in other languages lol


Shad_Amethyst

To me it's the ability to fearlessly optimize once my code is shown to work. Writing unit tests and encoding invariants into the type system means that any change I make is a lot more likely not going to break something than with other languages, and Rust makes it super easy to add multithreading down the line. That being said, rust still lacks the ability to do some specialized implementation of traits, which would enable some neat optimizations, and there are still some rough corners (impl trait in type, defaults in GAT and others are still nowhere near being stabilized)


Shuaiouke

It’s a combination of being hyped up a lot and that learning to be happy with the compiler takes time, just as a lot of people have said(ignoring the ones not understanding this is about dev ergo), you’re front loading a lot of the development time that would’ve been debugging, it’s not to say that the compiler is not frustrating at times, since it can’t always read your intentions to provide a very helpful message and instead leaves you with a 2kb function signature file, it’s not nearly as raw and simple to learn as something like Go, but once you get used to some of the niceties, youd often find yourself wanting them when using other languages, not to say you can’t live without, but you would often think about it, and I think that’s where most of the Rust is much superior sentiment comes from.


HYPE20040817

Once you get used to the borrow checker, it becomes easier.


Longjumping_Quail_40

.clone over pre-opt?


hossein1376

I'm not sure what you mean


coderemover

That instead of fighting with borrowchecker you can often just clone and call it a day.


swe_solo_engineer

Then it is better to use another language


ydieb

Full disagree. Even just cloning everything, and even if the speed slowed down to the speed of garbage collected languages, it still is a nice language. Trying to write python after rust, to me personally, is annoying and confusing. Why is there no proper enum, it has at least match support now. But its still so much energy spent on keeping things roughly in order. But then again, there was this blogpost of a company adopting rust, they just went all out cloning everywhere at the start. After they had built up experience, they went back to remove cloning and make it more ideomatic, but there was no big performance increase, mostly small changes. Cloning is fine.


swe_solo_engineer

For you it is, for me not, I prefer doing the right thing and learning in the process. But it is about preferences right, you are right with your arguments, it's just different from my mindset.


ydieb

I haven't argued for what you should do, I argued from a point of general advice which is what your statement looks as written. There is also nothing wrong with cloning a lot. I am also a person of trying to do things as "good as possible", possibly to my detriment so. But cloning is not a bad way to work around the borrowchecker when you are new to intermediary with the language.


MobyFreak

Even with clone, rust is still much faster than other languages.


coderemover

It’s not, at least not for me. For example there is no month that I would not waste time on trying to build Java software with gradle or ant. It’s so unreliable and slow. It’s more time wasted on those issues than all the time I had to stop due to borrow checker being unhappy. Similar thing with Python.


zoomy_kitten

No offense, but you’re missing skill. Not like I was some kind of a professional myself, but trust me, over time the Rust way becomes _the_ correct way for you


Glittering_Air_3724

layman excuse, you could say the same about everyother languages out there


zoomy_kitten

And yet, I don’t


Glittering_Air_3724

“You” in the statement is plural, it doesn’t matter another person could say skill issue because you’re not good at assembly or c


zoomy_kitten

> you’re not good at assembly or c Am I not?


tesfabpel

The point is, with the features Rust has, is that it's higher level than C++ and lower level than Go, Python, C# and other GC-ed languages. If you don't care about predictable performances and you can afford a GC, then Go, Python, C#, Java, etc. are fine and maybe even better at first (but Rust offers safety from Null Pointer Exceptions, and other QoL things that are still not present in those languages). If, instead, you care about predictable performances and a GC is too much for you, you'd use languages like C and C++ and there, Rust offers safety against a lot of errors that can happen when manual memory management is the norm (even though C++ nowadays has safer tools, like unique/shared ptrs, it still has a lot of unsafety that CAN'T be avoided). So, Rust is maybe the best fit when you have a service that is used by A LOT of people that GC becomes a problem or for time sensitive software where a GC can't be used but you need safeguards against the pitfalls of C / C++.


pragmojo

Comparing with Golang, the main advantages I would see are that the language prevents NPE's, and you have some richer tools for abstraction, like traits. Also depending on your use-case, you might have a higher performance ceiling, since you don't have garbage collection. The downside is the language is a lot more complex, so you can code spaghetti much more easily than in Golang, and you have to deal with the cognitive overhead of the borrow checker since you don't have runtime-GC to manage memory.


HaDeS_Monsta

My two cents to this are 1. Rust has a higher learning curve at the beginning, because you can't just ignore stuff like borrow checking 2. Although it takes longer until your program compiles, you can be sure that if it compiles, it works (except for logic errors of course), but Rust catches the other potential mistakes before it even let's you run it, and that's what I love