Most active commenters
  • steveklabnik(4)
  • melodyogonna(3)
  • swiftcoder(3)

←back to thread

451 points birdculture | 54 comments | | HN request time: 1.296s | source | bottom
1. mdwhatcott ◴[] No.43979711[source]
[flagged]
replies(13): >>43979747 #>>43980029 #>>43980452 #>>43980582 #>>43980897 #>>43981065 #>>43981118 #>>43981329 #>>43981636 #>>43981787 #>>43981862 #>>43982909 #>>43992716 #
2. mplanchard ◴[] No.43979747[source]
I suspect an article like this says more about the author than the language.

Note I’m not being critical of the author here. I think it’s lovely to turn your passion into trying to help others learn.

3. LAC-Tech ◴[] No.43980029[source]
I have taken the time to learn rust and you're absolutely right. It's a very complex, design-by-committee language. It has brilliant tooling, and is still much less complex than it's design-by-committee competitor C++, but it will never be easy to learn.
replies(3): >>43980172 #>>43980282 #>>43980583 #
4. worik ◴[] No.43980172[source]
There is a trade off. Rust gave us fast, and safe. It did not give us "easy to learn".

I think it is a very good example of why "design by committee" is good. The "Rust Committee" has done a fantastic job

Thank you

They say a camel is a horse designed by a committee (https://en.wiktionary.org/wiki/a_camel_is_a_horse_designed_b...)

Yes:

* Goes twice as far as a horse

* On half the food and a quarter the water of a horse

* Carries twice as much as a horse

Yes, I like design by committee. I have been on some very good, and some very bad committees, but there is nothing like the power of a good committee

Thank you Rust!

replies(1): >>43980457 #
5. rat87 ◴[] No.43980282[source]
its not design by committee its design by Pull request It doesn't have a central https://en.wikipedia.org/wiki/Benevolent_dictator_for_life like python used to so people suggest and implement features as a group, with code counting for a lot (although theoretical issues with safety/design also matter) as opposed to companies arguing for their pet features endlessly without much difference. Look at how long it takes C++ to get any new features.
replies(1): >>43980383 #
6. rafram ◴[] No.43980383{3}[source]
> Look at how long it takes C++ to get any new features.

I’m not sure “it doesn’t have enough features” has ever been anyone’s complaint about C++.

replies(1): >>43987964 #
7. rvz ◴[] No.43980452[source]
Maybe Rust is so complex, it is even more complex for an LLM to generate correct code (one-shot) without hallucinating non-existent functions.

Would rather have that than all the issues that JavaScript or any other weakly typed and dynamically typed language.

replies(1): >>43980625 #
8. LAC-Tech ◴[] No.43980457{3}[source]
It's just a programming language, not a religion.
replies(1): >>43981388 #
9. remram ◴[] No.43980582[source]
I don't know how to read your comment other than "nothing hard is worth doing". Some things have benefits and drawbacks, is the existence of drawbacks always a non-starter for you?

I'm trying to phrase this as delicately as I can but I am really puzzled.

If someone wrote an article about how playing the harp is difficult, just stick with it... would you also say that playing the harp is a terrible hobby?

replies(2): >>43981392 #>>43983055 #
10. yodsanklai ◴[] No.43980583[source]
> It's a very complex

I find it relatively simple. Much simpler than C++ (obviously). For someone who can write C++ and has some experience wth OCaml/Haskell/F#, it's not a hard language.

replies(1): >>43980684 #
11. namuol ◴[] No.43980625[source]
There _are_ more than two programming languages, though. I feel like most of the debates about Rust devolve into the same false choice between safety and ease.

Before Rust I was hearing the same argument from Haskell or Scala developers trying to justify their language of choice.

I know Rust is here to stay, but I think it’s mostly because it has a viable ecosystem and quality developer tools. Its popularity is _in spite of_ many of its language features that trade that extra 1% of safety for 90% extra learning curve.

replies(1): >>43981514 #
12. namuol ◴[] No.43980684{3}[source]
Sure, C++ has a more complex spec, nobody can argue against that.

Complex is the wrong word. Baffling is a better word. Or counterintuitive, or cumbersome. If “easy enough for someone with experience in C++, OCaml, Haskell, and F#” were the same thing as “not hard” then I don’t think this debate would come up so frequently.

replies(2): >>43981521 #>>43981689 #
13. cheikhcheikh ◴[] No.43980897[source]
> maybe that's a language design smell

why

14. zaptheimpaler ◴[] No.43981065[source]
Learning any programming language at all feels 10x as hard to beginners, so you might as well say programming is not worth learning period in this case. Anything new has a learning curve to it.
15. devjab ◴[] No.43981118[source]
I think you can have a lot of debate on the design decisions on Rust, but I don't think the need for these articles tell you a lot about the language itself. I'd argue that Python needs articles like this more so than Rust does, but for entirely different reasons. In two decades of more and more programmers who aren't coming from an engineering background, I've yet to see anyone who used a Python generator or slots. Data Classes are less rare, but mainly in the form of pydantics "version". Which doesn't exactly matter for a lot of Python code... This is a world where 4chan can serve 4 million concurrent users an apache server running a 10k line PHP file neither of which have been updated since 2015... so you can be fine doing inefficient and entirely in-memory Python code 95% (or more) of the time.

That doesn't mean you should though. Imagine how much energy is being wasted globally on bad Python code... The difference is of course that anyone can write it, and not everyone can write Rust. I'm not personally a big fan of Rust, I'd chose Zig any day of the week... but then I'd also choose C over C++, and I frankly do when I optimise Python code that falls in those last 5%. From that perspective... of someone who really has to understand how Python works under the hood and when to do what, I'd argue that Rust is a much easier langauge to learn with a lot less "design smell". I suppose Python isn't the greatest example as even those of us who love it know that it's a horrible language. But I think it has quite clearly become the language of "everyone" and even more so in the age of LLM. Since our AI friends will not write optimised Python unless you specifically tell them to use things like generators and where to use them, and since you (not you personally) won't because you've never heard about a generator before, then our AI overlords won't actually help.

16. bsder ◴[] No.43981329[source]
> If a language needs an article like this, absolutely begging people to bite the bullet to learn it, maybe that's a language design smell.

The problem with articles like this is that they don't really get to the heart of the problem:

There are programs that Rust will simply not let you write.

Rust has good reasons for this. However, this is fundamentally different from practically every programming language that people have likely used before where you can write the most egregious glop and get it to compile and sometimes even kinda-sorta run. You, as a programmer, have to make peace with not being able to write certain types of programs, or Rust is not your huckleberry.

replies(2): >>43982704 #>>43983778 #
17. psychoslave ◴[] No.43981388{4}[source]
Well, it does look like there is a will to mimic religious social structure in the community, be it as a satiric form of it. I mean, I guess they purposefully named their pancakes cargo, as in "cargo cult", didn't they? Rustacean, rustomicon, and the other few words I saw leak out of the community all seem to go in the same spirit. I'm almost surprised they didn't went with more fancy terms for these core concepts of ownership and borrowing. Perl was also full of religious stuff like blessing your object, though Larry was actually more in the "true devot" side of the line.
replies(1): >>43982847 #
18. etbebl ◴[] No.43981392[source]
Maybe people need persuading to learn Rust not just because they think it's hard, but also because they think it's bad? Not everything hard is worth doing. Difficulty is just one of the factors to consider.

I started to learn Rust, but I was put off by the heavy restrictions the language imposes and the attitude that this is the only safe way. There's a lack of acknowledgement, at least in beginner materials, that by choosing to write safe Rust you're sacrificing many perfectly good patterns that the compiler can't understand in exchange for safety. Eventually I decided to stop because I didn't like that tradeoff (and I didn't need it for my job or anything)

replies(2): >>43982319 #>>43983093 #
19. NitpickLawyer ◴[] No.43981514{3}[source]
> features that trade that extra 1% of safety for 90% extra learning curve.

I remember both MS and goog having talks about real-world safety issues in the range of 50% of cases were caused by things that safe rust doesn't allow (use after free, dangling pointers, double free, etc). The fact that even goog uses it, while also developing go (another great language with great practical applications) is telling imo.

20. estebank ◴[] No.43981521{4}[source]
What you call "baffling", I call "different". Being different doesn't mean it's "complex" or even "hard" (in isolation), but it can be baffling, in the same way that driving on the other side of the road for the first time can feel baffling (but doesn't mean it's "wrong").
21. melodyogonna ◴[] No.43981636[source]
Rust design decisions are pretty hard to understand sometimes, Mojo is another language with a borrow-checker but it is not nearly as hard to learn as Rust due to making a few decisions. First is value semantics, in Rust people are told to always clone when learning, why isn't this semantics built into the language? It is what you have in most static languages - C, C++, Go, etc. This is the mental model many people come to Rust with.

Secondary, Mojo's lifetime does not tell the compiler when a value is safe to use but when it is safe to delete, in this way the lifetime is not scope based, references will extend the lifetime of the value they reference, but values will be destroyed immediately after their last use. In Mojo you'll never see "value does not live long enough".

Just these two design decisions defines away so many ergonomic issues.

replies(3): >>43982040 #>>43983851 #>>43991263 #
22. yodsanklai ◴[] No.43981689{4}[source]
Of course, this is very subjective. For someone who only knows python or javascript at a superficial level, Rust may seem out of reach. But if you're ok with the most common programming paradigms, I don't find Rust baffling.

I mean, you can't expect to learn a new language in a few days, it'll always take a bit of work. My feeling is that people complaining of the language being hard aren't putting the effort.

My experience is that Rust is a relatively small language which doesn't introduce a lot of new concepts. The syntax is quite intuitive, and the compiler super helpful. The borrower checker was the only new thing for me. I'm not an expert at all, but my experience is that after spending 2 weeks full-time reading books and experimenting, I was able to work professionally with the language without feeling too much friction.

On the other hand, after spending much more time on C++, I don't feel really comfortable with the language.

replies(2): >>43985502 #>>43986634 #
23. jbs789 ◴[] No.43981787[source]
The article focuses on the learning curve rather than the problem Rust is solving, as an observation. Think you need both of those to draw a conclusion as to whether it’s worth doing.
24. BlackFly ◴[] No.43981862[source]
The truth is that by the time you are a senior developer, you will have encountered the lessons that make rust worth learning but may not have truly understood all the implications.

Many people will think, I have a garbage collected language, rust has nothing to teach me. Even in garbage collected languages, people create immutable types because the possibility of shared references with mutability makes things incredibly chaotic that they look for immutability as a sort panacea. However, once you have immutable types you quickly realize that you also need ergonomic ways of modifying those objects, the methods you create to do so are often more cumbersome than what would be permitted for a mutable object. You wish there was some way to express, "There is a time where this object is mutable and then it becomes immutable." Enter the borrow checker.

Once you are borrow checking... why are you garbage collecting? Well, expressing those timelines of mutability and existence is a cost because you need to understand the timeline and most people would rather not spend that energy--maybe mutability or the poor ergonomics of immutable objects wasn't so bad. So, I garbage collect because I do not want to understand the lifetimes of my objects. Not understanding the lifetimes of objects is what makes shared mutability hard. Immutability eliminates that problem without requiring me to understand. Rust can teach this lesson to you so that you make an informed choice.

Of course, you can also just listen to me and learn the same lesson but there is value for many people to experience it.

replies(1): >>43987454 #
25. tcfhgj ◴[] No.43982040[source]
> people are told to always clone when learning, why isn't this semantics built into the language?

Because cloning as opposed to copying is expensive and it generates a new instance of a type. In C, you don't clone, you simply copy the struct or pointer, which will lead to a pointer to the same memory or a struct with members pointing to the same memory.

C++ on the other hand has a copy constructor, and you have to move explicitly, often generating unnecessary copies (in the sense of clone)

> Mojo's lifetime does not tell the compiler when a value is safe to use but when it is safe to delete,

What happens if you pass the variable mutably to a function?

replies(1): >>43982082 #
26. melodyogonna ◴[] No.43982082{3}[source]
> What happens if you pass the variable mutably to a function?

What happens in what manner? Mojo uses ASAP memory model, values will always be destroyed at the point of its last use. Mojo dataflow analysis will track this.

In terms of safety, Mojo will enforce `alias xor mutability` - like in Rust.

> C++ on the other hand has a copy constructor, and you have to move explicitly, often generating unnecessary copies (in the sense of clone)

Mojo also has copy and move constructors, but unlike in C++ these are not synthesised by default; the type creator has to either explicitly define the constructors or add a synthesiser. In Mojo, you can have types that are not copyable and not movable, these types can only be passed by reference. You can also have types that are copyable but not movable, or movable but not copyable.

27. whyever ◴[] No.43982319{3}[source]
> by choosing to write safe Rust you're sacrificing many perfectly good patterns that the compiler can't understand in exchange for safety

Historically, programmers drastically overestimate their ability to write perfectly safe code, so it's an enormous benefit if the compiler is able to understand whether it's actually safe.

replies(1): >>43982632 #
28. Ragnarork ◴[] No.43982632{4}[source]
The first part of your statement feels true, although that's... unverified and lacks actual backing up.

The second part of your statement is very debatable based on what safe means in this case, and whether it's an enormous benefit for a given situation.

There's plenty of stories [0][1] about Rust getting in the way and being very innappropriate for certain tasks and goals, and those "enormous benefits" can become "enormous roadblocks" in different perspectives and use cases.

In my personal and very subjective opinion I think Rust can be very good when applied to security applications, realtime with critical safety requirements (in some embedded scenarios for example), that sort of stuff. I think it really gets in the way too much in other scenarios with demanding rules and pattern that prevent from experimenting easily and exploring solutions quickly.

[0]https://barretts.club/posts/rust-for-the-engine/ [1]https://loglog.games/blog/leaving-rust-gamedev/

29. swiftcoder ◴[] No.43982704[source]
> There are programs that Rust will simply not let you write.

Can you specify a few of these programs?

I can see where Rust might not allow you to write something the way you want to, but I fail to see how a program would not be expressible in rust...

replies(1): >>43984589 #
30. conorjh ◴[] No.43982847{5}[source]
the dogmatic culture would probably be my first suggestion. i always ask why are there any CVEs for rust if its "memory-safe" but never get an answer suprisingly
replies(2): >>43983755 #>>43984581 #
31. atoav ◴[] No.43982909[source]
As someone who learned Rust, bur mostly uses Python in the day to day, I don't think Rust has a language design smell. It is just a very strict language with some of the strictness out there to ruin your day if you try to program Rust like it isn't Rust.

What that means is for example, if you have high aesthetical ideals and try to write object oriented code you will hit a brick wall eventually. Why? Notnbecause Ruwt is a bad language, but because you try to write Rust like it is Java or something.

Rust is a very nice language if you respect that there are Rust-ways of doing things that and that these ways are more data oriented than you might be used to.

The strictness can be daunting for beginners, but with increasing complexity it becones an absolute godsend. Where in other languages I find errors only when they happen, most Rust code just works (provided you write it in a Rust way), because the errors will caught during compilation.

That doesn't prevent logic errors, but these can be addressed with the absolute stellar test integrations. Now Rust is not all roses, but it is certainly a language worth learning even if you never use it. The ways it mitigates certain classes of errors can be turned into good coding practises for other languages as well.

32. casey2 ◴[] No.43983055[source]
Let me help you

If it takes the average person 1 million hours to learn rust then the average person won't learn rust

If it takes the average person 1 hour to learn rust then the average person will learn rust.

If you were designing a language which would you pick all else being equal?

To your question, no but I wouldn't be puzzled when most people pick up a guitar. (Both are so much more intuitive than any programming language so the metaphor sets false expectations. Slick political move, but probably just turns more people off of Rust)

replies(1): >>43983340 #
33. atoav ◴[] No.43983093{3}[source]
The thing is, if you want to learn Rust this site contains good advice on how to do it. I know, because I learned Rust.

Rust isn't a language you should pick up if you're not ready to put in the work. Just like you shouldn't go for full blown automotive grade C coding if you just want to learn coding quickly to get a job or something.

Rust has a steep learning curve, but the harder part (as mentioned in the article) is to unlearn patterns from other programming languages if you think you're already a good programmer.

replies(1): >>43983626 #
34. dwattttt ◴[] No.43983340{3}[source]
> If you were designing a language which would you pick all else being equal?

But why would you think all else is equal? You might not agree with the tradeoffs Rust makes, and it's not as if there's a perfect language for all uses, but it absolutely makes hard software easier to write.

I've had the opportunity to debug weird crazy memory corruption, as well as "wow it's hard to figure out how to design this in Rust", and having come to terms with things much like this blog post I now get more work done, with less corruption _and_ design problems.

35. prmph ◴[] No.43983626{4}[source]
I think one can understand Rust and still dislike it? Not every criticism of Rust comes from thinking it is too hard. I appreciate it for what it is and the problems it tries to solve. I just don't like many aspects of design of the language, seeing it as unnecessarily ugly for achieving it's aims.
replies(1): >>43987415 #
36. psychoslave ◴[] No.43983755{6}[source]
CVE is not only for memory leak though, while eliminating (or even drastically reducing) such a class of issue is a fair point to advertise, it should not be confused as a magic safety facility that makes go away any security concern.
37. empath75 ◴[] No.43983778[source]
> There are programs that Rust will simply not let you write.

If you're writing purely safe code, I will say this is true in a practical sense, but you can almost always use unsafe to write whatever you think rust won't let you do.

38. dsego ◴[] No.43983851[source]
> but values will be destroyed immediately after their last use

Is this reference counting?

replies(1): >>43985733 #
39. steveklabnik ◴[] No.43984581{6}[source]
> i always ask why are there any CVEs for rust if its "memory-safe" but never get an answer suprisingly

The answer is straightforward: bugs exist. Even in formally proven software, mistakes can be made. Nothing is perfect.

Additionally, memory safety is a property that when people talk about it, they mean by default. All languages contain some amount of non-proven unsafe code in their implementation, or via features like FFI. Issues can arise when these two worlds interact. Yet, real-world usage shows that these cases are quite few compared to languages without these defaults. The exceptions are also a source of the CVEs you’re talking about.

40. steveklabnik ◴[] No.43984589{3}[source]
They mean in Safe Rust. Unsafe is included in Rust for this reason.
replies(1): >>43985098 #
41. swiftcoder ◴[] No.43985098{4}[source]
Is safe rust not Turing complete? I can see the argument that a purist "safe rust only" program might be slow, but it still will be expressible
replies(1): >>43985237 #
42. steveklabnik ◴[] No.43985237{5}[source]
Turning completeness doesn’t take efficiency into account, nor the reality of things like “call into the operating system so that you can display output” that are necessary when building real systems.
replies(1): >>43986479 #
43. icedchai ◴[] No.43985502{5}[source]
C++ is a huge and complex language. I worked in it, on and off, from 2002 through 2014 or so and never really felt comfortable, either. Everyone seems to use their own dialect.

(I'm working on learning Rust on my free time.)

44. melodyogonna ◴[] No.43985733{3}[source]
Nah, deterministic compiler analysis. Something they call ASAP memory management
45. swiftcoder ◴[] No.43986479{6}[source]
With respect, I think that's moving the goalposts. If we have defined out of existence all forms of I/O, then what are we actually discussing?
replies(1): >>43986672 #
46. ModernMech ◴[] No.43986634{5}[source]
My feeling is that Java / C++ / Python / Javascript are all really the same language when you get down to it. Rust borrows from OCaml more than an other popular imperative languages (the first implementatoin by Graydon Hoare was in OCaml, so the inspirations abound), and therefore it really is quite different to a lot of devs who have never seen the functional paradigm. Good rust is written as a mix of imperative with a strong functional flavoring. Bad Rust is when you try to do everything by mutating arrays over iteration as you would do in imperative languages.

For me, I almost never write "for loops" and "if statements" in Rust; instead I use "functional iterators" and "match expressions", which interface with the borrow checker more nicely.

For example, iterating over an array while modifying it is a common pattern in imperative languages that compiles fine but often causes hard to reason about logic errors during runtime. In Rust, such a thing would cause compile time errors. So instead you rewrite to be more functional, it compiles, and then the magic is it just works, which is a common property of functional languages like Haskell.

IMO a lot of the consternation about the cost of the learning curve is because developers haven't realized once you get past it, the benefit is your code more often is just correct and therefore you run into fewer runtime bugs. In other languages you get the code compiling faster, but then you spend a great deal of time debugging things at runtime which you didn't anticipate at compile time.

47. steveklabnik ◴[] No.43986672{7}[source]
We haven't, that's why Turing completeness is not relevant for the question at hand.

I can implement the non-IO parts of Brainfuck with safe Rust, so it is Turing Complete. That doesn't change the fact that there are useful programs not expressible in it.

48. pessimizer ◴[] No.43987415{5}[source]
I think the person you replied to never said "only people who do not understand Rust dislike it," or anything similar to that.

Even pretending that they did, I don't know if "appreciat[ing]" Rust means that you're saying that you "understand" it. It seems like choosing a different word in the second sentence of a two sentence argument may be an subtle way of hinting that you don't know Rust, although you've read articles about Rust and made judgements about it. If this is true, then it doesn't strongly support the first statement.

replies(1): >>43989284 #
49. zahlman ◴[] No.43987454[source]
> Not understanding the lifetimes of objects is what makes shared mutability hard.

Well, no; in my experience the difficulty overwhelmingly comes from thinking about the semantics. I.e.: these two clients currently share a mutable object; should they observe each others' mutations? Or: if I clone this object, will I regret not propagating the change to other clients?

replies(1): >>43992542 #
50. rat87 ◴[] No.43987964{4}[source]
There are definitely some c++ features that some people have been clamoring for for over a decade

Pattern matching for one(although to be fair that's been in rust from the start)

51. prmph ◴[] No.43989284{6}[source]
I'm not sure you fully grasp what I'm saying.

I'm seeking to draw a distinction between disliking rust for the real (or perceived) difficulty of learning/using it, and disliking it on principle, because you don't like it's trade-offs, approach to achieving it aims, syntax, type system, etc. This dichotomy is meaningful irrespective of the level of experience one has with Rust, beyond a certain level (and for the record I believe I have the requisite level of knowledge of rust to have an informed opinion on it).

For example, I don't know much Haskell. It seems to me (and to many other I read online) like it would be difficult to learn (and maybe use), although I'm familiar with functional languages in general. However, based on the little I've learned about it so far, it is a language I'd absolutely love to dig much deeper into as time permits, because almost everything about it makes so much sense to me.

Here's something amazing, I started to design my ideal language, before I started learning Haskell, and almost every language construct in Haskell I learn about seems to match exactly how I'd designed my language by coincidence (even down to keywords like "where", "do" blocks, etc.)

52. aw1621107 ◴[] No.43991263[source]
> but values will be destroyed immediately after their last use

For what it's worth, it appears this was considered for Rust at some point but the devs decided against it. As described by Steve Klabnik in 2018 [0]:

> This was called “early drop”, and we didn’t implement it because of worries about unsafe code. Yes, the compiler could tell for safe code, and it would be fine, but unsafe code cannot, by definition, be checked.

[0]: https://users.rust-lang.org/t/drop-values-as-soon-as-possibl...

53. BlackFly ◴[] No.43992542{3}[source]
If you understand how it will work then that is just a decision to be made and a decision (although design is not necessarily easy) isn't what I would call hard: it is the ordinary work. By difficulty I mean bugs and bugginess, and bugs happen in this area because there are unintentional race conditions on the mutability. Total immutability is merely one way to force yourself to understand it, if those two clients need to observe the modifications then you have to propagate the changes manually instead of relying on shared memory semantics. But worse than that, even if you decide that they should observe the changes, then you can often end up with tearing if you are changing multiple properties non-atomically. That is a lifetime issue: the mutable reference is allowed to coexist at the same time as an immutable reference. In rust you cannot share an ordinary reference to have runtime observability like that, once shared the object becomes immutable. This forces you to use internal mutability via a RefCell and the exclusive/shared reference is enforced at runtime to eliminate tearing. Lifetimes of these borrows matter and how they matter depends on the choice of semantics, but I wouldn't call the choice the hard part.
54. tomhow ◴[] No.43992716[source]
This comment set off a generic programming language debate, which is the just the kind of geek message board cliché we're hoping to avoid on HN!

Eschew flamebait. Avoid generic tangents. Omit internet tropes.

https://news.ycombinator.com/newsguidelines.html