On Mon, Sep 30, 2013 at 8:31 AM, Oren Ben-Kiki <[email protected]> wrote:
> Huh, this is _exactly_ my use case. I have data structures which I grow > but never shrink, and I never move anything out of them. This idiom isn't > that uncommon when writing in functional style... > > I incrementally build a complex structure that allows quick access to the > same pieces using different criteria (e.g., access a piece by a unique id, > or look it up by a path, or via a direct pointer held by a related piece, > etc.). All accesses are of (possibly mutable) borrowed pointers that live > as long as the whole thing exist. Then when done I can discard the whole > thing. > Just a thought, but when you write "incrementally build a complex structure ... discard the whole thing", I think "arena allocation". That /might/ solve your borrowed pointer woes by letting you pervasively use borrowed pointers which all live at-most-as-long-as the arena (and hence the structure) itself. The borrow checker in my head is not advanced enough to let me really think it through though. And I don't think the compiler will let you send anything if there are borrowed pointers involved. There's an `arena` module[1] in libextra, but I've never tried it, and it uses `@` pointers internally which also precludes sending. (I wonder if there's any way to safely encode the idea that if all pointers are internal to the arena (there's nothing pointing in or out), then sending an ~arena should be safe, because its location in memory doesn't change. Presumably you would also need to move-send a pointer to the beginning of the structure inside of the arena alongside it. Maybe borrowed pointers are not the best fit here, or maybe they are, I dunno.) [1]: http://static.rust-lang.org/doc/master/extra/arena/struct.Arena.html > > Sometimes I have a less-complex structure to which I attach a related > "view" structure. The view holds borrowed pointers to pieces of the > original immutable structure, allowing efficient access in new and > interesting ways. When done I can then discard the view and keep the > original. > > So basically, I want something that gives me the freedoms granted to > &'static, but only for as long as the "main" structure provably exists. > Something like &'shadow :-) > > I found Rust doesn't like these idioms at all. I some cases, where I was > too tired, performance wasn't an issue, and there was no need to send the > whole thing between tasks, I just used @ pointers. Otherwise, I used RcMut, > though this incurs boilerplate access code and hurts performance for no > "real" reason. In critical cases I may end up using unsafe pointers... > > Using a macro - hmm. Interesting and if possible, would be a great > solution. I'm not certain what such a macro would expand to, though. It > would need to be something that would express the concept of "I live only > as long as my container structure" _somehow_, and I thought we established > that can't be done... > > Thanks, > > Oren. > > On Mon, Sep 30, 2013 at 4:26 AM, Steven Blenkinsop <[email protected]>wrote: > >> Yeah, I was trying to come up with a design a while ago to allow >> intrastructural borrowed pointers, and basically the effect this had was >> that you could never move anything out of the datastructure since that >> would leave dangling pointers. Which means you could grow the structure but >> never shrink it, which is sort of not good. >> >> Now my thought is about whether it would be possible to make a macro >> which allows you to define a safely encapsulated smart node which ensures >> that any intrastructural references meet certain invariants about where >> they point within the structure, but I haven't developed the idea enough to >> say whether you could make something truly general this way. >> >> >> On Sun, Sep 29, 2013 at 7:28 PM, Steven Fackler >> <[email protected]>wrote: >> >>> Foo can't really be used safely. Say that we have >>> >>> struct Bar { >>> baz: BazPartOfBar >>> } >>> >>> struct Foo { >>> bar: Bar, >>> baz: &'magic BazPartOfBar >>> } >>> >>> And let's say we add a `self` syntax to allow field initializers to >>> refer to other fields: >>> >>> let foo = Foo { >>> bar: Bar { >>> baz: BazPartOfBar >>> }, >>> baz: &self.bar.baz >>> }; >>> >>> We can't really do much with Foo. If we move it, foo.baz is no longer a >>> valid reference, so that can't happen. We could modify foo.bar in this >>> case, but not if Bar were defined as >>> >>> struct Bar { >>> baz: ~BazPartOfBar >>> } >>> >>> since foo.baz would point to deallocated memory if we replace self.bar >>> or self.bar.baz. >>> >>> Steven Fackler >>> >>> >>> On Sun, Sep 29, 2013 at 3:15 PM, Tim Kuehn <[email protected]> wrote: >>> >>>> Could you use struct methods for "quick access"? Or is there a reason >>>> this wouldn't fit your use case? Sorry, I haven't followed the whole thread >>>> closely. >>>> >>>> struct Owner { >>>> owned: ~[int], >>>> } >>>> >>>> impl Owner { >>>> fn quick_access<'a>(&'a mut self) -> &'a mut int { >>>> &mut self.owned[0] >>>> } >>>> } >>>> >>> > _______________________________________________ > Rust-dev mailing list > [email protected] > https://mail.mozilla.org/listinfo/rust-dev > > -- Your ship was destroyed in a monadic eruption.
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
