Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
First Impressions of the Rust Programming Language (jakob.space)
100 points by dailymorn on June 9, 2018 | hide | past | favorite | 45 comments


Not too helpful. Just comments from a new programmer.

I'd like to hear something like "This is how our team used Rust to do (really hard thing involving heavy concurrency and lots of state)". From someone not involved with the development of Rust.

I was recently looking at a large, non web related C++ program which needs to be made multi-thread to increase capacity. I realized that if it was in Rust, it would be much easier to break out functionality into another thread. You need to classify data as immutable, locked, or unshared to make the program multi-thread. Rust has language support for that. C++ does not.


It might not qualify as "really hard thing involving heavy concurrency and lots of state", but I'm nearly done writing a service that interacts with http://tile38.com. I initially wrote it in Kotlin, and 2 weeks ago I ported it to Rust.

I'm still learning the language, so I haven't touched the "fearless concurrency" stuff, but so far it's looking very good.

~30% CPU time, 1-5% RAM use at peak; compared to the JVM.

I plan on writing about it, and open-sourcing the code (both Kotlin and Rust repos). Chasing a hectic work deadline at the moment.


Over the past year, I've been porting my GIS project over to Rust (https://github.com/jblindsay/whitebox-tools). I'm sitting at over 100k lines of Rust code now. My experience with the language has been very good and, in particular, its concurrency support is extremely productive and aligns well with the spatial algorithms that I work with. The one thing that I wish for, however, is a better GUI story.


I am surprised there has not been a Qt like project spring up that is written in Rust.


Right now https://github.com/maps4print/azul is looking the most promising.


I'll look into this. Thanks for bringing it to my attention.


This is a really massive undertaking, and the UI space is really crowded and moving in all sorts of directions. It's not that it would be without value, but it's really risky and a lot of work, so not very surprising.


There are a couple. But people don't just want any old GUI, they want a GUI that is marketed toward them and stamped with official approval.


I‘m not sure its needed anymore. WASM in the browser could be both efficient and be the new UI paradigm - why pay the cost of mapping to OS widgets?


I would imagine people looking at UIs for a systems programming language would want a lighter abstraction than pulling in an entire browser (for things like embedded).


On the other Hand, you wouldn’t need a UI abstraction layer on embedded, because those things don’t have standard controls and code is often platform specific, not portable.


Gross.


Yes, I'm kind of surprised by this too, but I guess that the whole industry has been moving away from desktop applications for quite some time.


Figma's Rust in production post was pretty good https://blog.figma.com/rust-in-production-at-figma-e10a0ec31...


> I'd like to hear something like "This is how our team used Rust to do (really hard thing involving heavy concurrency and lots of state)".

Our team uses Rust for moderately complex concurrency.

TL;dr: There are tradeoffs, but Rust can be quite nice when you care about performance.

In my experience, concurrency is actually pleasant in Rust. The borrow checker eliminates 99% of problems before they ever occur. As for libraries, the popular crossbeam library provides scoped thread pools, which make it easy to spin up a bunch of local worker threads. https://docs.rs/crossbeam/0.3.2/crossbeam/struct.Scope.html#... For "parallel iterators", Rayon is excellent. https://github.com/rayon-rs/rayon For async I/O, the tokio library still demands solid Rust skills (at least until Rust 2018 lands), but once you figure it out, it Just Works. https://tokio.rs/

As for our other experiences using Rust:

- Rust is amazing for fast, cross-platform CLI tools.

