Live data from Hacker News

Dave Herman’s contributions to Rust

brson.github.io

161–170 of 174 posts

Re: Dave Herman’s contributions to Rust

#161
post #91

Earlier quoted context omitted.

When I use rust, I find compile times faster and more manageable than other languages due to the speed of iterative compiles. Compiling from scratch is very slow, but iterative compiles are faster than most of my golang compiles and faster than running a JS builder in most projects. To make it extra fast, I follow the instructions from the bevy game engine[1]. With that setup, the feedback loop is quick. [1] https://…

> iterative compiles are faster than most of my golang compiles Maybe you're comparing apples to oranges here. I've worked professionally with both Rust and Go for years now on a variety of real world projects, and I've never seen a similarly-sized Go codebase that compiles slower than a Rust one. If you're comparing incremental Rust compilation to first-time Go compilation, maybe they could be competitive, but... Ru…

Possibly, when working with big codebases I'm typically working on Kubernetes controllers in both Golang and Rust. That makes for extra slow golang compiles, and the rust incremental compiles are significantly quicker in comparison. Otherwise the codebases tend to be quite small, and for those golang full compiles (the only option?) and rust incremental compiles are similarly nearly instant.

It is absolutely apples to oranges, but if you just care about the everyday local workflow and ability to iterate and test, it's close enough most of the time to not be much of a problem in either case.

I'm sure this experience isn't guaranteed for all codebases, and it certainly helps that I make heavy use of crates, which would minimize the work required during incremental compilation. Though I'm not actively going out of my way to optimize for incremental compilation really, beyond the config linked above.

Re: Dave Herman’s contributions to Rust

#162

Earlier quoted context omitted.

Having sat next to / worked with a lot of the rust core people (and Eich) I think while his support was important, that doesn't make him more important/pivotal than people like Dave Herman

It’s cool to erase me, no problem. Inconvenient facts: I hired Dave, as well as (not as hiring manager but by influence) Graydon. Also I’m cofounder of Mozilla Research and C-level advocate for grad student internships. I’m not taking more credit than them, I want less! But don’t erase sr. management or give anyone else at that level undue credit. It was a team effort, but while there is no “I” in team, there is no b…

Thanks for championing Rust!

Re: Dave Herman’s contributions to Rust

#163
post #67

Earlier quoted context omitted.

Personally, I find Rust syntax to be well-designed. At least, compared to any practical programming language I know. Quite a few times I was surprised that Rust breaks with some old patterns that were copied over and over in the last 50 years or so. For example: "match" instead of "switch", or the same if/else regardless if it is a statement or a value. These are small touches, but they show attention to detail.

I think that there's still time for Rust to reverse the .expect(...) naming mistake. It should be deprecated, either introducing something with an appropriate name like .unwrap_or_panic(...) or just leave it to be replaced by .unwrap_or_else(|| panic!(...)) which IMO one ought to use today instead of .expect(...). Everything else is named so well and designed so well that this really sticks out.

Why don't you like expect? It feels pretty natural to me.

    foo.expect("already validated")

Re: Dave Herman’s contributions to Rust

#164
post #161

Earlier quoted context omitted.

> iterative compiles are faster than most of my golang compiles Maybe you're comparing apples to oranges here. I've worked professionally with both Rust and Go for years now on a variety of real world projects, and I've never seen a similarly-sized Go codebase that compiles slower than a Rust one. If you're comparing incremental Rust compilation to first-time Go compilation, maybe they could be competitive, but... Ru…

Possibly, when working with big codebases I'm typically working on Kubernetes controllers in both Golang and Rust. That makes for extra slow golang compiles, and the rust incremental compiles are significantly quicker in comparison. Otherwise the codebases tend to be quite small, and for those golang full compiles (the only option?) and rust incremental compiles are similarly nearly instant. It is absolutely apples t…

Kubernetes is, unfortunately, not typical Go code. It uses a Makefile, which is never encouraged in Go, and it has a bunch of custom build scripts managed by that Makefile. I was looking at the Kubernetes issue tracker for other reasons, and came across one ticket open right now that mentions "fix excessive `go list` use in build scripts causing extremely long build times", so they know their build times are awful compared to what they should be. They don't even use Go Modules in the main Kubernetes code base, relying instead on $GOPATH which has been soft deprecated for years now, and hard deprecated possibly by the end of this year.

