Live data from Hacker News

Announcing Rust 1.20

blog.rust-lang.org

261–270 of 277 posts

Re: Announcing Rust 1.20

#261

Earlier quoted context omitted.

That sounds about right.

Wow, I can't believe I have been reading up lately on official Rust documentation and still I was under the impression that Rust had optional GC. Thanks for sorting me out...

Well, I think is sort of does when you use the Rc types, right? It's just much more explicit than a type modifier, it's a type wrapper that requires requires some level of additional code ornamentation in some instances when using later as well. It's just not really any different than using a library in C++ that offers the same, except that in Rust's case the library is part of the stdlib.

Re: Announcing Rust 1.20

#262

Earlier quoted context omitted.

Proofs and specifications are different things. Users need to be able to read specifications. For example, if you want to talk about definedness for arrays, a predicate defined(arrayname, lowbound, highbound) is helpful. That goes in assert statements. It's run-time checkable, if you have some extra state in the form of "is defined" flags. But you'd rather prove it once so the run-time checks are unnecessary. With a…

> That goes in assert statements. It's run-time checkable And runtime checks help because...? > But you'd rather prove it once so the run-time checks are unnecessary. No. I'd rather prove it to rule out the program being wrong. The runtime check is totally besides the point. > With a few simple theorems, such as (...) I think you mean “proposition”. It's not a theorem until it has been proven. > Think of proof suppor…

> > But you'd rather prove it once so the run-time checks are unnecessary.

> No. I'd rather prove it to rule out the program being wrong. The runtime check is totally besides the point.

That's the same thing. It's just a matter of it being automated.

> > Think of proof support as being an extension to optimization of assertions.

> I never use runtime-checked assertions, so I never need to optimize them away.

If you've ever used a language that uses bounds checked array access, you have. IIRC, you've used Rust some, so you've used bounds checked array access, except where Rust was able to prove that out of bounds access was impossible and elide the code that checks.

> > Users need never see those proofs.

> But, you see, I want to see the proofs. How am I supposed to maintain a program I don't understand?

There's a difference between need and ability. Just because it's stated you don't need to see something doesn't mean you can't. If you want to see a proof, you dig in and find it, or find where it's accepted canon that we don't need to reproduce (do we need proofs for integer addition? That seems of limited use to me, but maybe a formally proved as much as possible all the way to that level language has some interesting benefits).

Re: Announcing Rust 1.20

#263

Earlier quoted context omitted.

> That goes in assert statements. It's run-time checkable And runtime checks help because...? > But you'd rather prove it once so the run-time checks are unnecessary. No. I'd rather prove it to rule out the program being wrong. The runtime check is totally besides the point. > With a few simple theorems, such as (...) I think you mean “proposition”. It's not a theorem until it has been proven. > Think of proof suppor…

> > But you'd rather prove it once so the run-time checks are unnecessary. > No. I'd rather prove it to rule out the program being wrong. The runtime check is totally besides the point. That's the same thing. It's just a matter of it being automated. > > Think of proof support as being an extension to optimization of assertions. > I never use runtime-checked assertions, so I never need to optimize them away. If you'v…

> That's the same thing. It's just a matter of it being automated.

Re-read what he said. He presented runtime checks as an acceptable but non-optimal scenario for performance reasons. My reply was that runtime checks don't prevent a wrong program from being wrong, and it's this wrongness itself that I consider unacceptable.

> IIRC, you've used Rust some, so you've used bounds checked array access, except where Rust was able to prove that out of bounds access was impossible and elide the code that checks.

Runtime bounds-checked array manipulation is literally the single thing I hate the most about the languages I like the most (ML and Rust). It introduces a control flow path that shouldn't be reachable in a correct program, and hence shouldn't exist. This is particularly painful because beautiful array-manipulating algorithms have existed since, like, forever, yet in 2017 I still can't express them elegantly.

> If you want to see a proof, you dig in and find it, or find where it's accepted canon that we don't need to reproduce (do we need proofs for integer addition)?

I don't need to rebuild arithmetic from scratch again, because I've already done it at some point in time, and once is enough as long as you understand the process.

On the other hand, when I'm first confronted with an already existing program, I don't understand why the program is correct (if it is even correct in the first place), so I do have to set some time aside to properly study it.

Re: Announcing Rust 1.20

#264
post #250

Earlier quoted context omitted.

I actually think having syntactic methods is an important (if not the most important) part of "OOP". You compared x.foo() with foo(x), but that's the wrong comparison. The correct comparison is that when x if of type Tree, x.foo() vs tree_foo(x). Otherwise you get name clashes. That is, I think the essence of "OOP", OOP-as-used, not any theoretical OOP, is function name resolution depending on type. That and syntax.…

Function name resolution isn't OOP, it's attaching a namespace to a type. The _really_ important part is dynamic dispatch. You can have proper OOP without method syntax, it just looks awkward to our eyes. In fact, in Objective C, [obj doStuff: foo withBar: bar] gets desugared into objc_msgSend(obj, NSSelectorFromString(@“doStuff:withBar:”), foo, bar)

I already agreed function name resolution isn't OOP. My argument was that it is "OOP", with quotes. My supporting evidence is that people consider C++ without any dynamic dispatch as "OOP", with quotes.

Re: Announcing Rust 1.20

#265
post #244

Earlier quoted context omitted.

It doesn't matter that it's 'kind of unusual', even though I contend that it isn't. Even if, for the sake of argument, we assume that it is, that doesn't change my point. My point is that the whole point of Rust is supposedly that it >is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. except that when you look at any of the examples of code that really would…

> examples of code that really would benefit from the compiler's help This seems to be the point of disagreement here, and I think evidence clearly shows that you are wrong. Sure, Rust doesn't help you when writing the implementation of e.g. circular data structures. But what it does do is provide, far beyond C or C++, the tools for the author of that data structure to enforce that it's used correctly. And as mention…

I think you need to be careful with those comparisons. Comparing Rust programmes that are modern and take advantage of not just Rust but all the knowledge we have about safety and security and writing fast code for modern platforms with projects that are ancient and full of cruft? That's not really fair.

New modern C++ programmes don't have any memory safety bugs either.

Re: Announcing Rust 1.20

#266

Earlier quoted context omitted.

Rust doesn't ensure memory safety or safe concurrency. It ensures memory safety - including data race safety, just one part of safe concurrency - assuming you never use any unsafe code and that the standard library is free of bugs. I'm happy to assume the standard library is free of memory safety bugs, because you have to trust something. But I'm not happy trusting that dependencies aren't using unsafe code, and I'm…

Unsafe blocks are infectious, that's true, but it's possible to write safe APIs that limit that infectiousness to a single module. For example, even though Vec's implementation is crazy unsafe, you don't have to audit all the uses of Vec in safe programs -- a local audit of the Vec code can prove what we need to prove. This is the biggest benefit of the lifetime system and the borrow checker, that when we write piles…

You can prove it, but you can also prove that a C++ programme has no memory safety bugs. And there are a lot of languages where you don't have to, where it's simply impossible to get memory safety bugs (assuming the runtime is safe).

For nontrivial libraries that use a lot of unsafe, it really is very difficult to know that all the uses of unsafe don't interact in some way to create unsafety. The scoped lock that had a problem in Rust 1.0 (or just before it?) is an example.

You can force callers to maintain your invariants in C++ too, simply by using some basic safety. Yes people can still do things that are obviously visually unsafe in code and undefined, but that's not a serious issue.

I still think Rust is better here. Don't get me wrong. But it's very hyped as 'safe and fast' when it just isn't safe.

Re: Announcing Rust 1.20

#267
post #235

Earlier quoted context omitted.

Probably. I used to do formal proof of correctness work and headed a project to build a verifier.[1] That stuff is very hard. The partially initialized array thing is an issue of expressive power. You can't talk about that in Rust yet. This is a classic issue. The three big headaches in C around memory safety are "how big is it", "who owns it", and "who locks it". The language lacks the syntax to even talk about thos…

> Before you can even consider verifying something, you have to be able to talk about it in some formal language. Preferably the one you're programming in. I'd personally be excited too see a modern language implement this. I saw the potential for this type of verification in my (hobbyist) dabbling with Haskell. Which subsequently inspired me to relearn math, including a great book on proofs recommended on HN which r…

What book was that?

Re: Announcing Rust 1.20

#268

Earlier quoted context omitted.

Have you read "Learning Rust With Entirely Too Many Linked Lists"[1]? I think it will be quite helpful for these kind of situations. It walks you through all the possible tools in the language that is available to you, and at the end, if you just want to write it how you would in C, you could always do it "unsafely" with raw pointers (which is no worse than C). --- [1] http://cglab.ca/~abeinges/blah/too-many-lists/bo…

It's also really no better than C. Or at least no better than C++. This is my main issue with Rust. It doesn't seem to really solve the right problem. I feel like it solves the easy problems that I already know how to solve easily, but as soon as I get to something that really, truly feels like I want it, the best solution is unsafe. A complicated circular linked data structure is exactly where I want the language to…

If freedom from data and race conditions is the easily solved problems, I'll take it.

The problems with engineering solutions that approach something close to the end of the spectrum of perfection, is that it gets undo criticism for not being perfect-enough. Rust is hopefully a stepping stone along path towards more correct, less error prone computation. Lets not throw the baby out with the bathwater.

Re: Announcing Rust 1.20

#269
post #236
post #230

Earlier quoted context omitted.

IIRC, Rust's HashMap uses a single raw vector containing for each entry its hash code, its key, and its value; empty entries have a special hash code as a marker, with the key/value left uninitialized. Also, the hashes are kept together (separate from the rest) for better cache behavior during the linear probing.

Wouldn't that be two parallel vectors? (Side note: nobody ever thinks to bring up cache behavior in interviews where I ask about how a hash map could be implemented - it's nice to know that the library writers care :) ) How does that special hash marker work? What happens when something actually hashes to it? Just silently increment the hash?

> Wouldn't that be two parallel vectors?

Yes, but it's a single contiguous memory allocation. (It used to be three parallel vectors in a single allocation, with keys and values also kept separate to avoid padding between them, but experiments showed that had worse cache behavior.)

> How does that special hash marker work? What happens when something actually hashes to it? Just silently increment the hash?

Looking at the code, it always sets the most significant bit of every real hash value (since the least significant bits select the bucket, it makes no difference), and the marker has the most significant bit clear (in fact, all bits of the marker value are clear).

Re: Announcing Rust 1.20

#270
And here I am, still waiting for the second edition of that book on learning Rust to be finished. I want to learn Rust for fun and I know I should probably just start on reading the book, but I keep making up excuses not to. I want my ++, --, ?:, SIMD, etc.
Post reply on HN