Live data from Hacker News

Rewriting Rust

josephg.com

181–190 of 410 posts

Re: Rewriting Rust

#181
I think the first three items are "add effects, and do it right":

Capabilities to IO can be done by letting IO functions interrupt and call an effect handler, and the caller can specify the effect handler and do access control in there.

The whole Pin situation only exists because async/await was an afterthought and didn't work well with the existing language. async/await is an instance of effects.

I'm excited to start playing with a language that has a good effect system. I am hoping on Ante, but would also like to try Roc at some point.

Re: Rewriting Rust

#182
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…

I bet most of those lines are from the generated windows api crates. They are notoriously monstrous

I love and hate the Windows API crates. They're amazing in that they bring pretty much the entire modern Windows API into the language without needing to touch FFI generators yourself, but the Windows API is about as large as almost every package that comes with a desktop Linux install.

I wish crates that used Windows stuff wouldn't enable it by default.

Re: Rewriting Rust

#183

> The rust RFC process is a graveyard of good ideas. I actually have quite an opposite view: I think the Rust core team is 100% correct to make it very hard to add new "features" to the PL, in order to prevent the "language surface" from being bloated, inconsistent and unpredictable. I've seen this happen before: I started out as a Swift fan, even though I have been working with Objective-C++ for years, considered it…

Author here. I hear what you're saying. But there's lots of times while using rust where the language supports feature X and feature Y, but the features can't be used together. For example, you can write functions which return an impl Trait. And structs can contain arbitrary fields. But you can't write a struct which contains a value returned via impl Trait - because you can't name the type. Or, I can write if a && b…

I think it would be helpful to clearly distinguish between PL simplification (e.g., "if let Some(x) = x, x == 42 {}") and convenience-driven PL expansion (e.g., "let @discardable lhs = rhs ?? 0;"). In case of the former, I'm with you. In case of the latter, I'm not. Rust likely isn't meant to be a tool that is easy to learn at all costs (since the borrow checker does exist, after all). Rust is, IMvHO, supposed to be like vi: hard to learn and easy to use :).

Re: Rewriting Rust

#184

Earlier quoted context omitted.

Maybe. But javascript is arguably in that phase of its life as well, and JS has had a oodles of wonderful new features added in the last decade. Features like the spread operator, generator functions, async, arrow functions, leftpad, a new Date, and so on. The list of significant new features is endless. All that, despite JS being much older than rust, and much more widely used. Javascript also has several production…

Javascript has a quite different use-case audience than Rust. As an example, try to convince a guy like Linus Torvalds to officially support a particular PL for Linux kernel development, when his absolute priority (quite rightly so) is predicable, performant and portable code generation on the same level as raw C, with ease-of-use of a PL not being even a distant second, if considered at all. JavaScript does not real…

Author here.

> Javascript has a quite different use-case audience than Rust.

Eh. That sounds like a "just so" explanation to me. Linus Torvalds doesn't work on the rust compiler.

I think I could make much more convincing arguments that javascript should move slower than rust - given there's so many large language runtime projects. (V8, Safari, Javascript, Node, Deno, Bun, etc etc). But evidently, that isn't the case.

I'm open to the reason for rust's slow development being that the language developers want the language to move slowly. Thats fine. But, I personally don't want that. I've been waiting for generators to ship for 7 years. Or TAIT to appear - again, for years. I'd much rather rust to move faster.

Of course I attribute all of this to the process & team which makes these decisions. What else is there? What else has any affect on the development of rust?

Re: Rewriting Rust

#185
post #70

Earlier quoted context omitted.

This isn't necessarily a language problem, though, more of a "culture" problem, I think. I write in Clojure and I take great pains to avoid introducing dependencies. Contrary to the popular mantra, I will sometimes implement functionality instead of using a library, when the functionality is simple, or when the intersection area with the application is large (e.g. the library doesn't bring as many benefits as just us…

> This isn't necessarily a language problem, though, more of a "culture" problem, I think. Author here. We could make it a language problem by having the language sandbox dependencies by default. Seems like an easy win to me. Technical solutions are almost always easier to implement than social solutions.

Edit: replied to wrong person.

Re: Rewriting Rust

#186

If I were to rewrite Rust, I'd probably go the route of less features, not more. Make it 70% of Rust in 10% of the code, similarly to what QBE[0] is doing with LLVM. You'd probably be able to achieve that if you remove macros and some of the rarely-used features. [0]: https://c9x.me/compile/

Not to downplay QBE, but the initial goal of QBE was to provide 90% of the performance in 10% of the code, until it was changed to 70%. You generally don't know how much of Rust (or anything else) is possible without actually trying.

I wonder how soon they will arrive at 80%/20%.

Re: Rewriting Rust

#187

