Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The DB space for Rust is a bit young, though there are several good projects like sqlx making it much more pleasant.

Rust shares many of the benefits of Go:

- statically linked binaries for ease of deployment

- good concurrency

- builtin testing framework

But it's a much sharper tool than Go:

- Really great error handling with Result/Option and the ? marker

- Like, really really good error handling, esp compared to Go

- Very pleasant logging and tracing

- Serde is fantastic at automatically serializing/deserializing datastructures

- Generics make Map/Reduce/Filter really easy and readable

- Really good project management through modules/Cargo.toml

- Crates.io is like NPM - really discoverable and easy to upload (with its goods and bads)

- FFI with Swift, C, C++, Node, etc to share code everywhere

- Builtin documentation

- Builtin benchmarking

- Powerful hygienic and non-hygienic macros

There's a lot more. I would say people choose Rust over other web frameworks not because of the language, but the emphasis on great tooling. Being able to test, document, benchmark, deploy, package, with a language that feels like a child between Go, JavaScript, and C++ is very attractive. Plus, it's fast - like really fast - and it's really obvious where optimizations can be made when the time comes.

I've worked a decent amount with Go, but I'm also frustrated with the size of projects balloon. When I compare my Rust and Go code, the Rust code ends up being much smaller (LoC) and much more dense/terse.

I've been working with it for a few years now, and I'm 100% willing to trade some complexity when doing Advanced Stuff (tm) for the 1st-class tooling. I hate having to decide which testing/documentation/building/benchmark/etc framework to use in other languages. I just want to build, not futz around with Jest/Babel/Webpack/Poetry/PyEnv/Opam/CMAKE etc.

If you're looking into using Rust for web, I recommend https://github.com/http-rs/tide - it's the most pleasant web framework I've ever used.



I personally prefer Rust to Go for things that have hard resource requirements/limits, but there’s no denying that Go is much easier to program than Rust.

You don’t need to know much more than Python/Ruby to get something done in Go, whereas Rust needs a C++ or Scala or Haskell or whatever background.

Rust places too much mental workload on a programmer to make the compiler happy.

The Go compiler is much more human friendly.

Swift is a nice mix of all worlds, IMHO. Would be nice to see that get more server-side use.

At our Scala-centric company, Go gets used a lot more for one off tasks and microservices.

We rebuilt one Go service in Rust just to get familiar with it and no one has written more Rust since.


I dabbled a bit with Go and now I am trying Rust. I did find programming in Rust a tad difficult than with Go, but as I get used to concepts (borrow checking, Move vs/ copy, lifetimes etc.) I am liking it better than Go. With Go I feel there is an element of deceptive simplicity, which catches up with you as the problem space gets complex. I never became comfortable with doing object oriented programming with Go, which has not been the case with Rust. In addition in Go I find the project setup and settings like GOPATH, GOBIN quite confusing. In contrast Rust has _cargo_ which has less cognitive overload.

I think it would be good if one dabbles a bit with both and pick one which one feels resonance with. That being said probably one need to give a bit longer time for Rust to be comfortable with it.


> I never became comfortable with doing object oriented programming with Go, which has not been the case with Rust.

Ouch, OOP in Go is just asking for a trouble. "Inheritance" by embedding anonymous struct/interface should be rarely used. Playing with a magic dependency injection, reflection mocking often do not leads to anything good too.

> In addition in Go I find the project setup and settings like GOPATH, GOBIN quite confusing.

I guess you work on Linux :) Yeah, it is weird, I am glad they have improved that flow by guessing empty GOPATH will be equal to $USER/go/ directory. GOBIN is actually not needed, only if you have used dep dependency manager, which for many years is deprecated.


> but there’s no denying that Go is much easier to program than Rust.

Well here I am to deny it. I personally find Go super hard to write anything that is not a few lines of glue code (and in that case I just reach for Node).

Rust made me lazy. It's just so easy to be guided by the compiler and the architecture that emerges naturally is just so beautiful and easy to navigate.

I don't like Rust for its safety guarantees, I just find it pleasurable to write and even better to read. Safety is just a plus.

I'm not saying this is a universal truth though, Rust just fits my mental model. It isn't even a matter of past experience: I code frontend JS for a living (though I've been exposed to all kinds of code throughout the years) and I actually enjoy JS.

I tried really hard to like Go. I just couldn't.


> Well here I am to deny it. I personally find Go super hard to write anything that is not a few lines of glue code (and in that case I just reach for Node).

> I tried really hard to like Go. I just couldn't.

I would expect something opposite for most of programmers. Especially, because Rust support in VSCode/JetBrains IDEs was not very good for many years. However, during talks with various people, I have noticed the Go was natural choice for many former Python or Ruby devs, while Node/Java guys had problem with adapting to it.

Personally, when I take a look at the Rust code it feels like some ECMA Script in a compiled world.


I agree. Go just lets you get away with writing garbage.


TBH I'm kind of frustrated with Swift's lack of dynamic dispatch options, so things like network models, network service interfaces and testing mocks need to be code generated, while in JVM and Objective-C land, you don't need to do the same.

Swift's Codable is doing code gen under the hood, so it also has a binary size and compile time cost.

Swift also doesn't scale that well with core size like many other languages do, so your compile time is not easily fixable with large thread ripper style workstations.

Do you have similar issues with golang and rust? At least golang was designed to be compiled fast.


Rust has similar issues with dynamic dispatch (but you're probably better off avoiding mocking anyway). I believe there are libraries to use conditional compilation to switch in mocks for test builds if you really want them.

Compile times are definitely a pain point in Rust, but from what I've heard the Rust compiler is pretty good at scaling to multiple cores (my machine only has 2, so personally that doesn't help much).


I find it easier to either use conditional compilation or traits for test substitutes. Using dynamic dispatch for it is more trouble than it's worth IMO.


Can you expand on “needs a C++ or Scala or Haskell background”? C++ would probably help you appreciate what Rust brings to the table, but I don’t see how any of them fit in when learning to use Rust in practice.


One way of looking at Rust is that it is kinda at the intersection of three different language families: {Ruby,Python,JavaScript} x {C,C++} x {OCaml, Haskell, Scala}

“Needs” is a bit strong but “may find some things familiar and therefore easier” is a common refrain.


That makes more sense. I'd probably phrase it as: "if you are familiar with a lower-level language and a functional language, you'll likely have an easier time learning Rust".


Yup, I’d agree with that.


Not the OP, but I agree. Also, coming to Rust from a higher level language is very hard. Beginners who do so cannot understand why something like this:

    fn foo() -> &str {
        &String::from("foo")
    }
Does not work. Whereas coming from C or C++, you will appreciate the safety guarantees the borrow checker is giving you.

Learning Rust coming from an OO background is also hard, as you have to adapt to the more functional approach of the Rust type system.


There's definitely content to be learnt. But I'm not sure I'd say it's very hard. I came from JavaScript, and I found that the Rust Book was very good at explaining these kind of issues, so even though they were new to me they didn't cause too many problems.


That makes more sense - it's definitely true that knowing a lower-level language and a functional language gives you a leg up when learning Rust.

As for your example, even C and C++ devs would squint a bit at why that code doesn't compile: you're allocating a string on the heap, so why can't you return a pointer to it? Also, I think str vs. String is usually confusing at first, regardless of your background.


I think analogous C++ code is a bug, the text might be a heap allocation (SSO may stash it inside the object) but surely the string object is local and lives on the stack. When the function returns that local object no longer exists and the reference to it is now dangling ?

I would say that the relationship between str and String was what most surprised me. I at first assumed the underlying primitive would be String since str is what you get when you borrow from a String, but it isn't. str is a built-in, whereas String is just a type defined in the (optional, this is a systems language) standard library.

If your environment can't afford memory allocation, you can't have Strings but you can use str just fine, that's a built-in. Since you lack allocators obviously you won't be going around minting new strings but str is perfectly fine for stuff like substring operations or comparisons.


> Also, I think str vs. String is usually confusing at first, regardless of your background.

Yes, of course. Rust has some new concepts that will be confusing at first, regardless of your background. You still have to understand Rust's destructors to understand that example. I didn't mean to say that it is impossible for Rubyists to learn Rust, or that C++ devs would understand Rust immediately.

Perhaps a better example:

    fn foo() -> &usize {
        let x = 50;
        &x
    }


From my experience I found the ideas of move semantics from modern C++ directly relatable to ownership and move vs borrow. I also found the FP ideas from Scala, pattern matching, combinators, result and option monads directly useful in rust.


I would have said it was mor like ocaml.


> When I compare my Rust and Go code, the Rust code ends up being much smaller (LoC) and much more dense/terse.

Yes, but is it more readable too? The obfuscated C contest also tends to produce a lot of dense/terse code, but you probably wouldn't want to use that in a production system...


In my experience, Rust code is relatively easy to read, even by developers with no Rust experience.

Of course, you can write hard to read code. But that's not typically what comes out of a process of writing production software.

That's not to say that someone with no experience will fully understand the ownership transfer & borrowing that's happening, but that's just stuff you need to do for the compiler. Reading code that already compiles, you can mostly ignore that and focus on the program logic.


Yeah, readability is high, it's writing that can be a bit harder IMO.

Especially for someone unfamiliar with rust, it can be hard to really know why someone is using self, &self, or &mut self. Yet the code reads the same.

That's the funny thing about rust.


The compiler is supposed to tell you when you get it wrong. This does leave design issues on the table, but it's also good for those to be addressed explicitly, by the more senior people on the project.


Rust is one the hardest language to read. Take two people that never used Go or Rust and make them read code, good luck with Rust.


So I have opened golang.org:

v1, ok1 := <-c1

Not sure what is difference between := and = and what is that arrow. But if I'm going to do something with the language - I guess it will be easy to find out. Like with Rust.


Sure - except that in Go there are (my impression after taking a look at various Rust resources) far fewer things you have to find out this way than in Rust. Which, of course, some view as a limitation, others view as a plus for Go.


I'm a newcomer to Rust, and find it relatively easy to read, at least at the level of "what is this code doing?" (Not necessarily "why did they need to specify lifetime there?")

The major exception to this are cases where authors use macros to invent their own DSL inside Rust code. This sort of thing seems common in the Servo codebase, amomg others. It reminds me of C macros or Python metaprogramming magic, both of which directly led to some incredibly difficult past debugging experiences.


It depends on what you're trying to read. If you want to understand every technical detail (e.g. who owns this variable) then Rust is great. If you want to understand the business logic behind it (e.g. under what circumstances is a customer allowed to return that product) then Rust is not so great as you would have to mentally filter out all the technical noise.


Map/Filter/Collect/Reduce, all built on generics make code much more readable than their Go counterparts. I can make a frequency map simply by drain and collecting a vec into a hashmap - maybe 4 lines of code.

The density comes from being able to share common functionality behind generic interfaces, so I don’t have to reinvent the wheel for every new project.

I find that most projects I make look the same internally, unless I start pulling some “clever” optimizations like custom allocators or self-referential structs.


"good concurrency"

Async rust is very messy and a pretty big issue atm. The tooling on the IDE side is subpar compared to Go.


To write custom futures? Yes, you need to understand Pin and some advanced stuff.

To use? Eh - I just turn on async_std with the Tokio flag and write go-like code with async tasks. No issues thus far.


What's the deal with cancellations? If you're coming from Go, the context package makes it convenient to do.


Funny you mentioned the context package, as it was pretty hacky way to work around the cancellation problem.

There are some pain points with cancellation in Rust. Dropping a future cancels it, but that requires ownership over the future, and may cause unexpected behavior due to the nature of futures state machines. This, along with many other issues, is being discussed by the async working group: https://github.com/rust-lang/wg-async-foundations/issues/65. If you have specific suggestions, or a problem that you faced, please open an issue! It is really appreciated - async rust's problems cannot be solved without community feedback and engagement.


I switched to rust-analyzer and it made a huge difference. Have you tried it?


I'd be interested in hearing what you think is a problem in async Rust.


I'm not the one you responded to, and I haven't used Rust much myself, but one of the issues I've seen raised several times is that its async ecosystem is fractured. You have to select an async stack, and sometimes different libraries and frameworks use competing stacks, causing problems.

It's not like JavaScript or Go where everything is just built into the language afaik.


There’s been a decent amount of standardization on top of Tokio’s implementation of async (green threads). If a library didn’t support it at first, they probably now do using features in your project.toml requirements.[1][2] That said, I agree the standard library isn’t the size or utility of Go’s nor is the ecosystem as wide as Go or npm.

Personally, I’m looking forward to the next few years when more and more companies reveal what patterns they use with Rust development. I think Rust is missing the kind of boost that Rails gave Ruby, for example, or that TypeScript and React gave Node/SSR. Or that Pandas gave Python.

1. https://doc.rust-lang.org/cargo/reference/specifying-depende...

2. https://doc.rust-lang.org/cargo/reference/features.html#depe...


Your reply has piqued my attention, because as a person who develops in Go (and in other programming languages) I cannot put any > or < between Rust and Go - they are clearly tools dedicated for other type of applications.

I won't try to play as a Go devil advocate, because I don't feel good enough today to start such discussion.

What is the worst thing I have experienced in Rust? Lack of good packages, especially if we speak about cloud stuff (rusoto and google-api-rs). Human resources put from cloud providers are very scarce. As longer I dived into the Rust the more I felt I am alone freak, because I had to work more hours to achieve the same result as in Go, PHP, Kotlin, TypeScript, C#. My use case of Rust was a GraphQL gateway (gRPC+HTTP) and after few weeks of idea verification the project was dropped. Mostly because instead of developing business logic the team was focused to implement own libraries for Google Cloud and other SaaS offerings on their own. Ridiculous, but Mozilla devs [0] went the same way by taking the whole job on their shoulders and they were generating subsets of APIs, because they cannot find any good, official libraries. It is frustrating and time consuming making Rust completely no-go for many teams.

> I've worked a decent amount with Go, but I'm also frustrated with the size of projects balloon. When I compare my Rust and Go code, the Rust code ends up being much smaller (LoC) and much more dense/terse.

I can exactly the same about the Rust. I think it was not the problem with tool but with something between chair and keyboard. I had a pleasure to see and refactor very bad Go code and actual ballooning was never a case if you have applied Clean / Solid architecture. The "ballooning" was actual something nice, because anyone in the team could pick the repository and take care of implementing new business logic.

The number of lines of code is quite bad metric for Golang, because famous "if err != nil" takes a nasty 3 lines, while in many languages you can write it using single liner. In my humble experience, the number of lines of most Go web apps can be often compared to TypeScript apps. Also many web apps that I have developed usually had hefty 2-5k LoC and it is not bad result if we consider C# or Java web apps.

> - Powerful hygienic and non-hygienic macros

Yeah, having marcros in Rust is a gem.

> - Builtin benchmarking

Same as in Go. See testing.B.

It is weird you have pointed out

> - Builtin documentation

Same as in Go. See godoc.

> - FFI with Swift, C, C++, Node, etc to share code everywhere.

I rarely see the case for FFI in web app - I don't imagine even using it like that. It was common case for chart, TeX document or other web to image rendering to embed some library. I think it is a bad approach and the best currently is just run that code as separate binary, because it helps in maintainability of a third party dependency and your devops teams will love that decision.

As a person who rewrote the rxi/lite [1] to Rust I can only say I am terrified how many times I had to sacrifice having unsafe calls to just use some C code in my Rust application.

> - Crates.io is like NPM - really discoverable and easy to upload (with its goods and bads)

Personally, I feel Go/Deno/Docker flow of the installing dependencies is more convenient. I don't project names that do not sound what they provide. Naming thing is bad and I often see many developers are scratching head to find some unique name, so it could be easier findable in NPM or other repository. They are wasting time at looking for something short and funny and not something that is easily discoverable.

For many years, my only way of looking for dependency is GitHub. It helps to verify and investigate the quality of the code before adopting it in the application. It sometimes also results in contributing back to the project, because I already know where the project is located.

> - Really good project management through modules/Cargo.toml

It is really complex I'd say. But Cargo.rs would be nice to have :P

> - Generics make Map/Reduce/Filter really easy and readable

Matter of time in Go. :)

