Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It was my example, so I try to explain it a little more:

There are quite a lot of cases where you would like to have things like this, but the example that's probably most straightfoward to understand is GUI systems:

E.g. you have a generic `Widget`, the `IWidget`. Then you have some base-class `Container` which contains multiple other widgets (`list<IWidget>`). This might contain a reference to a `TextBox` (which is an implementation of `IWidget`) and another widget (or controller or whatever) might contain also a reference to the same thing. Both might need to be mutable. And in exact that moment you have code like the described one.

That's no borderline usecase, it's a thing that you in all popular HMI frameworks (and in C, C++, C#, Java, ...). Maybe you can solve the issues in a completly different fashion, with resorting to only immutable objects (like some approaches for ClojureScript). But these are then no longer zero-cost abstractions versus current technology and they are not that easy to pick up for most mainstream programmers (which expect C++ alternative and not a Haskell alternative).

Besides that people are already asking for bindings to things like QT - and that will require similar constructs.



I'm not aware of any production quality UI toolkits in Rust, but using traits and reference counting, Rust certainly supports this use case.

In fact, it supports it more flexibly since different widgets don't have to share the same methods and data at all... well, unless you want them to. And you can have your widgets implement more than one trait without having to combine them all into one giant class definition.


As soon as it supports storing trait objects in smart pointers and casting them. That's afaik still not the case.


You can as long as they are immutable objects. Again, you can't alias mutable references, even if they are of the exact same type.

Maybe you should read this: http://doc.rust-lang.org/guide.html#traits


I believe your parent is referring to storing trait objects in something like Arc<T>, which is not supported: currently, Arc<T> requires T to be sized.


Similar, but not exactly:

As I said, the objective is to have access to one object (in it's native form or in an interface (supertype) form from different locations. For that you can can use Rc. To be able to mutate it you can add RefMut and end up with Rc<RefMut<T>>, e.g. Rc<RefMut<IWidget>>. And now how do I get an Rc<RefMut<TextBox>> or any other type like &mut TextBox back from that?


I think you could store objects of type Box<DerefMut<IWidget>> and then write a generic wrapper struct which holds an Rc<RefCell<T>> and derefs into the trait object.

Admittedly this is ugly, and unnecessarily slow. For a more general solution, I think the language would allow implementing some kind of RcTransformed type which, given 'T, U : Unsized?, Transform : Fn(&T) -> &U' (or possibly a more general type, but I think that would require HKT?), takes an Rc<T>, calls the transform, and stores both the reference and the transformed reference, allowing direct access to the latter. This would require an unsafe implementation, but would be safe to use.

Alternatively, there may be some existing functionality like that that I just haven't heard of...




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: