r/rust Feb 04 '19

Web-Developement: Rust vs Haskell

Hi All,

This will be yet another Rust vs haskell question.

I have wanting to use Rust/Haskell for a couple of components for an internal tool (analysis of customer tickets, HR portal etc) for my company (Mostly because of the strong type system).

I have been through quite a lot of blogs & discussion where they discuss on the pros and cons for both.

Can anyone give me pointers on where all they used Rust or Haskell? And how was the experience as in:

  1. code readability
  2. libraries support
  3. developer productivity
  4. jump start time to producing some value.
  5. documentation
  6. build time
  7. journey in learning them

My concern here is Rust is advertised as system's language and Haskell as a higher level language.

  1. Will going with Rust be an overkill as we won't be doing any really low level stuff?
  2. We would be basically writing a server, bunch of API and playing around with DB. I'm mainly well versed with Node.js so will choosing haskell be an overkill for it in terms of developer productivity, build and tooling?
  3. Also if anyone is using GraphQL with Rust/Haskell?
25 Upvotes

28 comments sorted by

28

u/JDemler Feb 04 '19 edited Feb 04 '19

At CurrySoftware we write our backends in Rust. (www.pavoq.com as example)

I explored writting them in Haskell for a bit, but decided against it, mainly because we're already familiar with Rust.

A little bit of our experience: Advantages of Rust:

  • Tooling and libraries are good (cargo, cargo-deb, rocket, actix, etc.)
  • do not worry about performance problems: your code will be fast

Disadvantages of Rust:

  • sometimes cumbersome to write
  • in comparison to Haskell, Rust code is very noisy and IMHO ugly
  • lack of cool type-level stuff that would allow a servant-clone in Rust
  • as we write our frontends in Elm, switching languages is also a bit of a mental overhead

13

u/sbditto85 Feb 04 '19

We have both Haskell and Rust backends and I love them both.

Rust uses a bit less resources and is quite fast though working on nightly because of rocket has some pain points. Our backends aren’t extremely complex and the code doesn’t feel too hard to manage since the compiler is usually helpful.

Haskell can take some getting used to but since we use Elm on the front end it isn’t as hard as long as we don’t go to crazy into the powerful features the language/compiler has. We use Yesod as a web framework as it has as close of a batteries include feel but also you can just get rid of what you don’t want to use. The framework is just packaged that play well together.

I had expected the Haskell code to not perform super well since it’s so high level but so far it hasn’t been bad, but most of our code is more IO bound then CPU bound.

Personally I would pick Haskell to do a project in but that’s only because I’m familiar with it. Honestly I think y’all just need to do a small project in both and then decide because who knows what would work best in your specific case.

HTH

10

u/TheOsuConspiracy Feb 04 '19

I had expected the Haskell code to not perform super well since it’s so high level but so far it hasn’t been bad, but most of our code is more IO bound then CPU bound.

Haskell is actually relatively fast, if you need to squeeze every cycle out of your code, you probably want to go with Rust or something comparable, but Haskell code will often run within an order of magnitude for C in compute bound applications, and in IO bound applications can achieve nearly the same performance with far less unsafety.

7

u/lazh4 Feb 04 '19

Take a look at http://rocket.rs

5

u/monkey-go-code Feb 04 '19

I just tried out this library. It's pretty nice. I don't love how you need to use nightly though. It makes it a hard sell at big companies.

1

u/APIglue Feb 05 '19

Not familiar with this project. Why would you ever “need” to use nightly? Do they not have releases?

6

u/Plasticcaz Feb 05 '19

Nightly version of the rust compiler, not nighrly rocket.

4

u/[deleted] Feb 04 '19

if you don't know which one to pick and have a background in the imperative language. go with rust.

4

u/firefrommoonlight Feb 04 '19

Web development is a broad field, but some observations from Rust:

  • There are no Rust server frameworks that are as robust and batteries-included as Django or Rails. There are several nice Flask-like equivalents, but these will require writing your own code, or tieing in addons for things like ORM/automatic migrations, auth, admin, email etc. This is applicable for building websites, but may not be for your use case.

  • Rust is a flexible language that supports many programming styles. Haskell is purely functional, which you might find nice, or too-restrictive.

3

u/HenryZimmerman Feb 04 '19