> - Serde is fantastic at automatically serializing/deserializing datastructures

Oh, that's true. Go has numerous serializers (for only JSON there are about 20+ nice looking implementations) and it is still interesting to see new ones, especially because they bring many non-obvious optimizations. Kotlin serializer is also top notch thingy. I recommend to use protobufs types in Go - even for domain models. It is interesting how with Go2 can improve the situation.

> - Very pleasant logging and tracing

The log package is nice, together with macro log! is really pleasant to look at it how concise it is to fill some context parameters around the message. I think it is like Logrus in Go, except the syntax it has the same features. There is also Zap package that sacrifices readability for performance. There is no problem to embed number of line of code, calling function in Go logs either.

Tracing? Yep, it feels the same for both languages I think. I had used OpenTracing (Jaeger) and I hardly can say I miss something from one or other language. Maybe some macro/annotation wrapper that will be added on compile time? However, I rarely see any use case right now for complicating such thing like tracing.

> - Like, really really good error handling, esp compared to Go

Hey, it is not that bad! :D But well, as long as you use Goland you don't care about the if-err-non-nil.

If you switch for few days to Java-world you will be like in hell after developing in Go, because the error-over-exception flow is really helpful to provide code that does not have any kind of error and you, as a developer, can guess what happens in specific line without any println("1") or debugger. Monads are nice but I will not trade current if-err for them.

> - builtin testing framework

AFAIK all modern programming languages includes some testing framework: Kotlin (kotlin.test), Zig (std.test), Elixir (ExUnit) etc. I am glad both Rust and Go joined that club.

> If you're looking into using Rust for web, I recommend https://github.com/http-rs/tide - it's the most pleasant web framework I've ever used.

It is interesting, but I think even today there is nothing that I could label as a "framework" in Go world. You wisely choose the best packages matching your needs. The situation has improved with many libraries providing a GraphQL endpoint.

> I've worked a decent amount with Go

Reading your post, made me think you don't have good Go experience and it sounded bad IMHO. I guess you had nobody proficient enough in production-ready Go apps to evangelize it within the team or there was no reason to use Go (yep, it is not a perfect tool). ;)

[0]: https://github.com/mozilla-services/syncstorage-rs

[1]: https://github.com/rxi/lite




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: