Live data from Hacker News

100 days with Rust: a series of brick walls

brandur.org

301–310 of 323 posts

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

#301
You can spend a month or two and get used to the bulk of Rust out of raw exposure. After seeing the same compiler errors over and over, you start to pattern match and learn how to jiggle the handle to get what you want.

For example, have you ever accidentally passed &Request across a thread boundary? The compiler explodes with UnsafeCell errors deep within the inner sanctums. It feels impenetrable for a while. You throw some clone() at it and whatever your go-to guesswork is. Then 30 minutes pass and you realize you just needed to pass Request instead of &Request. And at the end of i you really haven't learned much beyond "I'll try that sooner next time."

I think that's the hardest part about Rust. It takes quite a bit of mastery to actually understand and work around the more difficult compiler errors, like one that seems to threaten the whole abstraction you were going for. But adding a `+ Send + Sync` somewhere suddenly fixes it and it's not obvious why. It can feel very precarious.

Anyways, I think most of Rust's issues are just tooling issues. For example, imagine being able to hover identifiers to see their scope shaded in and where they'll get dropped -- instead of just error-message ASCII art. Or being able to hover something to see that it can do something because it implements this certain trait.

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

#302
post #290

Earlier quoted context omitted.

> there is a trait of Material that has a function on it, and then there are different "implementations" of Material with different implementations of that fn, and can have arbitrary data stored against them. Do you mean like a class hierarchy+virtual functions, or just having allocated data of arbitrary length past the end of a struct? If it's the former, C++ fares no better in this regard but it's pretty easy to do…

impl Material for Lambertain { ... fn box_clone(&self) -> Box { Box::new(Lambertian { ..self }) } } Holllllly shit I think that works. Why am I allowed to do this and not just derive Clone and Copy!?!

Copy and clone have specific meanings and must resolve to the type of the class itself - basically copy or cloning a class of type A gets you another class of type A always.

It's possible, from a language sense, to have an implementation of box that could directly clone the trait, but I don't believe it would have a reasonable api.

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

#303
post #260

Earlier quoted context omitted.

Rust is certainly not the "end of history" for programming languages. But, taking on that task is for future generations of language devs; it's an open research question today. I can only hope so! I wrote some thoughts about "complexity" and language design here: http://words.steveklabnik.com/the-language-strangeness-budge... I also think the difference between incidental and inherent complexity is important...

One question I had after reading your post is - We currently build languages with purely additive models, ie features can be added to a language over time. Overtime the interaction between features creates "incidental complexity". Was wondering if you know of any languages that have been able to drop old features / ideas in a controlled manner.

Ruby 1.8 -> 1.9 was quite successful; it was painful at the time, but eventually worked out. Contrast with Python 2 -> 3 or Perl 5 -> 6.

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

#304

Earlier quoted context omitted.

as things tended to take String whenever I had &str's Functions should prefer &str or perhaps T where T: AsRef . Note that if you write code that needs an owned String , you could consider taking some T where T: Into , because this allows you to take many kinds of string types, such as &str , String , Box , and Cow .

I don't remember the details, but I just recall that I ended up with a converting nightmare. Your suggestions make sense, but I can't help but think that there is something fundamentally weird about basically having to use generic programming just to take a string arg. The most sensible thing would be " everything uses &str".

It's just a tradeoff, like any other. If you use a generic, you add complexity, but can accept a wider set of types. If you don't, things are simpler, but you accept a smaller set of types. I personally find the AsRef to almost always be overkill. YMMV.

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

#305
post #258

Earlier quoted context omitted.

There are some ways in which Rust can be simpler; see my above comments about learn ability. But a lot of the complexity is inherent in the choices we've made for the constraints of the language. For example, including a GC would make things much simpler in some ways! But it would also make it not appropriate for many of the use cases that are crucial to Rust's existence.

The way I see it, Rust exposes more of the underlying complexity of things which makes Rust itself appear more complex than its peers.

Yes. The String stuff is the epotiome of this, IMO.

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

#306
post #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 again…

I think this is an important point. When prototyping or developing one-off utilities, I'm not looking to shave off CPU cycles or run everything under 6 MB. I wish someone would write a "Rust for Programmers". :)

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

#307
post #295
post #280

Earlier quoted context omitted.

If software companies got recalls and were sued for lack of quality like in other industries, by now everyone would care about how their code gets written.

Sure, but that's a different debate. If that would be the case, you would have much less competent programmers who would be able to do their job properly. I believe the software industry is still too young and immature.

On the contrary, only those able to meet the bar would be on the field, and we wouldn't have self taughs calling themselves engineers.

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

#308
post #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…

This is a gap I would like to be filled by an IDE. Specifically, I'd like the inference that tells me the correct type in a compile error to auto-complete a function declaration for me. It would make the experience of pulling code into a helper function much easier.

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

#309
post #98

Earlier quoted context omitted.

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.

[deleted]

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

#310

Earlier quoted context omitted.

It's interesting how perspectives differ; I love refactoring Rust code more than any language I've ever used, as it catches so many of my errors when doing so for me, at compile time.

I love Rust when it's refactoring time, the compiler essentially spits out a checklist that you just need to work through. And once it's done complaining it feels pretty confidence inspiring. But I'll agree that Rust is unpleasant for prototyping. What I find myself doing a lot when starting out a project is just figuring out if some snippet of code will work. There's no REPL to just run it in. Then I have to either…

Do you know about unimplemented!()? I use #[test] functions for what I'd throw into a REPL and if it's not horrible you can keep them as actual tests later.
Post reply on HN