DEV Community

Discussion on: Rust or Go for web development?

Collapse
 
leob profile image
leob • Edited

Good points, however when you say:

"Writing Rust code comes pretty close to how you write code in other popular languages. That's not that much new to learn"

... then I really need to disagree! I have minimal experience with Rust (and Go), but having worked through most of the docs/tutorial, and subsequently having like a week (yes just a week) hands-on experience with a real-world codebase, what jumped out for me was this:

Rust has quite a strong Functional Programming (FP) feel to it - it often reminded me of Haskell which I dabbled in for a while; lots of emphasis on map/filter/reduce type of things, and declaring (abstract) data types.

This leads to Rust code tending to be much more "declarative" than Go code (which tends to be very much imperative, generic map/filter/reduce kind of code isn't even possible really for lack of a generic type system).

So, while I only have 'experience' with both Go and Rust on a "tutorial" and glorified "hello world" level, conceptually I was much more impressed with Rust as a programming language.

My feeling was that Go is very much "dumbed down" - especially the lack of generics sticks out like a sore thumb, because this forces you to write for loops ad infinitum ... the code you write tends to be very imperative. In that regard it sort of feels like a step back. Rust (at least that's my opinion) is a lot more elegant as a programming language.

On the other hand:

  • the Go compiler is insanely fast! Rust's compiler is s-l-o-w ...

  • Rust misses the biggest asset of Go which is the easy async/concurrency model

  • Employability: the number of Go jobs is probably an order of magnitude larger than the number of Rust jobs

On the other hand, the way Go manages its dependencies (with GOPATH and so on, and with its prescription of how you need to physically organize your files/directories) is indeed a bit "weird", but it didn't bother me really - if you stick to the conventions then it just works (again however, Rust's module system, while more complex, is a lot more elegant).

So, conceptually I'm much more impressed with Rust, but I acknowledge that Go might be more practical for "real world" purposes.

Now if Rust would acquire Go's concurrency features (Goroutines) and Go would get generic types, then the competition between the two would become really interesting!

Collapse
 
oliverjumpertz profile image
Oliver Jumpertz • Edited

Thank you really much for your reply!

Yes you are right, Rust has a heavy emphasis on FP-style.
But consider this two examples:

JS:

function foo(bars) {
  return bars.filter((bar) => bar.isGreat).map((bar) => bar.give());
}

Java:

Collection<Bar> foo(Collection<Bar> bars) {
  return bars
           .stream()
           .filter(bar -> bar.IsGreat)
           .map(bar -> bar.give())
           .collect(Collectors.toCollection(LinkedList::new));
}

These are only two examples, specifically tailored to your point of Rust's FP-style.
What I just want to showcase is: It's not that much new. If you got the concept somewhere else, you'll get it within Rust.
The same could be made up for variable declaration, and nearly everything else.
It's just a similar style. :-)

On Go being dumbed down:
Yes, absolutely.
IIRC, one reason for Rob Pike, Ken Thompson and Robert Griesemer to design Go the way it is, is, that Google faces some unique challenges.
They had to invest an enormous amount of money to get their C++ infrastructure right and they have to onboard a lot of new engineers very often. Concurrency, of course, is very difficult and so they wanted to create something very easy to understand and write working Software with. They also wanted to fight the enormous build times Google's C++ projects sometimes have.
Their intention was to create a language with the minimal feature set needed to accomplish a task at Google scale by negating the drawbacks they previously faced.

Rust's compiler gets faster and faster with every release, but for all the checks and safety features it comes with, there need to be some drawbacks.

What do you think about the following?

async fn foo() -> u8 { 5 }

fn bar() -> impl Future<Output = u8> {
    async {
        let x: u8 = foo().await;
        x + 5
    }
}

It may not be that fancy as a go func... and then using channels and so on, but we're getting closer. :-)

Edit regarding the job situation:
I think we will have to give it a little more time. Let the ecosystem mature more and I'm, pretty sure that, as the community grows, job opportunities will also arise.

Thread Thread
 
leob profile image
leob

Haha yes you're right - the map/filter/reduce style isn't that new really if you look at what you can do in Java and Javascript.

So yes, Java and JS (but not Go) already allow you to do this. But, arguably, Rust takes FP a step further - its type system is very refined and reminded me of Haskell's, which enables Rust to do some really nifty things.

So my point was more that Go does not allow you to use this style (at least not in a generic way).

But I understand the point about the problems that Google wanted to solve with Go.

I was already impressed with the size and quality of both the ecosystem and the community around Rust - ORM is there, web server/REST API server, remoting etc. If they are able to speed up the compiler a bit, then I think Rust can have a good future competing with Go.

By the way, your example of an async function makes sense, Go Routines aren't that much more than the "Promises" and "async/await" style that we already know from JS, but with some nice "syntax sugar".

How would you implement Go's "channels" in Rust?

Thread Thread
 
oliverjumpertz profile image
Oliver Jumpertz

Yea, our opinions seem to match there. :-)

If we simplify Go's channels into just an unbound stream of typed messages, we could use reactive streams RxRust e.g..
But we won't be able to exactly reproduce the comfort of language level features for asynchronously waiting for a return value, while the runtime takes care of halting the thread execution until said response really arrives.

Thread Thread
 
leob profile image
leob • Edited

Right, I see, yes that's what Rust doesn't have, Go's runtime ... so that means it would be hard to implement it in exactly the same way.

Some "history" on Reddit (reddit.com/r/rust/comments/a6f85e/...

"While the concept of 'goroutines' is unique to Go, they represent a feature of many languages known as green threads, where there are an arbitrary number of green threads per system thread.

Once upon a time in pre 1.0, Rust natively implemented green threads. It was decided however that green threads were somewhat antithetical to Rust's philosophy, particularly the aim of having a minimal runtime, so they were dropped in favour of system threads."

So okay, you can achieve the same thing but it will probably "feel" less seamless than it does in Golang.

Thread Thread
 
oliverjumpertz profile image
Oliver Jumpertz

Yes, exactly. :-)

Thread Thread
 
oliverjumpertz profile image
Oliver Jumpertz • Edited

One more thing I actually forgot about and which may actually help and is more native than using something like Rx: Rust channels

Thread Thread
 
leob profile image
leob

Right! so there you have it ... however when I read the article that these Rust channels are for "native OS threads" rather than the 'green threads' or coroutines that we're talking about?

Thread Thread
 
oliverjumpertz profile image
Oliver Jumpertz

Yep, no green threads for Rust. Those channels are indeed thread backed. :-)