Live data from Hacker News

100 days with Rust: a series of brick walls

brandur.org

31–40 of 323 posts

Re: 100 days with Rust: a series of brick walls

#31
>Even something as simple as abstracting a new helper function often turns into a veritable odyssey because getting type annotations right can be so difficult (especially where a third party library is involved).

This is a sentiment I can't say that I share or even understand. You have a compiler doing inference, it will tell you what the types are if you ask?

A lot of times when I find myself writing something where I'm unsure of the concrete type -- I'll just stick a bogus type ascription in the expression somewhere. Then I run `rustc` knowing full well that it will fail. Somewhere in the error will be a message of the form "found expected " and now I know what the inferred type is.

>The horribly anti-user futures system, compiler messages generated by a misused macros that are second only to C++ template errors in how egregiously difficult they are to parse, universally terrible documentation and lacking examples, unstable APIs, type annotation hell, and so much more.

Given the author's dig at the `futures` crate though, I have a feeling a lot of the verbosity in errors they are seeing is due to the extremely long chains of combinators that the futures crate encourages. I haven't run into these errors myself since I'm avoiding async IO in rust until an `await` style abstraction becomes available. In my opinion: jumping into using an async library/runtime that is undergoing heavy development is probably not the best place to start when it comes to learning Rust.

I think this is one thing that Go definitely got right: having concurrency baked into the language that encourages a "syncrhonous-style" of programming is absolutely the way to go for approachability. I'm not sure that I'd go so far as to call `futures` user-hostile, as the tokio devs are doing great work, but it certainly isn't user-friendly yet.

Re: 100 days with Rust: a series of brick walls

#32
post #19

Earlier quoted context omitted.

They're completely different kind of docs that Python's. Python's are written by hand, with many examples and tips how to use the various tools. Rust's documentation very much feels generated, and the last time I checked methods were not grouped. So vast portions of a page are consumed by variants of methods (overloaded methods?) which work exactly the same except they take different argument type. Python documentati…

You mean like how Vec has a ton of examples? https://doc.rust-lang.org/std/vec/struct.Vec.html FWIW I'm not a huge fan of Python's docs because I can't quickly scan them to track down that one detail about a function I was using. Rust's docs also let you collapse everything which makes browsing them much faster.

The traits implementation section is god awful and in an utterly unusable order because the ordering makes no sense.

I find myself always just looking at the source to make sense of things rather than the docs which kind of defeats the point.

Re: 100 days with Rust: a series of brick walls

#33
post #19

I was following along until this: > universally terrible documentation and lacking examples, unstable APIs, type annotation hell, and so much more. The docs in Rust are by far some of the best I've seen, without specifics it's really hard to understand what issues he hit.

They're completely different kind of docs that Python's. Python's are written by hand, with many examples and tips how to use the various tools. Rust's documentation very much feels generated, and the last time I checked methods were not grouped. So vast portions of a page are consumed by variants of methods (overloaded methods?) which work exactly the same except they take different argument type. Python documentati…

I'm curious which docs you are talking about. The Python standard library has much less examples than Rust's in my experience. numpy has excellent documentation, but that's some library.

Also, I don't see the redundancy you are talking about. There is no overloading, except for traits, and for those the documentation is in one place and all the implementations are just listed, which seems pretty minimal to me.

Re: 100 days with Rust: a series of brick walls

#34
post #24

Earlier quoted context omitted.

I did find the documentation for promises and tokio to be pretty confusing. But I had only been learning Rust for a few days at that point, so I think I was probably just not ready for it. I went on to just use the basic sockets instead and that was pretty easy.

Tokio and futures are still in their infancy. We'll get there at some point hopefully

I liked the concept and will return to it when I'm a little bit more adept.

Re: 100 days with Rust: a series of brick walls

#35

I'm not sure how easy Rust claims to be... The main idea here is " I love that Haskell-esque feeling where a compiling program is usually a working program." Rust will probably get easier, but it's main goal is safety. The main problem I have with a pure safety focus is that the warnings often feel like overkill for 99% of programs. For example, when gcc yells about comparing signed and unsigned ints, I find that the…

Well gcc cannot know if your signed with unsigned comparison is going to blow up on a critical path of a security related function.

Re: 100 days with Rust: a series of brick walls

#36
post #25
post #13

Earlier quoted context omitted.

I’m observing some similar muttering in the JavaScript community with Promises. Chain them incorrectly and you get an error with no actionable context. The most popular 3rd party promise framework in JavaScript collects extra cause and effect data when you run the code in development mode. It helps but it still isn’t always enough. I fundamentally don’t understand how people still think writing tools and libraries is…

Don't leave us hanging. What's the other piece of advice?

