Live data from Hacker News

How I went about learning Rust

eli.thegreenplace.net

261–270 of 303 posts

Re: How I went about learning Rust

#261
post #9
post #3

I have been thinking to myself whether I should pick up Go or Rust as a new language this year. Coming from a NodeJS background, Rust looks a tad more complicated but it looks cooler. There are also more job listings looking for Golang than Rust which makes me wonder if Golang might be a more rewarding investment? What would be a good use case of Rust than Golang cannot do given its extra complexity and potentially l…

As someone with extensive experience with Rust and a teensy bit of experience in Go I can tell you that I adore Rust for every use case I’ve tried it out for *except* for network services. It works ok for low level proxies and stuff like that; but Python/Flask-level easy it is not. Meanwhile my experience with Go has been the reverse. I’ve found it acceptable for most use cases, but for network services it really sta…

> I adore Rust for every use case I’ve tried it out for except for network service

thats hilarious, my daily driver language is elixir which is the goat for network services. I saw rust as the perfect compliment for that where I need everything else.

Re: How I went about learning Rust

#262
post #131

Earlier quoted context omitted.

Oh yeah, allowing values to be nullable by default is bad, that's totally different than just 'including null'. I thought they meant including null in the language! > you would set the score of someone who hasn't sat the test yet as `None` Yep that's what I expected. Emoji thumbs up.

>Oh yeah, allowing values to be nullable by default is bad, that's totally different than just 'including null'. In Rust (and Haskell and OCaml for that matter), there is no built-in null keyword. Option is just an enum in the library that happens to have a variant called None. So it's technically Option::None and Option::Some(x). But, really, it could be Quux and Quux::Bla and Quux::Boo(x) instead--without any langu…

For all practical purposes, in C# with nullability checks enabled, null is not a member of every type anymore: T? includes null, while T does not.

Re: How I went about learning Rust

#263
post #72
post #3

I have been thinking to myself whether I should pick up Go or Rust as a new language this year. Coming from a NodeJS background, Rust looks a tad more complicated but it looks cooler. There are also more job listings looking for Golang than Rust which makes me wonder if Golang might be a more rewarding investment? What would be a good use case of Rust than Golang cannot do given its extra complexity and potentially l…

One drawback of Go (in my opinion) is that it has a runtime. So it's very difficult (impossible) to use it with other languages that also have a runtime. So if you learn Go, you'll never be able to use it to interoperate with e.g. your Python program to speed it up. With Rust, you could use it to replace the most time critical parts of your high-level program piece by piece. The learning curve is then much easier, an…

Having a runtime does not, by itself, preclude interoperating with other languages that have their own runtime. Here's a project that does that for .NET and Python:

http://pythonnet.github.io/

(Note that this is not a reimplementation of Python on top of CLR, but rather a bridge between CLR and CPython.)

The thing that makes FFI problematic in Go is green threads, which have their own stacks that nothing but Go understands. Thus, every FFI call has to arrange things to be what the callee expects, and you can't do async using goroutines across language boundaries (whereas callback-based solutions like promises work jsut fine).

Re: How I went about learning Rust

#264
post #237

Serious question: can I just use smart pointer like feature of Rc/Arc combing with Mutex or RWLock instead of fighting borrow checker? I know this practice is shunned upon by Rust purists but I like to see how practical it is in real life and project. Especially around using Rust as a safer but more performant language instead of pushing for ultimate zero-cost abstraction and top notch performance.

In addition to munificient's response, I'd point out that this will likely have a significant performance cost. Since performance is one of the main reasons of using a low-level language like Rust, it should give you pause. I'm not saying there's anything bad with Arc + Mutex - they're certainly useful tools and great in some scenarios; it's just that I wouldn't reach out to them just to "avoid fighting the borrow ch…

Refcounting had been a very common way to implement resource cleanup for object graphs back in 90s already, in a much more resource-constrained environment. E.g. COM, which is widespread in Windows to this day, is all refcounted.

Re: How I went about learning Rust

#265

Serious question: can I just use smart pointer like feature of Rc/Arc combing with Mutex or RWLock instead of fighting borrow checker? I know this practice is shunned upon by Rust purists but I like to see how practical it is in real life and project. Especially around using Rust as a safer but more performant language instead of pushing for ultimate zero-cost abstraction and top notch performance.

The main drawback of trying to do this might be that the syntax is unwieldy. If you have one big shared object, or shared objects only in a specific part of your program, it's no big deal, and it arguably helps call attention to what's going on. But if everything is using Arc >, you'll have .write().unwrap() or similar on every line, and it'll feel terrible. The sibling comment mentioned cycle leaks, and in addition…

Agree that I should not just stick Rc everywhere. The use of borrow checkers makes a lot of sense at a macro scale, i.e: libraries, APIs. But, I’m just wondering the justification for using Rc in a smaller scope, say inside my own implementation of a trait. If I am to provide external APIs then yes, sticking Rc everywhere would not be a good idea ergonomically.

Re: How I went about learning Rust

#266
post #248

Earlier quoted context omitted.

> The compiler would enforce Number-ness every time I try and run a function that takes a number, right? > Wouldn’t I still have to check for NoScore? No, because you differentiate between the sum type (e.g. Maybe in Haskell) and the number type at compile time. It's a small distinction - there will still be one or two places where you ask "is this a Maybe-score, or a Just-Score, or a No-Score", but the upside is tha…

> I.e. if you pass maybe-scores to something that computes the mean, you'll get a compiler error. The writer of the mean function doesn't need to care you've overloaded an error value onto your numbers. If I pass a null into something that calculates an average, taking numbers, the TS compiler will complain now. The writer of mean() (assuming mean() is typed) doesn’t have to know anything about my code.

This only works for non-sentinels. I.e. if "-1" happens to be the value indicating NoScore, I don't think the TS compiler can catch that?

Re: How I went about learning Rust

#267
post #226

Earlier quoted context omitted.

We solved this with flat vectors and just sharing index values in cheap walker objects. It is much nicer to work with compared to arc/weak pointers. Code here: https://github.com/prisma/prisma-engines/tree/main/libs%2Fda...

How is this fundamentally different from raw pointers?

Not OP

It serializes better, it's memory safe, it can be much faster in performance terms, you can get better memory usage if you're holding a lot of "pointers" because the indexes don't need to be 64 bits.

Re: How I went about learning Rust

#268

Earlier quoted context omitted.

The main drawback of trying to do this might be that the syntax is unwieldy. If you have one big shared object, or shared objects only in a specific part of your program, it's no big deal, and it arguably helps call attention to what's going on. But if everything is using Arc >, you'll have .write().unwrap() or similar on every line, and it'll feel terrible. The sibling comment mentioned cycle leaks, and in addition…

Agree that I should not just stick Rc everywhere. The use of borrow checkers makes a lot of sense at a macro scale, i.e: libraries, APIs. But, I’m just wondering the justification for using Rc in a smaller scope, say inside my own implementation of a trait. If I am to provide external APIs then yes, sticking Rc everywhere would not be a good idea ergonomically.

I say give it a shot and see how it goes :)

One high level problem with learning Rust is that a lot of the patterns we use to work with the borrow checker are pretty non-obvious. (Things like using indexes instead of references, and avoiding methods that keep &self borrowed.) To the extend that Rc and Arc let you avoid learning those patterns, I agree with folks who say not to use them too much. But if you know how you might solve something without Rc, and you want to try it with Rc anyway to see how it feels, that's totally reasonable.

Re: How I went about learning Rust

#269
post #242

“How” is the stupidest word to auto-censor. Removing it completely changes the meaning of titles. It makes articles seem vapid or banal when they wouldn’t otherwise, and vice versa.

It changes the meaning of some titles. It makes more of them less baity. The danger with these arguments is that you only notice the cases that don't work. That's a 100% failure rate! Can't get more stupid than that! pg suggested this edit to me years ago and I spent a long time back testing it on old titles. At the time, it was a clear win. I suppose it's possible that title conventions have changed since then and t…

> The danger with these arguments is that you only notice the cases that don't work. That's a 100% failure rate! Can't get more stupid than that!

I’m gonna go out on a limb and suggest maybe you’re too close to this. I notice the “clear win” cases frequently too. At best they’re very clearly and awkwardly editorialized. I click on them frequently just to reassure myself that I’m aware I’m not mistaking reality for fiction. I do the same with “why” and “\d” editorialized titles that get auto-edits. Maybe the clear win is identifying clickbait, but the editing is definitely not effective.

Re: How I went about learning Rust

#270

Earlier quoted context omitted.

Read about sum types. They exist in Haskell, Rust, OCaml, Typescript, Swift, Kotlin, etc. You are likely only familiar with product types without knowing they're called product types. (Cartesian product) You can have 100% type-safe, guaranteed at compile time code without null that can still represent the absence of data. Once you've used sum types, you feel clumsy when using Javascript, Python, Go, Ruby, C, C++, etc…

Arguably dynamic languages have sum types: every variable is one big sum type with the variants being every other type! I suspect the lack of sum types in many static languages are partially responsible for the popularity of dynamic ones.

I would say that traits are a better analogy for dynamic types, but at the same time you can think of enums as closed sets and traits as open sets, so they are different ways of encoding sets of possible structure and functionality, more alike in what they provide than it initially seems.
Post reply on HN