Hacker News new | ask | show | jobs
by 4pkjai 1173 days ago
I really like the speed of rust. It’s very difficult to learn it though
4 comments

As someone who came mostly from Python and some C: I must say the most difficult part was stopping myself from forcing aesthetical ideas of how to structure code from the other languages into Rust.

There are three points here:

- Rust lends itself to certain structures (that you might not be used to) and makes others very harder to pull off (that you might be used to). The trick is not try to do the latter when the former is perfectly fine. E.g. me trying to do object oriented programming in Rust, or starting off with a linked list as a C programmer

- Rust can be written on different levels. For example you can go for "perfect" code in terms of performance and dive into things deep or you can just not bother at all and do the totally naive thing and still end up with quite fast programs most of the time

- Rust has a type system that it strictly enforces. This makes some things harder, others simpler. Make sure to be aware what you can do with a type system and why it can be a good thing to have one.

As a javascript/typescript developer I took a notion to learn Rust and it has been hard but rewarding on a personal level. Im concerned though that I'm learning somwthing that has very few if any real jobs right now. All I see is block chain nonsense. In your opinion is there much chance that this will change?
To be honest I would say Rust is worth learning even if you were to never use the language at all after learning it.

The problems Rust attempts to tackle are fundamental problems you will encounter in many languages. Understanding how to program or how to think in order not to get those problems in the first place is the thing Rust can teach you. A lesson that any programmer can learn from.

That being said Rust has great testability and interopability. I myself use Rust in some (work) projects in conjunction with Python.

So I definitly see some future for the language, also commercially. But even if I wouldn't, I would still recommend learning it.

Interesting take. So far I agree with what you're saying. It has given me more insight into how memory management works than I'd had before. I think one of the things that bugs me about javascript is how difficult it is to track down memory leaks. A problem I've often faced when dealing with large codebases and other peoples code. The memory management in Rust via the borrow checker is a very elegant as a solution. It's also a pain but not as hard to deal with as people make out.
"the most difficult part was stopping myself from forcing aesthetical ideas of how to structure code from the other languages"

Coming from C and PHP to JavaScript gave me similar cognitive dissonance.

Syntactically these languages are very similar, but the semantics require to rethink quite much if what I learned.

Yeah, I wish there was a good list of things to hint you aren't being rusty. When you are cloning everything or have arc on everything that is a pretty good hint, but I'm sure someone could put together a better list than I could.
Clippy can help you to write more idiomatic Rust, so if you aren't already, definitely check out the clippy lints for a working program you wrote:

  cargo clippy
Clippy won't tend to spot unnecessary Arcs and similar architectural mistakes, however it would notice if you act as though things aren't Copy when they are [e.g. you've probably never 100.clone() but if you did Clippy would point out that's just 100 and the same would apply to types where it's less obvious that they're Copy and you might have forgotten]
Yeah clippy is amazing, but I was thinking things everyone has to do sometimes in rust, but that if you find yourself having to resort to them often might be a hint that your overall paradigm might need a tweak to fit well. I didn't mean unnecessary arcs, but rather necessary ones. I find that if I donthings the way Ferris wants me to, that I dont have arc, rc, refcell, or clone very often, and nothing ends up needing to derive copy. When Ferris is happy my life is easier.
The trick to learning Rust is to first start learning C++; that way your motivation to learn Rust increases even further and you start getting the feeling that Rust is easy ;)

This is similar to the psychological trick of how an obese person, to make himself/herself feel better, stands next to an even more obese person :)

Not just any c++, I'd recommend performance aware modern c++. It leads towards the functional-ish zero-copy lock-free thinking rust rewards. I've been told ocaml or f# programmers also find rust easy.
I think there are definitely aspects of Rust that OCaml/F# developers would find easy because it borrows a lot of syntax and concepts from ML. But to be honest those bits are the easy parts or Rust. Knowing OCaml or F# won't help with the borrow checker.

I think C++ programmers are probably the ones that are likely to find Rust easiest because they should be familiar with lifetimes even if they never really had to write them down.

It is the speed of any compiled language to native code.
I mean, that's probably true in some broad categorical sense, for the question of "speed of execution of final program" which it's not clear your parent meant.

However it's not true in the specifics, there are so often little tweaks Rust has that otherwise comparable languages don't have that squeeze out a little better performance and this adds up. For example:

C++ std::vector is a perfectly respectable growable array type right? But no less than Bjarne Stroustrup observes that actually, to his apparent surprise, the reserve() method on this type isn't very effective in using what a programmer knows about the growth of a particular instance for improving upon the amortized exponential growth curve. Rust's Vec is superficially the same type. But it has a subtly different API and in the process it unlocks what Bjarne missed, using Vec::reserve() does allow programmers to successfully guide the growth curve and benefit. [[If you need the equivalent of the C++ API, Rust provides Vec::reserve_exact() for you, but you probably don't]]

Still, for a lot of us there are more important "speeds" than the performance of running code. Rust does a lot of "shift left" on errors, where more of the defects in your first attempt to solve the problem are compiler errors, which you notice quickly and can fix, rather than them failing tests, being spotted in review, or worst of all, getting all the way to an actual user where they cause real problems.

One speed that Rust doesn't have on its side is compilation performance. Rust is not going to be the fastest language for turning correct high level code into running binaries.

> One speed that Rust doesn't have on its side is compilation performance.

I noticed that `cargo check` alone is plenty fast, and when you give it a program with a type issue to check, it reports errors nearly instantaneously (< 0.5s).

So this is probably not all the type checking (including borrowchecking) that slows things down, but the phases that happen later, likely code generation. Which leads me to a question - why is code generation so slow even in debug mode compared to other compiled languages? (this is one thing that Golang does right).

Well I guess we can always play micro-benchmarks game if you want to go down that path, including selecting specific compiler toolchains and flags while making it a point that it is a property of language XYZ, to make it even better.
I don't see the std::vector example as a micro-benchmark, we're not talking about wasting a few microseconds in a contrived example, we're talking about destroying the amortized constant time growth performance of the data structure because of an API goof.
Which std::vector, from which C++ compiler, targeting what OS, with what set of compiler flags, and optimization passes?
You'd think right?

Except nope, it's an API design problem. If you write a std::vector or equivalent but where reserve has analogous behaviour to Vec::reserve you can't do Vec::reserve_exact at all and that can really hurt in other cases.

There really are two distinct features and C++ specifies a single API call.

You'd think right?

Except nope, it's an API design problem. If you write a std::vector or equivalent but where reserve has analogous behaviour to Vec::reserve you can't do Vec::reserve_exact at all and that can really hurt in other cases.

There really are two distinct features and C++ specifies a single API call.

Oh, no, it isn't. Take the speed of Haskell or Prolog. They are much slower than Rust at runtime.
There are even more:

  - Java (compiled AOT, anyone remembers how dead slow code GCJ produced?)
  - Go (not always as bad as Java, but not perfect either)
GCJ was always a toy compiler, if you want good AOT Java code check the commercial JDKs that have been in business for the last 20 years.
First of all Prolog is usually not AOT compiled rather JITed, secondly regarding Haskell, it is an issue with the skill set of the developer more than anything.
Given expert skills in both Haskell and Rust, Rust is by far the fastest performing language. And if you use idiomatic Haskell the difference is even bigger. E.g. if you use lots of Monad transformers and lazy evaluation.
The optimisation lies between keyboard and chair.

Plus if one lacks the ability to write high performance Haskell code, they definitely aren't experts.

Check out Odin, it's breath of fresh air, the syntax is minimal and well thought out, so unlike rust or zig (and much like jai*), things are consistent and make sense**.

(*) https://pixeldroid.com/jailang/overview/Features/Factorabili...

(**) https://www.gingerbill.org/article/2018/03/12/on-the-aesthet...*