8 ms·
Rust seems to be a poor match for the way the author wishes to solve this particular problem. That doesn't mean that their design is wrong, or that Rust is wron
by ekidd 10y ago
Rust seems to be a poor match for the way the author wishes to solve this particular problem. That doesn't mean that their design is wrong, or that Rust is wrong, but it does mean that mixing the two would require rethinking parts of the design.
> So a trait can define abstract functions, but can't access any underlying fields.
In Rust, a trait is a purely abstract interface to a type. It explains how you can use that type, but it knows nothing about the implementation.
I'm not quite sure what the design goal was with the Widget type, but the closest solution is to replace the member variable in the abstract type with some kind of accessor (and to replace the magic negative font sizes with an Option):
trait Widget {
// ADDED: Access whatever underlying font
// size you have stored in this type.
fn desired_font_size(&self) -> Option<i32>;
// ADDED: Access the theme of this object.
fn theme(&self) -> &Theme;
// High-level interface to get font size.
// (With a default implementation in terms of
// other functions on this trait.)
fn font_size(&self) -> i32 {
if let Some(sz) = self.desired_font_size() {
sz
} else {
self.theme().get_standard_font_size()
}
}
}
I'm not sure this is how I'd personally design this, but it should compile.
> What IS the idiomatic Rust way to do a cyclical directed graph?
Unfortunately, the correct idiomatic way is that you try very hard to avoid doing so. Rust is all about clear ownership, and it doesn't like circular references.
The usual solution is to put the cyclic graph code into a library, and to use pointers and about 20 lines of unsafe code. (EDIT: See below for a better solution.) It's not much different from the C++ solution.
The Servo team really wants GCed, safe pointer support in Rust, and design work is well underway. But it's going to take a while to stabilize.
GUI libraries are an interesting special case: They involve huge class hierarchies, lots of implementation inheritance, circular references, and tricky ownership. Most older OO languages were optimized for this case. Newer languages tend to favor flatter type hierarchies and far less implementation inheritance. Which means that traditional object-oriented GUI designs may be awkward.
- pcwalton 10y ago> The usual solution is to put the cyclic graph code into a library, and to use pointers and about 20 lines of unsafe code. It's not much different from the C++ solution. Well, petgraph uses vectors and indices to avoid unsafe code, and it's the most popular graph library on crates.io. Really, the answer here is "use a graph crate on crates.io". If you don't know which one to use, the best answer is probably petgraph. > The Servo team really wants GCed, safe pointer support in Rust, and design work is well underway. But it's going to take a while to stabilize. We aren't going to use GC'd pointers for any of the trees except the DOM. GC is way overkill for this use case. The reason why we want GC support is not to make tree data structures: it's for integration with JavaScript.
- ekidd 10y ago> Well, petgraph uses vectors and indices to avoid unsafe code, and it's the most popular graph library on crates.io. Nice! I hadn't seen that yet, but it looks really interesting: http://bluss.github.io/petgraph/doc/petgraph/graph/struct.Graph.html http://bluss.github.io/petgraph/doc/petgraph/graph/struct.Gr...
- chias 10y agoNot sure if it's just me, but the ampersands at that link are displaying super weirdly on my end: https://i.imgur.com/Bg8rejM.png https://i.imgur.com/Bg8rejM.png
- MaulingMonkey 10y agoHappens here too (on Chrome 52-53.) I guess it isn't some locally corrupted font, eh? Edit: Doesn't occur on IE 11, so it seems Chrome specific.
- iopq 10y agoIt's a locally corrupted copy of Source Code Pro. When I installed a new version it was resolved.
- iopq 10y agoIt means you have an older version of source code pro, the Rust website uses your local font instead of an invalid font name like some websites do.
- TillE 10y agoA lot of problems in Rust seem to involve replacing (smart) pointers with handles. Sometimes you really do want to do that, but it's bad if it's a necessary kludge. Like someone else said recently, it's a problem if you can't reasonably teach a basic computer science course in Rust.
- 10y ago
- partiallattice 10y ago> > What IS the idiomatic Rust way to do a cyclical directed graph? > Unfortunately, the correct idiomatic way is that you try very hard to avoid doing so. Rust is all about clear ownership, and it doesn't like circular references. > The usual solution is to put the cyclic graph code into a library, and to use pointers and about 20 lines of unsafe code. The point about C++ is important. Cyclic graphs are hard in any non-GC'ed language because it breaks the ownership story.
- Animats 10y agoThe usual solution is to put the cyclic graph code into a library, and to use pointers and about 20 lines of unsafe code. That indicates a fundamental design flaw in the language.
- oldmanjay 10y agoWhich flaw does it indicate? It seems like there is nothing about the solution that contravenes the design goals of the language.
- stouset 10y agoIn what conceivable way? Safe Rust allows one to do an incredible amount of things whole providing strong guarantees against the sorts of problems that plague lower level languages. Since this isn't suitable for absolutely everything, we have unsafe Rust to fill in the gaps in the small areas it's needed. Unsafe Rust isn't "bad", it just doesn't provide the same guarantees as safe Rust. And if something goes wrong, you can at least narrow down your search to unsafe areas of the code. This isn't the sign of fundamental language design flaws. It's the sign of a phenomenally well-designed language, where the downsides of seldom-needed yet powerful features are limited to only those areas where they're used.
- Animats 10y agoAnd if something goes wrong, you can at least narrow down your search to unsafe areas of the code. No. That's only true if the unsafe code presents a completely safe interface to its callers. If the safe code opens a hole in Rust's protection system, which is very easy to do, you can now have C-type no-idea-where-it-is bugs.
- hinkley 10y agoGiven that Rust was designed by a group known for writing web browsers, how does that work out in practice, given that the DOM is a deep bidirectional graph? UIs work routinely by the organizational principle the author is attempting. Nested groupings of related functions that often interact in small groups. And the thing is, a pointer to your parent doesn't semantically mean an ownership relationship anyway. It s in fact an extremely clear declaration of the ownership contract because while the owner can own many things, an object in this graph can have but one owner. Now, I'm not sure how you would encode this into a compiler, so the discussion may have to end there as being impractical to implement.
- mastax 10y ago> Given that Rust was designed by a group known for writing web browsers, how does that work out in practice, given that the DOM is a deep bidirectional graph? I believe that the JS engine has ownership over the DOM, and pointers into the DOM are GC'd by the JS engine. This is part of the motivation for adding hooks for GC's in Rust. These posts [1][2] discusses this, although I think there is a more recent one. Edit: more recent one here [4]. > Now, I'm not sure how you would encode this into a compiler, so the discussion may have to end there as being impractical to implement. This seems like a good use case for a Weak<> pointer [3]. [1]: http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-specing-the-problem/ http://blog.pnkfx.org/blog/2015/11/10/gc-and-rust-part-1-spe... [2]: http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roots-of-the-problem/ http://blog.pnkfx.org/blog/2016/01/01/gc-and-rust-part-2-roo... [3]: https://doc.rust-lang.org/std/rc/struct.Weak.html https://doc.rust-lang.org/std/rc/struct.Weak.html [4]: http://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-design/ http://manishearth.github.io/blog/2016/08/18/gc-support-in-r...
- hinkley 10y agoMeh. Using Weak Types for this would be circumventing the ownership system to say what you mean and maintain it by hand. Indeed I believe the Rust Language is essentially stating that you can't manage these things by hand but a computer can. The road to hell is paved with good intentions, and I know myself and my cohort well enough that I appreciate the Rust sentiment on this subject. It was the main feature that drew my attention. I'm wondering if this is a concrete concept that could be build into the ownership system. Logically speaking, this back pointer only exists to allow objects that are part of a Composition to reason about their environment, or be reasoned upon by an outside observer. Maybe some of this information already exists in the language internals and you just need a function that can expose the owner of record of the object... There can only be one, right?
- loup-vaillant 10y ago> GUI libraries are an interesting special case: They involve huge class hierarchies, lots of implementation inheritance, circular references, and tricky ownership. I doubt they have to be. There are other ways to do GUI, see for instance how Light Table uses a database-like Entity Component System. https://www.youtube.com/watch?v=V1Eu9vZaDYw https://www.youtube.com/watch?v=V1Eu9vZaDYw
- jerf 10y agoI am fairly confident "someone" could write a composition-based UI. I know of no fundamental reason why that would be impossible, or even any more difficult than doing one with inheritance. However, that does not solve the problem that all the mature existing UI widget toolkits are based on inheritance, and that causes a serious "impedance mismatch" with languages that don't have inheritance. As I expect more languages to start privileging composition over inheritance, I also therefore expect this problem to continue to become more acute until "someone" finally solves it. However, GUI toolkits are huge and "someone" is likely to be a substantially-sized organization. The problem is going to have to become very painful before it is solved well.
- loup-vaillant 10y agoGranted, current GUI toolkits are huge. On the other hand, I have worked with Qt, and this convinced me most of the complexity there was a blend of avoidable bloat and a long tail of features few people ever use (a bit like offices suites). I'm pretty sure properly written GUI toolkits can be much smaller. As in, satisfying 90% of our needs in a couple thousand lines of code. (The remaining 10% might require heaps and heaps of code, but I'm sure it doesn't have to affect the core.) It's only an intuition at this point (I have yet to implement my own GUI toolkit). But I have reasons to believe this intuition is right: http://www.vpri.org/pdf/tr2012001_steps.pdf http://www.vpri.org/pdf/tr2012001_steps.pdf
- jerf 10y agoWell, I guess I ought to put this in here, rather than rewrite it :) : https://news.ycombinator.com/item?id=12410471 https://news.ycombinator.com/item?id=12410471 The "long tail" is like the long tail of Excel or Word; yeah, everybody only uses 5% of it but everybody uses a different 5%.
- mcguire 10y ago"The Servo team really wants GCed, safe pointer support in Rust, and design work is well underway. But it's going to take a while to stabilize." Any details on this? GCs and finalizers don't really work well together, which is why I gave up on my cycle detector implementation.
- Veedrac 10y agoThey want objects that can be shared with Javascript.
- Manishearth 10y agohttp://manishearth.github.io/blog/2016/08/18/gc-support-in-rust-api-design/ http://manishearth.github.io/blog/2016/08/18/gc-support-in-r... The reason Servo in particular would like GC hooks is because JavaScript is GCd and we want to be able to pass around Spidermonkey-managed pointers safely. We have a framework in place that does this, but proper compiler support would be nice. Servo doesn't need to worry about finalizers because our DOM structs never have nontrivial destructors (explicit Drop impls). The blog post throws around some ideas for dealing with the finalized problem though.
- dilann 10y ago> GUI libraries are an interesting special case > traditional object-oriented GUI designs may be awkward For example, Qt has moved that tricky part into a specialized language. I think that it's the way to go. So it's okay if a low-level language is not designed to do that ancient stuff with pointers to widgets.
- zanny 10y agoAlso note that there are actually several QML for Rust implementations out there, and while I've only done weekend toying at least qml-rust works well.
- jwatte 10y agoThe solution is to implement guis with composition and delegation rather than inheritance. It requires some ree-thinking and elbow grease, rather than just copying stale designs from 30 years ago, which may be why so many people avoid it, though.