Rust isn't an Exciting New Language any more. It's in the "work towards widespread adoption" phase. Slower feature development is natural and healthy, the stakes are high, mistaken design choices are much more harmful than low velocity at this point. I'm not excited about Rust because of cool features, I'm excited because it's a whole new CLASS of language (memory safe, no GC, production ready). Actually getting it i…
Rewriting Rust
231–240 of 410 posts
Re: Rewriting Rust
#232Earlier quoted context omitted.
https://github.com/eradman/entr is Language files blank comment code ------------------------------------------------------------------------------- C 4 154 163 880 Bourne Shell 2 74 28 536 C/C++ Header 4 21 66 70 Markdown 1 21 0 37 YAML 1 0 0 14 ------------------------------------------------------------------------------- SUM: 12 270 257 1537 ------------------------------------------------------------------------…
Note that entr doesn't recursively watch for file changes. It has a list of files it watches for changes, but this list isn't amended when new files are added. Fundamentally that's a fairly small subset of proper recursive file watching. In terms of just watching files a better project to compare against is https://github.com/inotify-tools/inotify-tools .
Rebuild project if a source file is modified or added to the src/ di‐
rectory:
$ while sleep 0.1; do ls src/*.rb | entr -d make; done
Though I shudder to think of the amount of code needed to rewrite that in a compiled language while sticking to the principle of not reinventing anything remotely wheel-shaped. (Btw the libinotify/src is like 2.3kloc, inotify cli <1.2kloc.)Re: Rewriting Rust
#233Earlier quoted context omitted.
https://github.com/eradman/entr is Language files blank comment code ------------------------------------------------------------------------------- C 4 154 163 880 Bourne Shell 2 74 28 536 C/C++ Header 4 21 66 70 Markdown 1 21 0 37 YAML 1 0 0 14 ------------------------------------------------------------------------------- SUM: 12 270 257 1537 ------------------------------------------------------------------------…
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 (…
Re: Rewriting Rust
#234Earlier quoted context omitted.
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…
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++
Sorry I have a problem with "just" word in tech.
Re: Rewriting Rust
#235I would gladly switch to a Rust fork without async. Even though this article is not about async per se, it’s clear that async makes most of the described problems worse.
Isn't that trivial? Just use Rust but reject any occurrence of `async` or `await` in your code or dependencies. Rust doesn't even force the use of async code for certain features in its standard library.
This applies to both suggestions ("fork" and "don't use it").
Re: Rewriting Rust
#236> Rust doesn't have syntax to mark a struct field as being in a borrowed state. > ast_nodes: Vec , Oh, that would be neat to replace the https://github.com/tommie/incrstruct I wrote for two-phase initialization. Unlike Ouroboros and self_cell, it uses traits so the self-references can be recreated after a move. Whether it's a good idea, I don't know, but the magic Ouroboros applies to my struct feels wrong. But I say…
The same thing in C++17:
if (auto x = something();
expr1(x)) {}
else if (expr2(x)) {}
It's really neat to have the variable scoped to the if/else-clause.Re: Rewriting Rust
#237Earlier quoted context omitted.
You do have good points as well and it depends heavily on how disciplined the std lib makers are. Go for example has a very clean and stable std lib. I posted this in some other thread: I am not a Rust expert but the thing with the standard libraries is that it only has peer dependencies with itself and they are all synced to the same version. Meaning if you only use the std lib you: 1) Will never include two differe…
For 1), Cargo already take care of that if you use the same major version. Bundling dependencies in the stdlib "solves" the problem by making new major versions impossible. This means that if a bundled dependency in the stdlib is even found to have some design issue that require breaking changes to fix then you're out of luck. As you said the stdlib could deprecate the old version and add a new one, but then you're j…
Most dependency management systems do that, but large projects often end up pulling multiple different major versions of (often very large) dependencies.
> 2) worse by forcing everyone to include the old deprecated dependency too!
Like I said I am no expert on Rust, but I assume that Rust can eliminate stdlib dead-code from the runtime? So unused deprecated features shouldn't be included on every build? Also deprecated features often are modified to use the new implementation under the hood which reduces code duplication problem.
> Bundling dependencies in the stdlib "solves" the problem by making new major versions impossible.
Yes, which is a feature. For example Go is very annoying about this not only on the stdlib. https://go.dev/doc/go1compat a lot of 3rd party libs follow this principle as well.
I bring Go a lot but I actually don't like the language that much, but it gets some pragmatic things right.
I am not saying everything should be in the stdlib, but I tend to think that the stdlib should be fairly big and tackle most common problems.
Re: Rewriting Rust
#238Earlier quoted context omitted.
This is the main reason we have banned Rust across my Org. Every third party library needs to be audited before being introduced as a vendored dependency which is not easy to do with the bloated dependency chains that Cargo promotes.
How do you solve this for other languages you use?
Re: Rewriting Rust
#239Earlier 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…
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 RFC was written: https://rust-lang.github.io/rfcs/2497-if-let-chains.html - which fixes my issues. But it still hasn't shipped.
Do I have too high expectations? Is 6 years too quick? Maybe, a decade is a reasonable amount of time to spend, to really talk through the options? Apparently 433 people contributed to Rust 1.81. Is that not enough people? Do we need more people, maybe? Would that help?
Yes, I do feel piqued by the glacial progress. I don't care about the || operator here - since I don't have any instinct for what that should do. And complex match expressions are already covered by match, anyway.
Rust doesn't do the obvious thing, in an obvious, common situation. If you ask me, this isn't the kind of problem that should take over 6 years to solve.
> 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.
If I'm totally off base, I'd appreciate more details and less personal insults.
I've certainly given Pin an honest go. I've used Pin. I've read the documentation, gotten confused and read everything again. I've struggled to write code using it, given up, then come back to it and ultimately overcame my struggles. I've boxed so many things. So many things.
The thing I've struggled with the most was writing a custom async stream wrapper around a value that changes over time. I used tokio's RwLock and broadcast channel to publish changes. My Future needed a self-referential type (because I need to hold a RwLockGuard across an async boundary). So I couldn't just write a simple, custom struct. But I also couldn't use an async function, because I needed to implement the stream trait.
As far as I can tell, the only way to make that code work was to glue async fn and Futures together in a weird frankenstruct. (Is this a common pattern? For all the essays about Pin and Future out there, I haven't heard anyone talk about this.) I got the idea from how tokio implements their own stream adaptor for broadcast streams[1]. And with that, I got this hairy piece of code working.
But who knows? I've written hundreds of lines of code on top of Pin. Not thousands. Maybe I still don't truly get it. I've read plenty of blog posts, with all sorts of ideas about Pin being about a place, or about a value, or a life philosophy. But - yes, I haven't yet, also read the 9000 words of essay you linked. Maybe if I do so I'll finally, finally be enlightened.
But I doubt it. I think Pin is hard. If it was simple, you wouldn't have written 9000 words talking about it. As you say:
> Unfortunately, [pin] has also been one of the least accessible and most misunderstood elements of async Rust.
Pin foists all its complexity onto the programmer. And for that reason, I think its a bad design. Maybe it was the best option at the time. But if we're still talking about it years later - if its still confusing people so long after its introduction - then its a bad part of the language.
I also suspect there are way simpler designs which could solve the problems that pin solves. Maybe I'm an idiot, and I'm not the guy who'll figure those designs out. But in that case, I'd really like to inspire smarter people than me to think about it. There's gotta be a simpler approach. It would be incredibly sad if people are still struggling with Pin long after I'm dead.
[1] https://github.com/tokio-rs/tokio/blob/master/tokio-stream/s...
Re: Rewriting Rust
#240I would gladly switch to a Rust fork without async. Even though this article is not about async per se, it’s clear that async makes most of the described problems worse.
Author here. I think async is a great feature to have - but I can't help but wonder if you're right. It might just be case of timing, but it seemed like once async was in the works, work on the rest of the language ceased. For awhile there all energy was poured into bikeshedding over how async would work. And I don't know if anyone is super happy with the result. Pin is a mess. Async functions still return anonymous…
The decision for `async` handed a lot of power to Amazon et al.