> Most crates I use - like human-size or serde don't need any special capabilities to work. So we don't need to worry so much about their authors "turning evil" and adding malicious code to our software well... :-( Actually, it's obvious that some authors might "turn evil" dumbly, by abusing some kind of priviledged permissions. By chance, these kinds of supply-chain risks are "easily" identified because 1) the permi…

Is there a known ratio of crates that use unsafe to ones that don't? It feels like most nontrivial crates would often need some unsafe. But a system like this might create a scenario where crates offload some of their unsafe code into separate crates so they need updating less frequently (Much like the blah-sys versus blah crates).

I think that you can delete files from safe code, but safe as it won't crash or deadlock (but may panic or trigger bugs on unsafe code).

It'd be good to track capabilities needed by libraries, so similarly to unsafe code, risky portions needing careful review are constrained and highlighted in some way.

Re: Rewriting Rust

#188

Earlier quoted context omitted.

You are comparing a bicycle and a car; while you might only need a bicycle for your daily life, they are not directly comparable. BSD, Mac OS and Linux share the same interface that approximates POSIX---so it only supports a single platform with different variants. Its CLI is not well-designed, it's just a fixed unconditional terminal sequence that even doesn't look at $TERM and its options have no long counterpart (…

There's no standard way of doing file watching across BSDs, Mac OS and Linux. > it's just a fixed unconditional terminal sequence Are you referring to the clear feature? Yes, it's fixed. It's also pretty standard in that regard. It's optional so if it breaks (probably on xterm because it's weird but that's about it) you don't have to use it and can just issue a clear command manually as part of whatever you're runnin…

> There's no standard way of doing file watching across BSDs, Mac OS and Linux.

You are correct, but that's about the only divergence matters in this context. As I've noted elsewhere, you can't even safely use `char*` for file names in Windows; it should be `wchar_t*` in order to avoid any encoding problem.

> Are you referring to the clear feature? Yes, it's fixed. It's also pretty standard in that regard.

At the very least it should have checked for TTY in advance. I'm not even interested in terminfo (which should go die).

> spamming colours everywhere is eye candy not a feature

Agreed that "spamming" is a real problem, provided that you don't treat any amount of color as spamming.

> Which is unnecessary and entirely cargo specific. Meanwhile you can achieve the same effect with entr by just chaining it with an appropriate jq invocation. entr is more flexible by not having this feature.

Cargo-watch was strictly designed for Cargo users, which would obviously want to watch some Cargo workspace. Entr just happens to be not designed for this use case. And jq is much larger than entr, so you should instead consider the size of entr + jq by that logic.

> Not really anywhere near as many lines as you seem to think.

Yeah, my estimate is about 300 lines of code with a carefully chosen set of interface. But you have to ensure that it is indeed correct yourself, and JSON is already known for its sloppily worded standard and varying implementation [1]. That's what is actually required.

[1] https://seriot.ch/projects/parsing_json.html

> Yes, I think trying to golf the problem is probably not appropriate. But 4M LoC is fucking ridiculous by any metric. 1M would still be ridiculous.

And that 4M LoC is fucking ridiculous because it includes all `#[cfg]`-ignored lines in various crates including most of 2.2M LoC in the `windows` crate. That figure is just fucking incorrect and not relevant!

> 100k would also be ridiculous 50k is still pretty ridiculous.

And for this part, you would be correct if I didn't say the "faithful" reproduction. I'm totally sure that some thousand lines of Rust code should be enough to deliver a functionally identical program, but that's short of the faithful reproduction. This faithfulness issue actually occurs in many comparisons between Rust and C/C++; even the simple "Hello, world!" program does a different thing in Rust and in C because Rust panics when it couldn't write the whole text for example. 50K is just a safety margin for such subtle differences. (I can for example imagine some Unicode stuffs around...)

Re: Rewriting Rust

#189

Earlier quoted context omitted.

Author here. Thanks for the in depth response. I appreciate hearing an insider's perspective. > I always find it amusing to see, simultaneously, people complaining that the language isn't moving fast enough and other people complaining that the language is moving too fast. I think people complain that rust is a big language, and they don't want it to be bigger. But keeping the current half-baked async implementation…

> Why not? I believe you are proposing a language-based security (langsec), which seemed very promising at first but the current consensus is that it still has to be accompanied with other measures. One big reason is that virtually no practical language implementation is fully specified. As an example, let's say that we only have fixed-size integer variables and simple functions with no other control constructs. Inte…

> As an example, let's say that we only have fixed-size integer variables and simple functions with no other control constructs. Integers wrap around and division by zero yields zero, so no integer operation can trap. So it should be easy to check for the infinite recursion and declare that the program would never trap otherwise, right? No! A large enough number of nested but otherwise distinct function calls would eventually overflow the stack and cause a trap or anything else.

So? Panics or traps from stack overflows don't allow 3rd party code to write to arbitrary files on my filesystem. Nor does integer overflow.

Maybe there's some clever layered attack which could pull off something like that. But, fine! Right now the state is "anyone in any crate can trivially do anything to my computer". Limiting the granted permission to only allowing panics, infinite loops, integer overflows and stack overflows sounds like a big win to me!

If people do figure out ways to turn a stack overflow in safe rust into RCE, well, that was already a soundness hole in the language. Lets fix it.

Re: Rewriting Rust

#190

> The rust RFC process is a graveyard of good ideas. I actually have quite an opposite view: I think the Rust core team is 100% correct to make it very hard to add new "features" to the PL, in order to prevent the "language surface" from being bloated, inconsistent and unpredictable. I've seen this happen before: I started out as a Swift fan, even though I have been working with Objective-C++ for years, considered it…

Author here. I hear what you're saying. But there's lots of times while using rust where the language supports feature X and feature Y, but the features can't be used together. For example, you can write functions which return an impl Trait. And structs can contain arbitrary fields. But you can't write a struct which contains a value returned via impl Trait - because you can't name the type. Or, I can write if a && b…

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 be designed in such a way that the language remains internally consistent and works in all edge cases.

> Pin didn't take much work to implement in the standard library. But its not a "lean" feature. It takes a massive cognitive burden to use - to say nothing of how complex code that uses it becomes. I'd rather clean, simple, easy to read rust code and a complex borrow checker than a simple compiler and a horrible language.

Your commentary on Pin in this post is even more sophomoric than the rest of it and mostly either wrong or off the point. I find this quite frustrating, especially since I wrote detailed posts explaining Pin and its development just a few months ago.

https://without.boats/blog/pin/ https://without.boats/blog/pinned-places/

Post reply on HN