Live data from Hacker News

Rewriting Rust

josephg.com

301–310 of 410 posts

Re: Rewriting Rust

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

The fact is that dependency jungle is the prevalent way to get shit done these days. The best the runtime can do is embrace it, make it as performant and safe as possible and try to support minimum-dependency projects by having a broad std library. Also I am no expert, but I think file-watchers are definitely not simple at all, especially if they are multi-platform.

If you lose track of your dependencies you are just asking for supply chain attacks.

And since xz we know resourceful and patient attackers are reality and not just "it might happen".

Sorry but sprawling transitive micro-dependencies are not sustainable. It's convenient and many modern projects right now utilize it but they require a high-trust environment and we don't have that anymore, unfortunately.

Re: Rewriting Rust

#302
post #234

Earlier quoted context omitted.

Those companies can just ban using new rust dependencies, if they want to. Writing with minimal dependencies is just as easy in rust as it is in c++

You can't "just ban" new dependencies in an ecosystem where they are so pervasive otherwise the ban becomes a roadblock to progress in no time. Sorry I have a problem with "just" word in tech.

No one is forcing you to use a dependency. Write the code yourself just like you would in another language. Or vendor the dependency and re-write/delete/whatever the code you don't like.

Re: Rewriting Rust

#303

Earlier quoted context omitted.

No, Linus Torvalds doesn't work on the Rust compiler, but it is up to people like Linus to support or shoot down a particular PL for a particular use case. And here we arrive at the heart of our discussion: I am personally much more interested in being able to use Rust for Linux kernel development at the cost of any programming convenience, while you are more interested in being able to use cutting-edge PL features.…

> I am personally much more interested in being able to use Rust for Linux kernel development at the cost of any programming convenience, while you are more interested in being able to use cutting-edge PL features. Some of the "cutting-edge PL features" I want are things like function effects - which would allow you to (at compile time) mark that a function cannot panic. This is something the linux kernel has been as…

> Some of the "cutting-edge PL features" I want are things like function effects

That's probably the least convincing of your examples. My understanding is that effects systems can get complicated fast, and there's no consensus yet on what a good general purpose implementation should look like, never mind a specific implementation for Rust.

Re: Rewriting Rust

#304

Earlier quoted context omitted.

> But keeping the current half-baked async implementation doesn't make the language smaller or simpler. It just makes the language worse. I can't disagree more. In fact, I think that the current state of async Rust is the best implementation of async in any language. To get Pin stuff out of the way: it is indeed more complicated than it could be (because reverse compatibility etc), but when was the last time you need…

> In fact, I think that the current state of async Rust is the best implementation of async in any language. Hahahaha hard disagree. Last year I implemented the braid protocol (a custom streaming protocol using HTTP) in javascript in less than an hour and about 30 lines of code. Then I spent 2 weeks trying to do the same thing in rust - writing hundreds of lines of code in the process and I couldn't get it to work. E…

> Then I spent 2 weeks trying to do the same thing in rust… Eventually I gave up.

In my experience, that kind of difference boils down to a combination of three things.

- Comparing apples and oranges. For example, Box makes pinning trivial (you can just move in and out of Pin no problem), but oftentimes people new to Rust try to prematurely optimise and eliminate a single pointer lookup. If that's the case, were you really writing the same thing in JS and in Rust?

- An extension to the previous point, the behaviour is usually different. What would happen in your JS implementation if two streams were awaited concurrently, one received a message, and the other had to be cancelled? What if one threw an exception? In Rust, you're forced to think about those things from the start. In JS, you're coding the happy path.

- Trying to reproduce the exact same architecture even if it's awkward of inefficient. For example, it's really really easy to use a stream wrapper [1] to produce a stream from a channel, but then the architecture gets very different.

> Again I needed to produce an async stream, and thats impossible using async fn

I strongly recommend a channel instead. There's also async_stream [2], but channels are simpler and cleaner.

Over two years of writing embedded, web, and CLI rust I didn't have to write a raw future once.

[1] https://docs.rs/tokio-stream/latest/tokio_stream/wrappers/in...

[2] https://docs.rs/async-stream/latest/async_stream/

Re: Rewriting Rust

#305

Earlier quoted context omitted.

> it’s likely harder to guarantee that malicious code doesn’t just call syscalls directly via assembly. Hence the requirement to also limit / ban `unsafe` in untrusted code. I mean, if you can poke raw memory, the game is up. But most utility crates don't need unsafe code. > Package scope is typically too coarse - a package might export multiple different pieces of related functionality and you’d want to be able to u…

> Hence the requirement to also limit / ban `unsafe` in untrusted code I think you’d be surprised by how much code has a transitive unsafe somewhere in the call chain. For example, RefCell and Mutex would need unsafe and I think you’d agree those are “safe constructs” that you would want available to “utility” code that should haven’t filesystem access. So now you have to go and reenable constructs that use unsafe th…