Plus, Kubernetes is sitting at 5 million lines of Go code, by my count. Try compiling a 5 million LoC Rust code base... I won't wait around.

I would assume that a controller written in Rust bypasses all the complex legacy of the Kubernetes code base, and that's why it can compile faster. If someone made a similar project in Go[0] to write Kubernetes controllers in Go without depending on the mega-Kubernetes code base, I'm sure it would be incredibly faster at compiling than the Rust version.

Beyond that, I've heard that the Kubernetes codebase is internally just a nightmare of basically untyped `interface{}` stuff floating around everywhere, which would make the development experience subpar. I don't know how much this is exposed to custom controllers.

So, if Kubernetes is your only experience with Go... I'm sorry you've had to experience that. It's a product that people seem to agree is functional and works most of the time, but I can't remember hearing any positive experience from people working on it. From what I understand, it was originally prototyped in Java, and then hastily rewritten into Go before public release, and I'm sure that didn't help things.

[0]: conceptually, maybe something like this? https://github.com/ericchiang/k8s or an updated fork of it like this: https://github.com/karlmutch/k8s No idea how well either works, if at all.

Re: Dave Herman’s contributions to Rust

#165
post #158

Earlier quoted context omitted.

Macros and compile-time function evaluation are different and fill different roles. Macros define new syntax, while compile-time function evaluation evaluates expressions written using the existing syntax. The corresponding Rust feature for the latter is not macros, but rather "const fn".

I think they both have potential performance issues in the compiler though, and both can be compared with textual code generation. I think of one as metaprogramming with the parser and the other as metaprogramming with an interpreter. (And the C preprocessor is metaprogramming with only a lexer. Code generation is the kind of metaprogramming that every language supports :) ) Although maybe you're saying Zig doesn't h…

In zig you get a compile error if you exceed 1000 backwards branches (e.g. a loop or a function call). If you want to raise the quota you bump it with e.g. `@setEvalBranchQuota(2000);`. This is how we solve the halting problem :)

Anyway if you want to know why your compile time is slow in a given zig project, you can probably get pretty far by grepping for calls to that builtin.

Re: Dave Herman’s contributions to Rust

#166
post #64

Earlier quoted context omitted.

Being in the team that created rust would look great on any CV. I think millionaire is reachable for many of them.

Under the current framework, you cannot get wealthy off of salary. If you working a wage, then you are a corporate slave most of the time.

Agree, millionare is not wealthy.

Re: Dave Herman’s contributions to Rust

#167

Earlier quoted context omitted.

I think that there's still time for Rust to reverse the .expect(...) naming mistake. It should be deprecated, either introducing something with an appropriate name like .unwrap_or_panic(...) or just leave it to be replaced by .unwrap_or_else(|| panic!(...)) which IMO one ought to use today instead of .expect(...). Everything else is named so well and designed so well that this really sticks out.

Why don't you like expect? It feels pretty natural to me. foo.expect("already validated")

That reads as "I expect this to be already validated". Is that what you intended it to mean? Similarly,

  foo.expect("There was a problem and I had to crash")
That _reads_ as "I expect there to be a problem and have to crash". But it _means_ something totally different. It means:

  There should not be a problem, but if there were a problem
  I would crash and print out this message.
And the way to write that in readable code is

  foo.unwrap_or_else(|| panic!("There was a problem and I had to crash"))
I'm sorry if I'm misunderstanding -- if I am can you explain to me how? Because I feel like my view is diametrically opposed to yours but it's really not that subjective a matter; only one of us can be right.

Re: Dave Herman’s contributions to Rust

#168

Earlier quoted context omitted.

Why don't you like expect? It feels pretty natural to me. foo.expect("already validated")

That reads as "I expect this to be already validated". Is that what you intended it to mean? Similarly, foo.expect("There was a problem and I had to crash") That _reads_ as "I expect there to be a problem and have to crash". But it _means_ something totally different. It means: There should not be a problem, but if there were a problem I would crash and print out this message. And the way to write that in readable co…

You just phrase things the opposite way. I don't think it's clearly better to say the expected happy path or the unexpected sad path in a crash message.

> That reads as "I expect this to be already validated". Is that what you intended it to mean?

Yes

