let (reader, vec) = await { io.read_until(reader, b'\n', Vec::new() }?;
if vec.len() == 0 {
return Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"));
}
let string = String::from_utf8(vec)?;2,029 karma · joined July 31, 2014
let (reader, vec) = await { io.read_until(reader, b'\n', Vec::new() }?;
if vec.len() == 0 {
return Err(Error::new(ErrorKind::BrokenPipe, "broken pipe"));
}
let string = String::from_utf8(vec)?;Users of safe Rust do not need to worry about whether the composition of two safe interfaces that use unsafe internally is safe unless one of those interfaces is incorrect. Your comment would suggest that users need to think about the untyped invariants of each library they use, but this is not correct, libraries are not allowed to rely on untyped invariants for the correctness of their safe APIs.
If it is a violation of Rust's safety guarantees, then at least one of those libraries has a bug, it is exposes a safe abstraction which is not actually safe. One could not argue that the safe Rust program is wrong; the library exposing an unsafe interface as safe is unarguably wrong.
If the library just behaves incorrectly in a manner disconnected from the type system because some global state was changed in a way it doesn't expect ("the hardware" in this case), then that's a normal bug & it is not connected to unsafe code at all.
This comment suggests you don't have much domain knowledge about how `unsafe` in Rust works, so I'm surprised you speak with such confidence. Your comment is flatly wrong: users using only safe code are not responsibility for guaranteeing the composed safety of the components they use (whether or not they are implemented with unsafe code).
Interfaces marked safe must uphold Rust's safety guarantees, or they are incorrect. They are just wrong if they have additional untyped invariants that need to be maintained to guarantee their safety; interfaces like this must be marked `unsafe`.
Because they cannot depend on untyped invariants, any correct implementation with a safe interface can be composed with any other. This ability to create safe abstractions over unsafe code which extend the reasoning ability of the type system is a fundamental value proposition of Rust.
- We would love to have a REPL but there are nontrivial technical challenges, and it has not been a major requested feature by our users.
- I have never heard the complaint about the size of packages before now; I have no idea how we compare to other languages in this regard.
I've witnessed some of the conversations you're talking about (I think I engaged with you about REPLs in the past), and I think the "true-believer syndrome" has more to do with how you interpret the answers you receive than with the behavior of anyone else.
But this is also a very different objection from your initial objection, which was just a statement of fact about type systems for turing complete languages.
And of course there is a huge amount of abstraction to build this up. It's just all hidden in the language runtime, so people can say with a straight face that there is "no abstraction and no cruft."
Of course, schedulers are just complicated. Most of the time you don't think about how complicated your scheduler is, because its either an OS primitive in the kernel or a language primitive in your language's runtime. But since tokio is a library - and modular - it gets criticism for being complex that in my opinion is unfair.
[] To be more concrete: a future is essentially a state machine representing the stack state at any yield point; it can't (currently) contain lightweight references into itself because they'd be invalidated when the future is move around. This means using borrowing in futures programs is often infeasible today. Solutions are in the works.
http://www.aidsmap.com/No-one-with-an-undetectable-viral-loa...
Frequent testing and early intervention are very effective to achieving an undetectable viral load. The adoption of these as public health policy, as well as making available of prophylactic measures for at risk populations, has been effective at combating the spread of HIV - e.g. in San Francisco, where infection rate has been declining significantly over the last 5 or so years.
But this isn't the official compiler, this is someone's personal project?
You must mean that you stored your `CounterWidget` in a RefCell, which does have the semantics that if you mutate it while holding a mutable reference to it, it will crash. But your code sample didn't include a RefCell at all, so this is very unclear.
Yes, its true - Rust provides a hard guarantee against simultaneous mutable access to the same data. This is invaluable even in a non-concurrent context, both because of memory issues like iterator invalidation & higher level logic errors that result from silent mutation at a distance.
I can assume looking at your code that didClick() doesn't mutate this CounterWidget - or even access it. This means I know that if I rearrange the counter increment with the didClick callback, I know nothing is semantically different. I can introduce additional code to the function, knowing that the state is the same after didClick as before it. All of this information is very useful to me when I'm trying to maintain this codebase (not to mention useful to the optimizer).
If you want to be able to provide mutable access to the callback, just make it an `fn(&mut CounterWidget)`.
But by providing a set type, Rust is able to provide for users various set operations which Go requires you to write by hand. It becomes hard to argue that a set is simpler than a slice when you have to write your own methods dealing with union, disjunction, intersection, difference, subsets/supersets, etc every time.