Live data from Hacker News

100 days with Rust: a series of brick walls

brandur.org

91–100 of 323 posts

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

#91

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…

> For example, when gcc yells about comparing signed and unsigned ints, I find that there rarely is a true safety concern involved. I hope Rust is better than that. In Rust these are treated as two completely different types so this is a compiler error and not a warning. You need to explicitly cast one of them to make the comparison and integer types are not automatically converted in any way. You have to do the same…

> You could certainly define the `ParitalOrd` trait for the two types to make the comparison possible

I don't believe that's possible. Unless something changed relatively recently, the trait implementation has to be either a) in the module where the trait itself is defined (so the standard library in this case), or b) in the module where the type you're implementing the trait for is defined (again, the standard library). Since you can just modify the standard library, implementing PartialOrd would not be possible for e.g. comparing u16/s16 (or whatever).

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

#92
post #89
post #87

I have been working with Rust, full time, for a little less than 100 days. Like the author, I also came from Python (I authored Yosai). Unlike the author, I haven't been hitting brick walls. I also have observed all of the warning signs that the futures bridge on the tokio highway is unfinished so I didn't cross the barrier and still try to use it anyway. Instead, I have been working on myriad other synchronous parts…

I'm from the Ruby community, did a year of Scala after leaving Ruby. I'm now with rust and after the first struggle, I don't really have trouble with Rust anymore. I know the design I need to do to get certain things done, I know what is allowed now easily with purely concurrent Rust, and when do you need to split things up into threads. Right now I can refactor a project from threads to reactor in a couple of days a…

What type of projects?

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

#93
post #61

Earlier quoted context omitted.

There's nothing at all preventing you from having a Vec in a struct, and the use cases for variable sized structs are pretty rare. It sounds more like you conflated having a different problem with having a Vec be in a struct and stuff like that poisoned your further attempts to understand the language

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 "…

It fundamentally doesn't make sense to have a Vec, because Vec expects each of its elements to be the same size (otherwise you couldn't index into it in O(1)), but different types that implement Trait can have different sizes. Other languages allow this because they automatically box everything, but Vec> should accomplish the same in Rust; I'm curious what the "other reasons" you referred to are, that make that unsuitable. Alternately, if any given instance of the Vec is only expected to have values of a single type (but the type can be different for different Vecs), you may be able to accomplish what you want with generics instead.

That said, trait objects in Rust are pretty broken in general, so - this is just speculation, but - I think your problem might actually arise from that, and the Vec issue is a red herring.

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

#94
post #92
post #89

Earlier quoted context omitted.

I'm from the Ruby community, did a year of Scala after leaving Ruby. I'm now with rust and after the first struggle, I don't really have trouble with Rust anymore. I know the design I need to do to get certain things done, I know what is allowed now easily with purely concurrent Rust, and when do you need to split things up into threads. Right now I can refactor a project from threads to reactor in a couple of days a…

What type of projects?

Async consumers that deal with events and trigger stuff on internal and outside services. RabbitMQ in, http out, response back to RabbitMQ kind of things.

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

#95
I feel like a lot of difficulties people run into with Rust are because they're trying to do things the "right" way. You can often make your life easier with liberal use of reference counted objects, instead of solving difficult lifetime constraints, but it doesn't feel like the perfect way to do it. Often people are pursuing zero-cost abstractions to their detriment. They then compare the language unfavourably against languages where those zero-cost abstractions weren't even an option.

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

#96

Earlier quoted context omitted.

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.

I do not have experience with Rust, I had similar experience like author when coming to C/c++ , you need to also understand what a linker is, how compilation works, other low level things to be able to understand c/c++ errors. In C#/Java things are simpler so is normal to be hit with ton of new things that you need to understand

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

#97

> universally terrible documentation Wait, what? Rust has what I consider the best documentation I've seen of any language. The docs explain things at a high-level, but concisely, and have numerous examples. The formatting is good, the keyboard navigation support is good, it's well-linked, and it has convenient features like links to the source and the ability to collapse everything but method headers for easier brow…

http://www.cplusplus.com/reference/ Far far far better documentation. The Rust documentation is a mess and difficult to read for many people, but many involved in Rust seem to deny that it is a problem.

Docs team lead here. Specific feedback on improving the output of the docs is absolutely, 100% welcome. Without knowing what "it" is, I can't say if we're "denying that it is a problem."

We are constantly tweaking the layout of stuff, and have some larger plans on the way as well.

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

#98

> universally terrible documentation Wait, what? Rust has what I consider the best documentation I've seen of any language. The docs explain things at a high-level, but concisely, and have numerous examples. The formatting is good, the keyboard navigation support is good, it's well-linked, and it has convenient features like links to the source and the ability to collapse everything but method headers for easier brow…

http://www.cplusplus.com/reference/ Far far far better documentation. The Rust documentation is a mess and difficult to read for many people, but many involved in Rust seem to deny that it is a problem.

What is explicitly better about it? From glancing it seems similar.

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

#99
post #30

Earlier quoted context omitted.

> Lifting is a concept which allows you to transform a function into a corresponding function within another (usually more general) setting. What's there not to understand? :)

Yeah that bit was alright, it was everything after that I struggled with ;) As an example; I don't know what a functor is. I've not come across that term in anything I've done before, so I click on it to read up and get the definition: "The Functor typeclass represents the mathematical functor: a mapping between categories in the context of category theory. In practice a functor represents a type that can be mapped o…

I did mathematics to first year university level and didn't come across any of the terms used in Haskells.

Our programmers group is currently working through category theory with - https://bartoszmilewski.com/2014/10/28/category-theory-for-p... - and a lot of it is utterly bewildering, but at least I am starting to understand some of what Haskell is going on about. As for real world usage, however, I still have a long way to go...

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

#100
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::…

That's nothing!

      |
  212 | /     fn call(&self, payload: Self::Request) -> Self::Future {
  213 | |         let request = self.create_request(payload);
  214 | |
  215 | |         let work = async_block! {
  ...   |
  254 | |         FutureResponse(Box::new(work))
  255 | |     }
      | |_____^
  note: ...so that the type `impl futures::__rt::MyFuture
request:hyper::Request for {futures::Async, (), fn(std::result::Result) -> std::result::Result as std::ops::Try>::Ok, as std::ops::Try>::Error> { as std::ops::Try>::into_result}, futures::MapErr, hyper::Response, std::option::Option, &'r hyper::Response, hyper::StatusCode, fn(std::result::Result) -> std::result::Result as std::ops::Try>::Ok, as std::ops::Try>::Error> { as std::ops::Try>::into_result}, futures::stream::Concat2>}] as std::ops::Generator>::Return>` will meet its required lifetime bounds
Post reply on HN