- For most kinds of programs, I barely notice the borrow checker any more. But this is partly because I don't write programs with giant webs of objects that all try to mutate each other (like some game engines, for example). Also, I've never needed to implement a non-hierarchical data structure in Rust (the gory details of which are described at http://cglab.ca/~abeinges/blah/too-many-lists/book/), mostly because anything I needed was already on crates.io.

- Library support is much better than I would expect for a young language, but I do occasionally find myself overhauling the guts of an AMQP library or something. This costs me maybe a week or two per year?

Flavor-wise, Rust feels like a simpler C++ without the sharp edges or footguns. It has much better package-management tools. Safe Rust code doesn't have data races or buffer overflows. If you fuzz Rust code, the worst that will normally happen is a controlled panic caused by an invalid array index.

But Rust is going to be more challenging to somebody who has never thought about stack allocation versus heap allocation, or who has never written "my_list.map(some_function)". And sometimes the type names can get a bit hairy, if somebody uses too many parameterized types.

But overall, I'm really enjoying Rust at work. It's basically the language I spent the entire 90s desperately wanting, back when performance was always a big deal.


> And sometimes the type names can get a bit hairy, if somebody uses too many parameterized types.

`impl Trait` just landed in stable! I think the most interesting use cases (putting an impl Trait in a struct) aren't stable yet? But the basics are working great.


Yes I agree. From what I remember from a feedback of +1 year of Rust, Rust makes a whole point at treating panic and errors that C++ or other languages don’t do. It goes to a lot more length than what we have our there.

Maybe you will find you want here if you didn’t know this website already.

https://hn.algolia.com/?query=rust&sort=byPopularity&prefix&...


A simple pattern I follow for C++ concurrency is to have each thread run an event loop and use https://github.com/cameron314/concurrentqueue as `concurrentqueue<std::function<void()>` for execution of code in the other thread ; I don't remember getting threading problems by doing like this as long as any shared resource either outlives both threads or is in a shared_ptr of sorts.


Can I interest you in some Pony?

https://www.ponylang.org/


I found "The list of reference capabilities" at https://tutorial.ponylang.org/capabilities/reference-capabil... especially interesting to compare with Rust's borrow checker.



As I wrote to the author on Lobsters:

Glad you liked TRPL! I agree that some of the examples can be too abstract at times, it’s tough. Totally open issues if you want to talk about it; I’m open to improving things, but I’m also pretty particular about the book.


I'm really looking forward to getting the hard copy!


Me too! It’s being printed right now... so close!


> Compile-time memory management requires designing your programs in a way you might not be used to, but it definitely beats manual memory management, or letting a runtime take care of garbage collection.

What about Automatic Reference Counting a la Swift / Objective-C?

Seems like a nice blend: compiler assisted, much less runtime overhead than traditional garbage collection, simple programming model.


I too have always found ARC to be the sweet spot, the only downside is still having to care about retain cycles.


Rust supports reference counting for places where you need it. There is both the RC and ARC datatypes.


And to be clear, Swift’s ARC and Rust’s Arc are different; automatic vs atomic. Swift’s ARC is automatic usage of Rust’s Arc type, if that makes any sense.


Is are there some special properties in Apple's implementation that would make their ARC competitive with state of the art GC?


Depends what you mean by competitive. Generally speaking reference counting offers better memory efficiency and more deterministic performance than tracing. These are usually desirable traits for mobile apps and games, and in many cases servers too.


"Also, I've been fairly critical of Rust in the past because that view was in-line with the opinions of my friends, but now that I've decided to go out of my way to learn a new programming language, I might as well use this as an opportunity to see if my criticisms were unfounded."

While this is an honest comment, why and how can you be critical of a language you don't know. Skeptical sure, but critical?


Is it me, or does the Rust compiler produce terribly unoptimized code? Just compare it to the equivalent C++ code: https://godbolt.org/g/Jdfkm6. Both Clang and GCC produce really lean binary output.


Sometimes. It just depends. Some possibilities:

1. The parent didn’t say if they compiled with optimizations. I bet they did, as the code would probably look even worse without, but who knows.

2. This isn’t apples to oranges, as you’re not doing formatting here, right?

3. The formatting code makes various trade offs; it’s not optimized for speed, more for size, in my understanding.

4. Codegen bugs do happen. Maybe this is a degenerate case.

In general, if the code is significantly worse, then it’s a bug.


first thing that jumps (sic) is that comparing puts to formatted print is not worth of a gentleman.


How would you write it, out of curiosity?


There's an example of using stdout.write at the top of this page: https://doc.rust-lang.org/std/io/fn.stdout.html

    use std::io::{self, Write};

    fn main() -> io::Result<()> {
        io::stdout().write(b"hello world")?;

        Ok(())
    }


I should improve this example, in its current form you could drop the ? and the Ok stuff...


no idea, but puts is memcopy right ? println! / printf involve megatons of steps


> if let is a syntax construct that I don't think any other language has

AFAIK (not too familiar with rust or c++), you can do something like this:

    if (Maybe may = whatever; may.issome)


`if let Some(x) = y { … }` is equivalent in Rust to `match y { Some(x) => { … }, None => () }`: pattern bindings are available. Thus it is quite different from `if y.is_some() { … }`.


Is it? It does something with y if it is something, otherwise it does nothing...


To make clearer what I meant by pattern bindings being available:

  if let Some(x) = y {
      println!("y has a value, {}", x);
  }
Whereas with a method, the contents of the variant are not bound:

  if y.is_some() {
      println!("y has a value, {}", /* uh… */);
  }
In Rust, pattern matching is the only to get at the contents of an enum. Methods like is_some() are just this:

  pub fn is_some(&self) -> bool {
      match *self {
          Some(_) => true,
          None => false,
      }
  }


It’s also present in Swift.


man 3 strdup. Why is this upvoted? If you are a new programmer, don't read this nonsense.


It's true that on platforms where strdup is supported, the C example could be written more succinctly with strdup. But strdup isn't part of the ANSI/ISO standard, at least according to the man page on Ubuntu 16.04. And even when using strdup, you can't get away from manual memory management; you still have to call free (or strfree) afterward.

Furthermore, the field of programming is so vast that it's unreasonable to expect someone to know every nuance of a given language, especially if it's one that they don't use heavily.

So I don't think there's any good reason to dismiss the whole article as nonsense.




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

Search: