Live data from Hacker News

The struggle with Rust

ayende.com

171–180 of 301 posts

Re: The struggle with Rust

#171
post #53

When I first learned OCaml (knowing only Python), I swore a lot at the type checker for refusing to compile code that I knew would work at run-time (e.g., a variable having multiple types, but on strictly disjoint execution paths). It seemed insane to me that people would want to subject themselves to this kind of bondage and discipline. And yet, many years later now, I have learned and internalized how type systems…

> I believe that we are seeing the same kind of phenomenon in Rust: I don't know. I picked up OCaml fairly quickly, but I have consistently struggled with Rust, trying it for a while before abandoning it in frustration with lifetimes, 2 or 3 times. I can program in Rust, but it still seems like an ongoing struggle, as opposed to the smooth brain to text programming I've gotten used to in Python, JavaScript, OCaml, an…

> I think Rust may be ideal for embedded software development, or low-level systems software, but for general application development, I think OCaml or perhaps Swift or Scala are more ideal, at least for me (or at least until I decide to try Rust again, perhaps it will stick this time).

If you're not aware of it, scala-native looks very interesting... It looks to be active project.

https://github.com/scala-native/scala-native

FWIW, I've also enjoyed Swift development quite a bit. I think Swift will go deep into the C++ sweet spot.

Re: The struggle with Rust

#172

Earlier quoted context omitted.

First, the expressiveness is all there. You just need to explicitly say you are responsible by using unsafe blocks. So risky pointer and allocation logic becomes the programmer's job, not the borrow checker. Second, this article only considers the costs of a stricter borrow checker, not the benefits. It will be more work for the coder to have to think about how allocation and ownership is communicates. But I've been…

> Even if Rust is much harder than alternatives instead of just different, and even if that's inherent in borrow checking, it's not clear that it's still not worth it in the long run. One obvious argument is that Rust frontloads its difficulty. It's a terrible tool for most 30 line tasks, simply because the majority of your work will go into arguing with the compiler. But that's true of a great many tools - if there'…

"One obvious argument is that Rust frontloads its difficulty. It's a terrible tool for most 30 line tasks, simply because the majority of your work will go into arguing with the compiler. "

It does. Ada did too with people saying same stuff. Once they got used to it, they swore by Ada since their stuff usually worked after they got it past compiler. I also add that the alternative to Rust for GC-free safety of heap code is essentially separation (VCC) or matching logic (KCC). That's probably much harder for average programmer to work with than structuring stuff to get through borrow checker easily. Cyclone and then Rust were huge steps up on dynamic, memory safety given they're accessible to people who don't know formal verification.

That's the comparison people keep leaving off griping about borrow checker. I think Rust looks a lot better when one adds it. Still a headache but good in relative way.

Re: The struggle with Rust

#173

Earlier quoted context omitted.

C++ and Java are a bad example as they are unusually similar. Consider moving between C++, Python, and Javascript: on that scale, Rust doesn't seem so far out.

I doubt moving from Java to C++ would be that trivial, Java is a comparatively safe language without many of the issues that will trip you up in C++.

In particular, the lack of pointers in Java would probably annoy the article author as much as Rust does.

Re: The struggle with Rust

#174

Earlier quoted context omitted.

Agreed. Rust is different from other languages in that it is HARD to learn. It took me 3 projects and thousands of lines of code before I finally felt like I'm okay at Rust. Each project involved tons of compiler fighting that I now know how to avoid or solve. The problem is that instead of a general technique for solving borrow checker issues, every issue has a different specific technique. Hash map matches (like th…

> Agreed. Rust is different from other languages in that it is HARD to learn But do you learn to code in a different paradigm where you don't struggle by iterating on a compilable and runnable piece of code, but rather struggle on iterating on a non-compilable piece of code and "once it compiles, it works"?

Definitely and I'd say the struggle is only there for the first couple of weeks.

This will get shorter as tooling gets better this year.

Re: The struggle with Rust

#175

Earlier quoted context omitted.

They have that with the "unsafe" blocks but like I said promoting it as something you should use when things don't fit borrow-checker goes against their primary goal of making things safe. I guess there are two camps, one that wants compile time safety guarantees - those people made Rust, and the other wants a C++ replacement with modern tooling and no legacy garbage - those are looking at Rust and getting discourage…

As I understand it, you can't disable just borrow checker somewhere where you don't need it.

It's subtle. Unsafe Rust is a superset of safe Rust; that is, all valid safe Rust code is valid unsafe Rust code.

  fn foo() {
      unsafe {
          let x = &5; // this is still going to get borrow checked
      }
  }
Since it's a superset, it gives you access to new tools, that don't interact with the borrow checker, rather than "turning the borrow checker off".

  fn foo() {
      unsafe {
          let x = *const 5; // this is not going to get borrow checked
      }
  }

Re: The struggle with Rust

#176
post #80

Earlier quoted context omitted.

> I want the compiler to tell me when I'm making the mistake, even if it makes things choppier. You don't think the OCaml type system would do this? OCaml gives you just as much safety as Rust does, it just doesn't also give you no GC like Rust does. And the price Rust pays for the absence of GC is the lifetime concept, which adds a very significant layer of complexity to the language. Much like OCaml, Swift and Scal…

OCaml seems like the argument against Rust's claim to trade usability for safety. It's not true for everything, I wouldn't write embedded OCaml, but it's an easy disproof-by-example for "Rust's difficulty is the inevitable price for trustworthy code!" Which isn't to say OCaml is trivial, or Rust is useless (GC and threading both being limitations). It just makes me skeptical of claims that Rust's difficulty is irredu…

But OCaml isn't intended for the use cases Rust is intended for: a replacement for C and C++

Re: The struggle with Rust

#177

When I first learned OCaml (knowing only Python), I swore a lot at the type checker for refusing to compile code that I knew would work at run-time (e.g., a variable having multiple types, but on strictly disjoint execution paths). It seemed insane to me that people would want to subject themselves to this kind of bondage and discipline. And yet, many years later now, I have learned and internalized how type systems…

Not related to the topic but how do you find ocaml as compared to python or rust? Do you think its worth learning today as opposed to rust for high level general purpose programming?

I'll also add to their recommendations that GC'd languages can be used for OS's or system code. You can do that with a number of strategies:

1. Go unsafe on lowest-level operations that simply can't be GC'd. Quite a few of these can be expressed as finite, state machines which can be model-checked for correctness. Static analyzers are also really good these days in whatever code you can avoid dynamic allocation in. The rest of the code is GC'd. That's what the Oberon operating systems do.

2. Use a real-time, low-latency, concurrent GC that basically knocks low single or two digit performance out of the system. Lots of products in embedded Java have special GC's for that. Buy a faster CPU. Trade dollars or performance for productivity and safety.

3. Use a mix of GC's in the system where each one is tuned for the job at hand. You might use a real-time, concurrent one in the kernel. Maybe just reference counting in one more about performance. Maybe a straight-forward one for stuff that's not performance-critical. Could even use one that's mathematically verified for correctness in that situation. JX Operating System is an example of OS that mixes up GC strategies.

That's for software. Your options open up a bit if you can also deploy custom hardware. At the least, a modified soft-core on an FPGA. The LISP machines & maybe a Java CPU of the past often included hardware acceleration for garbage collection. One built the GC right into memory subsystem/interface of the processor where neither the processor nor applications had to be aware of its existence. It just did its thing in parallel to execution of the app. A concurrent, low-latency one integrated with virtual, memory hardware shouldn't take much hardware resources to pull off.

Re: The struggle with Rust

#178
post #166
post #141

Earlier quoted context omitted.

>Either way, it feels like part of the learning curve is learning the "Rustic" way to do something - in general, you probably shouldn't be reaching for "unsafe" until you know what you're doing! ;) I tend to agree with this sentiment. The moment I saw that OP was doing pointer arithmetic: I knew they were in for a bad time. It's not that you can't do it -- it's moreso that Rust's raison d'etre is to highlight the fla…

In other words, you weren't using it as the systems language it's billed as. Which is fine, but it's claimed to be a systems level language, and if it's really that painful to do systems level things, then there's a problem somewhere. Which is what's being discussed.

>and if it's really that painful to do systems level things, then there's a problem somewhere.

To me it's not a problem at all, Rust is working exactly as designed. When you start writing code in the style that Ayende has: its memory layout becomes entirely non-obvious. The structure definition no longer lines up with how that memory is actually being used. You'll need documentation of the sentinels & invariants, you'll want diagrams of the memory layout (since it won't line up with the structure definition), and a careful understanding of every line of code packing the bytes -- that's just to get a basic understanding of what's actually going on.

This is fine, and you absolutely need to be able to do it, which is exactly why Rust provides `unsafe {}` (along with `std::ptr` and `std::mem`.) Sometimes you need that control you want a memory-efficient data structure, other times that's because you're reading registers directly off the hardware. In either case Rust is going to make you use `unsafe {}` which is a signal to say: "to understand how this is really laid out in memory you need to understand every single line in this block."

I would much rather be able to grep for `unsafe {}` and audit parts of a trie-map for memory safety, as opposed to auditing my entire program for memory safety violations. That's not a failing of Rust, it's functioning exactly as intended. Trying to squeeze every last byte out of a struct is neither obvious nor safe, it requires careful thought.

Re: The struggle with Rust

#179
post #169
post #97

Earlier quoted context omitted.

My point is that C++ has a learning curve that's as steep as Rust's. Rust is a C++ replacement. So this isn't a disadvantage for Rust. It may stop Rust from getting widespread adoption, but I see no problem with that. C++ isn't "widely used" either by most meanings. Rust may still largely replace C++ even without magically having a less steep learning curve. (Which it, IMHO, actually has anyway.)

> My point is that C++ has a learning curve that's as steep as Rust's. Rust is a C++ replacement. So this isn't a disadvantage for Rust. As someone who learned C++ first and later Rust, no it isn't. Rust's learning curve is a hell of a lot higher than C++'s. This reminds me of when Java was trying to compete with C++, you would have all these Java people making claims that HotSpot was going to take over the world and…

> Rust's learning curve is a hell of a lot higher than C++'s

I had the exact opposite experience, i.e. Rust allows me to not worry about memory safety and allows me to think on a much closer level of abstraction to my problem domain than C++.

Re: The struggle with Rust

#180
post #80

Earlier quoted context omitted.

> I want the compiler to tell me when I'm making the mistake, even if it makes things choppier. You don't think the OCaml type system would do this? OCaml gives you just as much safety as Rust does, it just doesn't also give you no GC like Rust does. And the price Rust pays for the absence of GC is the lifetime concept, which adds a very significant layer of complexity to the language. Much like OCaml, Swift and Scal…

Ownership and borrowing are also useful for avoiding data races. OCaml solves the problem by not having any shared state at all, which is obviously a huge limitation.

Current OCaml needn't worry about data races since no state is shared. Unfortunately, current OCaml also only exploits a single core, but it's so insanely fast that usually doesn't matter.

Upcoming OCaml multicore solves the shared state and data races problem with algebraic effects[0]. It is working, it's just not yet been released in mainline OCaml. Supposedly, that will happen this year, but we'll see.

0. http://kcsrk.info/ocaml/multicore/2015/05/20/effects-multico...

Post reply on HN