Live data from Hacker News

Rewriting Rust

josephg.com

261–270 of 410 posts

Re: Rewriting Rust

#261

Earlier quoted context omitted.

> I personally use two conditionals for such case. Me too. But that often makes my logic worse. Its quite common to want to share the same code in the else branch, for example: if let Some(val) = opt { if expr { // .... } else { do_complex_stuff(); } } else { do_complex_stuff(); } I don't want to copy+paste that complex code in two places. And you can fix that in turn with a named block & named break statements or a…

I'm worried that you want a "good" language at any circumstance, which is not even generally possible but also at odds with other aspects of languages. This still counts as minor for me because it is just slightly annoying and doesn't make something impossible or much harder to read (and the readability varies enough that this threshold is much higher than this case).

> I'm worried that you want a "good" language at any circumstance, which is not even generally possible but also at odds with other aspects of languages.

Yes, I do want a good programming language. I agree its relatively minor compared to the other issues I talked about in the blog post.

In what way is this at odds with other aspects of the language? If its at odds with the rest of the language, why is this feature being added?

https://rust-lang.github.io/rfcs/2497-if-let-chains.html

Re: Rewriting Rust

#262
post #15

I think the dependency situation is pretty rough, and very few folks want to admit it. An example I recently stumbled upon: the cargo-watch[0] crate. At its core its a pretty simple app. I watches for file changes, and re-runs the compiler. The implementation is less than 1000 lines of code. But what happens if I vendor the dependencies? It turns out, the deps add up to almost 4 million lines of Rust code, spread acr…

This is a natural and not really scary thing. All code is built on mountains of dependencies that by their nature will do more than what you are using them for. For example, part of cargo watch is to bring in a win32 API wrapper library (which is just autogenerated bindings for win32 calls). Of course that thing is going to be massive while watch is using only a sliver of it in the case it's built for windows. The st…

> The alternative is the npm hellscape where you have a package for "isOdd" and a package for "is even" that can break the entire ecosystem if the owner is disgruntled because everything depends on them.

This used to be true 5-10 years ago. The js ecosystem moves fast and much has been done to fix the dependency sprawl.

Re: Rewriting Rust

#263
Shouldn’t read this without also reading Josh Triplett’s comment in response on reddit. One of the core examples in this post is just plain wrong (mutexes), for example: https://old.reddit.com/r/rust/comments/1fpomvp/rewriting_rus...

Edit: nevermind, comment is here too: https://news.ycombinator.com/item?id=41655268

Re: Rewriting Rust

#264

Earlier quoted context omitted.

These features are slow to be accepted for good reasons, not just out of some sort of pique. For example, the design space around combining `if let` pattern matching with boolean expressions has a lot of fraught issues around the scoping of the bindings declared in the pattern. This becomes especially complex when you consider the `||` operator. The obvious examples you want to use work fine, but the feature needs to…

> The obvious examples you want to use work fine, but the feature needs to be designed in such a way that the language remains internally consistent and works in all edge cases. True. How long should that process take? A month? A year? Two years? I ask because this feature has been talked about since I started using rust - which (I just checked) was at the start of 2017. Thats nearly 8 years ago now. 6 years ago this…

I don't deny that Pin is complicated to use as it stands (in fact that is the entire thrust of my blog posts!), just that there is some magical easier solution involving Move and changes to the borrow checker. You wrote something on the back of a napkin and you imagine its better, whereas I actually had to ship a feature that works.

The state of async Rust is not better because no one hired me to finish it past the MVP. I have solutions to all of your problems (implementing a stream with async/await, making Pin easier to use, etc). Since I am not working on it the project has spun its wheels on goofy ideas and gotten almost no work done in this space for years. I agree this is a bad situation. I've devoted a lot of my free time in the past year to explaining what I think the project should do, and its slowly starting to move in that direction.

My understanding is that if let chaining is stalled because some within the project want to pretend there's a solution where a pattern matching operator could actually be a boolean expression. I agree that stalling things forever on the idea that there will magically be a perfect solution that has every desirable property in the future is a bad pattern of behavior that the Rust project exhibits. Tony Hoare had this insightful thing to say:

> One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.

> The first method is far more difficult. It demands the same skill, devotion, insight, and even inspiration as the discovery of the simple physical laws which underlie the complex phenomena of nature. It also requires a willingness to accept objectives which are limited by physical, logical, and technological constraints, and to accept a compromise when conflicting objectives cannot be met. No committee will ever do this until it is too late.

Re: Rewriting Rust

#265

Earlier quoted context omitted.

Author here. Yeah thats my thinking. I also think you probably only need to restrict your dependencies. If you have a dep tree like this: a |-b |-c Then if crate a decides b isn't trusted, c would inherit the same trust rules. This would allow crates to be refactored, but keep the list of rules needed in big projects to a minimum. You just have to add explicit rules for sub-crates which need more permissions. Thats p…

What if dep tree is like this: a |-b | |-c | |-c |-d |-c I may have read not carefully, but what happens if you allow crate X to write files, and it gets compromised? Should we set restrictions on per-call base instead? I see we may catch those situations when a crate starts reading/writing when it hadn't, or in an unexpected place, if we set restrictions per call, but this only limits the attack surface, not elimina…

> I may have read not carefully, but what happens if you allow crate X to write files, and it gets compromised? Should we set restrictions on per-call base instead?

Yeah, these are important details to figure out. But lets not let perfect be the enemy of good here. We're arguing about what brand of lock to buy for the back door of the house, when the front door is currently wide open.

After all - I think most programs will allow 1 or, usually 0 crates to write files anyway. Limiting the attack surface to 1% of where it is today is a huge win, even if its not perfect.

When it comes to files, the privileged operation should really be opening a file (at some path). Writing to a file handle you've been given is relatively a much safer operation. Files should usually be (only) opened by the main process. Then the opened file handle can be handed to any functions / structs in 3rd party crates which need access.

Re: Rewriting Rust

#266

Earlier quoted context omitted.

These features are slow to be accepted for good reasons, not just out of some sort of pique. For example, the design space around combining `if let` pattern matching with boolean expressions has a lot of fraught issues around the scoping of the bindings declared in the pattern. This becomes especially complex when you consider the `||` operator. The obvious examples you want to use work fine, but the feature needs to…

I think you just proved his point on how hard it is to understand and correctly use Pin.

I agree with that assessment of Pin. That's why the second post I linked to presents a set of features that would make it as easy to use as mutability (pinning is really the dual of immutability: an immutable place cannot be assigned into, whereas a pinned place cannot be moved out of).

Re: Rewriting Rust

#267

Earlier quoted context omitted.

> Namespace is not a solution for name squatting: namespace is just yet another identifier that can be squatted. If you are worried about squatting, the only effective solution is sandboxing, everything else is just moving the goal post. The problems crates.io struggles with have never been an issue with Maven, regardless of how creatively you try to redefine words. That's a fact. Deal with it.

How can you be that sure? :-) It is not even like that Maven repositories don't suffer from malicious packages with confusing names (for example, [1])... [1] https://github.com/spring-projects/spring-ai/issues/537

That seems to be an absolute win to be honest. Not sure how you think this is helping your case.

Maven Central people nuked the artifact that may have caused confusion, and if the owners try anything like that again, it's likely their domain will be banned from publishing.

Re: Rewriting Rust

#268

Earlier quoted context omitted.

> If we could go back in time and have the rust project decide to never implement async, I wonder what rust would look like today. If withoutboats is right [1], then Rust would never have received the industry backing to be as successful as it is now. [1]: https://without.boats/blog/why-async-rust/ especially the section "Organizational considerations"

"Pleasing to corporate sponsors" isn't what comes to mind when I think about great programming languages.

But it probably is a prerequisite for any project achieving its mission on a large scale. I'd rather have a programming language that makes a big positive impact in the security, reliability, and efficiency of software that lots of people use, than one that's aesthetically pleasing but not widely used.

Re: Rewriting Rust

#269

Earlier quoted context omitted.

These features are slow to be accepted for good reasons, not just out of some sort of pique. For example, the design space around combining `if let` pattern matching with boolean expressions has a lot of fraught issues around the scoping of the bindings declared in the pattern. This becomes especially complex when you consider the `||` operator. The obvious examples you want to use work fine, but the feature needs to…

A properly designed feature shouldn’t require an entire blog post, let alone multiple, to understand.

So… all programming languages are not properly designed? People usually need to study for months to be able to use their first one.

Sometimes you need knowledge to understand things.

Re: Rewriting Rust

#270

Earlier quoted context omitted.

Why, concretely, does this matter? Other than people who care about relatively obscure concerns like distro packaging, nobody is impeded in their work in any practical way by crates having a lot of transitive dependencies.

Author here. If I compile a package which has 1000 transitive dependencies written by different authors, there's ~1000 people who can execute arbitrary code on my computer, with my full user permissions. I wouldn't even know if they did. That sounds like a massive security problem to me. All it would take is one popular crate to get hacked / bribed / taken over and we're all done for. Giving thousands of strangers th…

Rust can't prevent crates from doing anything. It's not a sandbox language, and can't be made into one without losing its systems programming power and compatibility with C/C++ way of working.

There are countless obscure holes in rustc, LLVM, and linkers, because they were never meant to be a security barrier against the code they compile. This doesn't affect normal programs, because the exploits are impossible to write by accident, but they are possible to write on purpose.

---

Secondly, it's not 1000 crates from 1000 people. Rust projects tend to split themselves into dozens of micro packages. It's almost like splitting code across multiple .c files, except they're visible in Cargo. Many packages are from a few prolific authors and rust-lang members.

The risk is there, but it's not as outsized as it seems.

Maintainers of your distro do not review code they pull in for security, and the libraries you link to have their own transitive dependencies from hundreds of people, but you usually just don't see them: https://wiki.alopex.li/LetsBeRealAboutDependencies

Rust has cargo-vet and cargo-crev for vetting of dependencies. It's actually much easier to review code of small single-purpose packages.

Post reply on HN