> I think you’d be surprised by how much code has a transitive unsafe somewhere in the call chain. For example, RefCell and Mutex would need unsafe and I think you’d agree those are “safe constructs” that you would want available to “utility” code that should haven’t filesystem access. So now you have to go and reenable constructs that use unsafe that should be allowed anyway. It’s a massively difficult undertaking.

RefCell and Mutex have safe wrappers. If you stick to the safe APIs of those types, it should be impossible to read / write to arbitrary memory.

I think we just don't want untrusted code itself using unsafe. We could easily allow a way to whitelist trusted crates, even when they appear deep in the call tree. This would also be useful for things like tokio, and maybe pin_project and others.

Re: Rewriting Rust

#306

Earlier quoted context omitted.

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…

> 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.

?? Then why did the language team put it on the 2024 roadmap? Am I looking at something different? (Specifically on under the 'Express yourself more easily' (1) goal, which links to the RFC issue (2)).

It certainly looks like the implementation is both complete and unblocked, and actively used.

It looks more like the issue is (despite being put on the roadmap and broadly approved as a feature), being argued about because of the alternative proposal for 'is' syntax.

ie. If you want to generalize then yes, there are features which are difficult to implement (yeah, I'll just make a Move trait... yeah... No. It's not that easy).

BUT.

That's not a problem.

A lot of clever folk can work through issues like that and find solutions for that kind of problem.

The real problem is that RCFs like this end up in the nebulous 'maybe maybe' bin, where they're implemented, have people who want them, have people who use them, have, broadly the approval of the lang team (It's on the roadmap).

...but then, they sit there.

For months. Or years. While people argue about it.

It's kind of shit.

If you're not going to do it, make the call, close the RFC. Say "we're not doing this". Bin the code.

Or... merge it into stable.

Someone has to make the call on stuff like this, and it's not happening.

This seems to happen to a fair few RFCs to a greater or less extent, but this one is particularly egregious in my opinion.

[1] - https://lang-team.rust-lang.org/roadmaps/roadmap-2024.html#t... [2] - https://github.com/rust-lang/rust/issues/53667

Re: Rewriting Rust

#307

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.

Because for a lot of companies, especially ones in industries that Rust is supposedly hoping to displace C and C++ in, dependencies are a much larger concern than memory safety. They slow down velocity way more than running massive amounts of static and dynamic analysis tools to detect memory issues does in C. Every dependency is going to need explicit approval. And frankly, most crates would never receive that appro…

I disagree i think avoiding dependencies is partly how we have these codebases like chromium's where you can't easily separate the functionally you want and deal with them as a library. That to me isn't minimalism.

Re: Rewriting Rust

#308

Earlier quoted context omitted.

No, Linus Torvalds doesn't work on the Rust compiler, but it is up to people like Linus to support or shoot down a particular PL for a particular use case. And here we arrive at the heart of our discussion: I am personally much more interested in being able to use Rust for Linux kernel development at the cost of any programming convenience, while you are more interested in being able to use cutting-edge PL features.…

> I am personally much more interested in being able to use Rust for Linux kernel development at the cost of any programming convenience, while you are more interested in being able to use cutting-edge PL features. Some of the "cutting-edge PL features" I want are things like function effects - which would allow you to (at compile time) mark that a function cannot panic. This is something the linux kernel has been as…

> I want are things like function effects

And it's not a cut and dry issue to add. Function effects would add a lot of cognitive load to the developer along with more implicit bounds which increases accidental API break changes. You talk about the compiler implicitly adding the bounds to functions, but what happens when I now add a line in my function that allocates when before it didn't? I just broke my API unless I was also defensively testing all implicit bounds. And if I was testing all implicit bounds, can the language no longer add new bounds? Reversing that and requiring the callee to defensively declare all bounds is a borderline non-starter because it'd such a huge burden to write any function or refactor anything.

Re: Rewriting Rust

#309
Rust 2.0 wishlist:

  * Supports Unions (TypeScript, Flow, Scala3, Hare)

  * Supports GADTs

  * Capable of targeting both preemptive userland concurrency (go, erlang, concurrent Haskell, concurrent OCaml) and cooperative (tinygo, nodejs, async-python, async-rust) without code changes

  * Easily build without libc (CGO_ENABLED=0)

  * No Backwards compatibility promise - This eliminates geriatrics

  * Cleaner syntax, closer to Go, F#, or Python

  * Graph-based Borrow Checker

  * Add `try-finally` or `defer` support, `Drop` is too limiting, Async drop could help.

  * Fix Remaining MIR Move Optimizations and Stack Efficiency

  * Culture for explicit allocator passing like Zig

  * `.unwrap()` is removed

Re: Rewriting Rust

#310
post #291

Earlier quoted context omitted.

> 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 e…

I think what you’re saying is that, in fully safe code, control flow can’t have any surprises other than panics and/or signals/exceptions. I think this is true. And I would love to use a language that limited side effects like this at the language level — even ignoring security, it makes reasoning about code easier. The issue of build-time security is somewhat separate, and it actually seems easier to tackle strongly…

> And I would love to use a language that limited side effects like this at the language level — even ignoring security, it makes reasoning about code easier.

This is one of the value propositions of Roc

Post reply on HN