Oh. For a similar reason (nobody reads your code unless they're looking at a problem): describe your piece of code in plain english. If you can make the code work the way you just described it, the code will age better.

(It might not be the fastest, but everyone will know if it's correct. When you're hunting for a bug it's important how quickly you can eliminate false positives to get to the real culprit. And you can make good code fast but you can't make fast code good.)

Re: 100 days with Rust: a series of brick walls

#37
post #6

This is a 100 sentences rant with 0 substances. Literally, there are no examples at all of any "brick wall". Why was this even posted here?

I think that pretty much sum up what the major problem of Rust is: "but I’m starting to feel seriously concerned by how glacially slow it is to get anything done."

As a small counterpoint, I did notice some people did very well at Advent of Code using Rust e.g. sciyoshi was 4th overall.

https://adventofcode.com/2017/leaderboard https://github.com/sciyoshi/advent-of-rust-2017

Re: 100 days with Rust: a series of brick walls

#38
I am currently learning Rust and I feel this intensely[1].

I really want to like Rust, but I feel like the way they cope with no GC (lifetimes, borrowing) fights me at every turn, and really simple situations in other languages[2] become these intensely painful situations. Every time you think you've worked out how to fix a problem you find while you've fixed that one you've actually created 2 more.

Want to have a data structure of variable size (eg a struct with an Vector in it)? You can't do that, structs have to be fixed size. OK so I'll make it a reference to a Vector. That's great, but now you can't have a factory function because the lifetime goes out of scope. OK so I'll wrap my reference in a Box. OK that's great but now your OTHER reference: a trait (because traits are also of unknown size) is complaining. OK I'll wrap that in a Box as well. Sorry, you can't wrap this trait in a box because before your trait requires implementors to implement copy because at one point you have to use the trait in more than one place and references break the lifetimes and--- THROWS LAPTOP OUT WINDOW

I'm going to keep chipping away at it for a bit longer, but I can feel my interest waning.

[1] Except for the bad docs bit, I really like the docs, and the error messages are definitely earnest in their attempts to help you.

[2] that I'm familiar with, which are no languages that don't auto-GC

-- EDIT --

To everyone taking the first line of my intentional rant paragraph and pointing out it works fine… you're correct, I am mistaken! Let me paste the reply I made to the first person:

---

You're absolutely right. What I really meant was that you can't have Vec where T is a trait without also wrapping that in a box, which for me in turn doesn't work for a bunch of other reasons.

In any case, my point remains the same: it is very challenging-- at least for someone used to just creating data structures and letting GC handle it-- to build code that does what you want, and you spend large amounts of time "fighting" the compiler. I am OK if people wish to peg that on me being stupid or whatever, it doesn't change the core point: it's hard for new people to get into, and if you're wanting there to be less Electron apps and more native apps things like Rust being easy to use seems important for that.

Re: 100 days with Rust: a series of brick walls

#39
post #10

As someone who has been programming in Rust for nearly a year, even for commercial purposes, this article is baffling to me. I've found the compiler messages to be succinct and helpful. The package system is wonderful. It's dead easy to get something off the ground quickly. All it took was learning how and when to borrow.

I can see where the author comes from. I've been working with ^W^W fighting against Tokio this week, and the error messages are horrible. Representative example:

  error[E0271]: type mismatch resolving ` + std::marker::Send>, [closure@src/server/mod.rs:59:18: 59:74]>, [closure@src/server/mod.rs:60:19: 69:10 next_connection_id:_], std::result::Result>, futures::MapErr, [closure@src/server/mod.rs:74:18: 74:74]>>, std::result::Result + std::marker::Send>, [closure@src/server/mod.rs:59:18: 59:74]>, [closure@src/server/mod.rs:60:19: 69:10 next_connection_id:_], std::result::Result>, futures::MapErr, [closure@src/server/mod.rs:74:18: 74:74]>>)>, [closure@src/server/mod.rs:78:34: 83:6 cfg:_]> as futures::Future>::Error == ()`
    --> src/server/mod.rs:85:15
     |
  85 |     return Ok(Box::new(server));
     |               ^^^^^^^^^^^^^^^^ expected tuple, found ()
     |
     = note: expected type `((), futures::SelectNext + std::marker::Send>, [closure@src/server/mod.rs:59:18: 59:74]>, [closure@src/server/mod.rs:60:19: 69:10 next_connection_id:_], std::result::Result>, futures::MapErr, [closure@src/server/mod.rs:74:18: 74:74]>>)`
                found type `()`
     = note: required for the cast to the object type `futures::Future`
I have hope that things will improve on this front when `impl Trait` lands.

EDIT: After re-reading this, I want to add that I don't mean to hate on Tokio. I like the basic design very much, and hope that they can work out the ergonomics issues and stabilize the API soon.

Re: 100 days with Rust: a series of brick walls

#40

This is a 100 sentences rant with 0 substances. Literally, there are no examples at all of any "brick wall". Why was this even posted here?

I think it sounds exactly right when a developer comes from a higher level language(like C# or Java with the rich base libraries) to a much low level one.

I'm coming from working in Typescript in Nodejs for the last 3 years and I've found it incredibly approachable. It's possible that it's because OOP is less prevalent in JS compared to the ones you mention as well as the author's use of Python. Then again, maybe it's just syntax similarities.
Post reply on HN