> foo.expect("There was a problem and I had to crash")

> That _reads_ as "I expect there to be a problem and have to crash". But it _means_ something totally different. It means:

Absolutely. That's why I'd phrase it foo.expect("foo invariant upheld")

Re: Dave Herman’s contributions to Rust

#169
post #153

Earlier quoted context omitted.

> The mental model of & being immutable and &mut being mutable, that’s what falls apart. Here are types that are taking &, and yet are mutating themselves. &mut still implies mutability, and even the constructs like Mutex or RefCell still expose their mutability support via &mut references. Only atomics don't (they don't provide any &mut access). Note that you don't add const like in C/C++, you add &mut. As for the V…

Mutex::lock() takes &self. RefCell::borrow_mut() takes &self. Those (and try_ variants) are the main ways people will use those types to gain access to their interior mutability. Sure, both do have get_mut() which takes &mut self (though these came after 1.0), but that’s seldom how you’ll actually access it. > But even if Rust had &uniq and &shared pointers, the challenge would be the same. Remember again that the mu…

> Mutex::lock() takes &self. RefCell::borrow_mut() takes &self. Those (and try_ variants) are the main ways people will use those types to gain access to their interior mutability.

Yeah they take &self, but that wasn't my point. My point was what they expose, which is MutexGuard in the case of Mutex, and if you want to modify the interior, you'll likely use the DerefMut impl which returns a &mut T. Same goes for RefCell::borrow_mut().

My point was that you don't mutate a &self reference directly in these instances, but turn a &self reference into a &mut self reference and then mutate. Again, atomics are an exception.

> just that &mut is false advertising

it is not false advertising, it implies mutable access. Had Rust been mut by default and had &T been &const T instead, I would agree with the false advertisement point. But thankfully it's non-mut by default.

Anyways, even if &mut were false advertising, and it were a bump in the learning curve, note that &uniq is such a bump too, because you have no idea what it says or implies initially. &mut makes it clear that if you want to mutate, you'll likely need a &mut somewher. But &uniq does not make this obvious, so you are required to learn something early on in Rust's comprehension, while &mut requires you to learn something later on. Generally, Rust has been criticized for having a steep learning curve at the start. In general I think it's worth it to learn Rust, but this wouldn't make it any better but worse.

Re: Dave Herman’s contributions to Rust

#170

Earlier quoted context omitted.

That reads as "I expect this to be already validated". Is that what you intended it to mean? Similarly, foo.expect("There was a problem and I had to crash") That _reads_ as "I expect there to be a problem and have to crash". But it _means_ something totally different. It means: There should not be a problem, but if there were a problem I would crash and print out this message. And the way to write that in readable co…

You just phrase things the opposite way. I don't think it's clearly better to say the expected happy path or the unexpected sad path in a crash message. > That reads as "I expect this to be already validated". Is that what you intended it to mean? Yes > foo.expect("There was a problem and I had to crash") > That _reads_ as "I expect there to be a problem and have to crash". But it _means_ something totally different.…

OK, that would be nice but...what you're saying just doesn't work! The user gets an error message saying

  thread 'main' panicked at 'foo invariant upheld'
And everyone, except those who are inured to the illogic via experience, will read that as

  thread 'main' panicked because 'foo invariant upheld'
especially new users, less experienced programmers, and non-Rust programmers seeing the panic message.

Now if the Rust language made that error message say

  thread 'main' panicked at failed expectation for 'foo invariant upheld'
that might be cool. But it does not do that. It feels like you're bending over backwards trying to excuse what is clearly a wart in a beautiful language. I'm happy to continue the debate though, I am fascinated to know how I can be wrong here :)

So that's my main point, that your strategy doesn't work due to the error message. But a secondary point is that Rust documentation encourages people to use it opposite to what you suggest: I mean, just look at the first example in the Rust book. It's completely nonsensical:

  let f = File::open("hello.txt").expect("Failed to open hello.txt");

I know there was some controversy about this early on and somehow it didn't get reverted; it would be more honest if the docs would at least admit that it's "a little strange".

https://doc.rust-lang.org/book/ch09-02-recoverable-errors-wi...

Playground if you want to remind yourself of the psychological experience of seeing that error message at run time with minimal effort.

https://play.rust-lang.org/?version=stable&mode=debug&editio...

Post reply on HN