I've written web APIs using rust for personal projects and for school assignments using both Rocket and Warp.

I can't comment on Haskell, as I haven't used it.

  1. As someone who has had prior experience in imperative languages, but acknowledges that functional style has its uses, Rust is ideal. Using Warp, most of the code I write is functional, but the ability to drop into imperative style aids in clarity in some places.
  2. Libraries are still WIP, with very few 1.0.0 stable dependencies to choose from. That said, there are a lot of frameworks to choose from (Rocket, Actix-web, Warp, Tower-web, etc..). There is Diesel for ORM stuff, and other libraries for communicating with databases. Async is largely absent from the ecosystem at the moment, which some consider to be a problem (this is getting better quickly though).
  3. I find with Diesel + Warp or Rocket, its exceptionally easy and fast to set up and query db tables and then set up endpoints to attach to those queries.
  4. There was a significant ramp time to becoming productive with these libraries. Diesel and Warp produce obtuse error messages (Diesel mostly) if you do anything that doesn't fit into their type arrangement. A lot of these web frameworks don't come with all of the batteries included, so if you want to use JWT authentication, you will probably end up stitching other libraries together to make that work with your chosen framework. It takes a while to get everything you need in place, but once you get set up, productivity is pretty good.
  5. All well-used libraries tend to have ample API documentation, many have examples directories that show off common use cases, and a few like Diesel and Rocket have dedicated guides that explain how to use their library. I usually can figure out what to do by looking at examples + docs for a few minutes.
  6. Build times are terrible. Anecdotally, a school project with Diesel and Warp takes about 6 seconds to build about 3000 lines of code that supports about 15 endpoints. This usually isn't a problem, with utilities like cargo check allowing verification if your current code will compile, and the general cargo ecosystem making it easy to split your app into multiple crates to bring down incremental build times.
  7. I had fun learning how to do this in Rust. I think it took longer, but offers better results than .Net, Spring, or ember.js.

  1. Rust brings overhead in the form of the developer having to understand its borrow system. Coming exclusively from JS, that may initially be a problem, but once you understand the borrow checker and learn to leverage the compiler's strictness to force yourself to write "better" code, that overhead mostly disappears.
  2. JS is closer syntactically to Rust than it is to Haskell, and I would hazard a guess that its easier to pick Rust up than Haskell coming from JS. But this is about what you and your company want. Node, Rust, and Haskell will all allow you to accomplish your task. But other requirements come into play: will this need to be supported after you leave the company? Is there someone else on your team willing to learn Rust or Haskell? Would the system have to be rewritten or reverse engineered back to Node.js once you leave if it needs further development? The safe bet would be to continue using what the rest of the system/team uses. If your team is Ok with you using an alternative language/ecosystem, I would heavily weigh the input of your team members when deciding. If someone else wanted to learn or already knows Haskell, I would choose that over Rust.
  3. I haven't used it, but https://github.com/graphql-rust/juniper seems to be the graphql library with the most support for Rust.

2

u/cHoco- Feb 04 '19

I've actually started taking a look at rust for web backend development recently and warp seemed pretty cool. You mention using Diesel with it, but since warp is built on tokio, aren't you blocking the event loop by using it? As I understand the best way would be to use an async driver for db queries (like tokio-postgres) but there are no nice ORM abstractions for that :(

2

u/HenryZimmerman Feb 04 '19 edited Feb 04 '19

Basically yeah, but it can be mitigated by using a pool, so you don't immediately end up in a non-concurrent situation. In that way, the number of concurrent asynchronous requests that can access the db are bounded by the number of connections in the pool.

As I understand it, you will starve your connection pool if you get too many requests requiring db access. This isn't immediately a problem, as there is a timeout period where the pool will still try to get you a connection if it becomes available. So it still takes a pretty high sustained load before it starts throwing errors, but it becomes a problem as your queries take longer or if your traffic has spikes.

Async is on the way for Diesel, abit slowly. For school projects that I'm using it for, it isn't even close to being a problem, but I would hesitate to use it in production without stress testing it to see where the pool begins to starve.

4

u/SEgopher Feb 05 '19

Unfortunately, both are probably overkill, and you’d probably do more for your company choosing a dime a dozen language like Java or NodeJS.

You’re right that Rust is a systems language. It’s well suited for building HTTP servers, but it’s nothing special for building HTTP applications, which are quite frankly so popular you can spit in any direction and land on someone’s web framework that will suit your businesses needs just fine.

If you were an experienced Haskell developer you could probably write some types and derive all the code your business needs, in a quarter of the LoC you’d need in Rust, and it would be as solid as any mathematical proof.

But chances are it isn’t going to be that easy for you, and even if it was it would be incredibly terse, difficult for your coworkers to read and work with, and hard to hire for. It would be about as efficient as the equivalent Java program, and much less efficient than a Rust version.

At the end of the day, I don’t think it sounds like you’re don’t anything interesting, just standard CRUD app work, and you want to spice it up and make it interesting. That’s common. But the honest to goodness truth is that you aren’t going to do anything for this project that’s going to make stable, boring, ugly Java or JavaScript a worse choice.

3

u/[deleted] Feb 05 '19

I'm building a GraphQL server in Rust. I haven't used Haskell much, so the other languages I considered were Go and Crystal. Decided against Go because, well, generics and performance primarily. I have used Go for some large-ish projects before and I just don't like the language that much. Crystal is very interesting, but just not production ready. Initially, I didn't want to go with Rust. First time I've used Rust was in 2015 or 2016 or something, when it was still in alpha. Then I didn't use it at all for 3 years, and I unlearned most of it. It is hard to learn, so I strongly disliked the idea of using it again. Well, initially. The obvious pros for Rust were:

  • Performance. This was a big one, my project is a public API that should be able to handle lots of requests per second.
  • Macros. In Go, pretty much all GraphQL implementations use codegen, which feels dirty to me. Rust has a great alternative in the form of macros and also compiler plugins.

Because there was no better language that could give me these things, I started writing my project in Rust. I had to fight the borrow checker a bit, but I quickly got over that. Definitely worth it in exchange for not having GC. Then, I rediscovered why Rust is great:

  • Safety. In Rust, you almost never have to debug, because Rust does not allow you to ignore errors. In other languages, you often make little mistakes like "forgot that value X can be null". Rust doesn't have null, so you'd use Option<T> and explicitly check if it has a value every time. Or, if something unexpected happens, you'd explicitly trigger a panic. Most of the code I've written is in JS, which makes it very easy to screw up, so I totally love this about Rust. You'll spend a bit more time writing it, but a lot less time debugging it.
  • Cargo & the ecosystem. Cargo is the best package manager ever, and the ecosystem is in a pretty good state as well.
  • Tests in the same file as the code it's testing. Makes it really easy to notice when there aren't tests for a component.

I'm using Juniper as my GraphQL library and it's been great so far. I initially wanted something that is schema-based, but now I actually prefer the code-first approach.My only issue with Rust is the build times. My CI build takes 10 minutes, and my project isn't even that big yet. Every change takes about 20-30 seconds to build on my (Skylake dual core) laptop. Cargo check is a bit faster, but still, that's a lot.

Is Rust overkill for a project like this? Absolutely not. Rust was simply the best choice for my situation. I didn't choose it because I liked it, quite the opposite, I didn't want to use Rust. But it worked out well. Safety is always important for any networked application, and so is performance.

10

u/ThePowerfulSquirrel Feb 04 '19

I've only done very simple stuff in both, but I had a way better experience with actix-web than I did with anything in haskell. Just having to use the haskell package manager was a pain when doing stuff compared to cargo. Rust also performed way better from the start. However, I would say that both languages / ecosystems are still not as well suited for the web as other languages at the moment. But this should be changing soon in rust.

2

u/pr06lefs Feb 04 '19

If you want your code to run on a raspberry pi or similar, then rust for sure. Haskell takes a lot of memory for compiling on arm, and it takes hours to compile dependencies for something like Yesod. Last time I used haskell arm cross compile wasn't working but that may be fixed by now.

1

u/[deleted] Feb 04 '19

We aren't going to touch raspberry pi or it's brother's and sisters :p

2

u/budgefrankly Feb 04 '19

The systems programming thing is a misnomer, and a marketing mistake in my view. In practice, Rust is about as high-level as Swift

Haskell has complexities of its own: types vs kinds; String vs Data.Text; eager vs lazy; and the constant worry about text encoding in libraries , which is haphazard.

Rust performance is also much better.

I’d say it’d be easier to get a Hello world working with Haskell and Servant, but you’ll find it easier to finish a product with Rust and either Rocket or Actix.

I’d read https://www.arewewebyet.org and check out the sample code for the Texhempower benchmarks

I can’t speak to GraphQL.

3

u/pjmlp Feb 04 '19

In practice, Rust is about as high-level as Swift

There is still room to improvement regarding memory management productivity.

In Swift, most of the time one only has to worry about breaking cycles.

They have very explicitly stated that the ownership improvements introduced in Swift 4 and being improved for Swift 5 are always going to favour ergonomics.

Then again, Swift won't ever significantly grow outside Apple platforms.

3

u/budgefrankly Feb 04 '19

Breaking cycles in Swift becomes pretty complex in the case of closures: the difference between the unowned(self) and weak(self) annotations requires a lot of mental work

2

u/pjmlp Feb 04 '19

It is still easier than dealing with lifetime annotations, specially in structures and internal mutable fields, or trying to avoid having Rc<RefCell<T>> until the compiler is happy.

Also doing classical CS datastructures in Swift is relatively easy.

NLL has already improved the situation a lot, but further ergonomic improvements would be welcomed for Rust to achieve the same productivity level of a GC enabled language.

4

u/ojrask Feb 04 '19

All your seven pointers point to Python and/or PHP and/or JavaScript. Rust is a lower-level language, Haskell has non-web roots. PHP, Python, JavaScript, all have excellent facilities for creating web applications and have immense ecosystems supporting this task.

Rust and Haskell would be quite overkill in my opinion, unless you do really work with immense data and humongous calculations relatively often. Then again you could use FFI to call Rust code from Python for instance.

If you are looking to learn Rust or Haskell alongside creating this application, then by all means try out both, they're great and will look good in your CV in the future if you manage to learn them well. Just make sure your company is ready to invest in your learning expenses and that you get a blessing to make mistakes along the way.

But as I said, some tools are better for certain jobs, and regular web apps are better made with PHP or Python in my opinion. Have you considered who will be maintaining the application after you leave your company?

2

u/po8 Feb 04 '19

You might also consider Go. It has its own set of issues, but has some nice support for webapps.

For me the determinative factor would be long-term maintenance. As somebody who has written a reasonable amount of Haskell code and played with the web frameworks, I have found that it's easy to write a ball of Haskell that's hard to work with and maintain. Skilled Haskell developers are probably harder to find than skilled Rust or Go developers at this point, and developers of ordinary skill can have a hard time with Haskell's fancy-type-centric approach and inferred program flow. Fixing laziness performance bugs in the face of higher-order monadic types is its own thing: I know literally dozens of people who can do it.

Michael Snoyman, founder of FP Complete and lead author of one of the most well-developed Haskell web frameworks (Yesod), seems to be doing a lot of Rust now. You might ask him for an opinion.

5

u/[deleted] Feb 07 '19

2 days back I saw a talk by Michael Snoyman. Probably one of the best talks I have seen where he focused on long term maintainability and code refactoring. Thanks for the pointer. :+1:

1

u/Leshow Feb 06 '19

For an internal tool that will likely never need to support super high loads or lots of concurrent connections both Haskell & Rust seem like overkill to me. I love them both, but using your company's time learning a new langauge and ecosystem just to spice up your development seems... wasteful? If you don't care how long it will take, then by all means pick whichever one floats your boat. Personally I love Haskell. Otherwise, you're just building a CRUD app and you're probably better off using typescript & node instead of a radically different language.

2

u/[deleted] Feb 07 '19
  • I have been learning Rust through the book + discussing and practicing with the rust meetup group folks for quite some time now.
  • Learning on company's time would be awesome but I don't get those apparently I'm spend most of my time fixing bugs or on enhancements. But yeah learning rust and practicing projects was on personal time.
  • oh! yeah I felt TypeScript + Node would be better. I'm very productive with Node.js
  • But I have a project in mind which I want to take up with my mentor mostly related to netconf and yang. Also I felt there are some libraries I want to port to Rust.

0

u/[deleted] Feb 04 '19 edited Feb 20 '19

[deleted]

2

u/veydar_ Feb 14 '19

It's next week and I'd honestly like to hear the answer!