Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Project Verona FAQ (github.com/microsoft)
29 points by rayiner on Feb 10, 2020 | hide | past | favorite | 8 comments


What I find really interesting about Verona is the use of regions, which is related but somewhat different from Rust: https://github.com/microsoft/verona/blob/master/docs/explore...

> Verona uses regions, groups of objects, as its fundamental concept of ownership. Rather than specifying object ownership as a reference owns an object, we generalise this a little to a reference can own a region, where a region is a group of objects. Within a region, any object can refer to any other object in that region. There is no restriction on the topology. When the owning reference to a region goes away then the entire region is collected.

In Rust, objects referenced by owning pointers form a tree--there is a unique pointer to each object. In Verona, an owning pointer references a sub-graph of the heap that is disjoint except for the path through the owning pointer. The sub-graph can be reclaimed when the owning pointer goes out of scope. Within the sub-graph, there are no restrictions, so you can have cyclic structures like doubly-linked lists. In Rust, by contrast, having a doubly-linked list requires either raw pointers and unsafe, or some sort of reference-counted pointer.

You can use regions to statically enforce the property that other pointers into a region, for example from the stack, cannot outlive the owning pointer for the region (and thus the region itself). Allowing such temporary aliasing of objects potentially eliminates or at least reduces the need for a borrowing mechanism. In Rust, for example, you run into borrowing as soon as you try to iterate over a linked list. If you allow temporary aliasing (and ensure that the iterator pointer cannot outlive the region by restricting its scope to a context where the region is live) you don't need a borrowing concept.

Using regions this way addresses one of the vague dissatisfaction I have with Rust, which is you need to introduce borrowing just to iterate over a singly linked list, and you need raw pointers and unsafe, or a special mechanism that uses unsafe under the hood, to have doubly linked lists. On the other hand, this creates problems as well. For example, within a region, you can't delete an object when the pointer to it goes out of scope, because it may be referenced from another object. So while you can always safely reclaim a region when the owning pointer goes out of scope, you can produce unbounded memory use by creating objects within regions. (As far as I can tell, Verona doesn't attempt to address that issue, yet.)


Regions used in this way predate Rust's use of regions—they go back to the ML Kit if not earlier. There was a lot of excitement around regions when first introduced, because it was thought that they obviated the need for garbage collection. Unfortunately, it didn't work out that way, and one major reason why is the one you described: you can't free objects within a region without freeing the whole region itself. This is why Rust altered the regions concept to the lifetime concept it has today.

Note that the Rust system is flexible enough to encode regions. There are some crates for this in the ecosystem, for example bumpalo.


This seems to be the same as having everything in the subgraph be "owned" by the owning pointer. Which would be a special case of the Rusty "ownership forms a tree" model. The key is that because ownership within the subgraph is explicitly untracked, you can only really drop the whole subgraph at once. Supporting this idiomatically in Rust should become quite a bit easier once custom, non-global allocators (like in C++) are allowed, since these are often used for the same things anyway.


It's not quite supported in Rust, as far as I understand it. Say I have two local variables: 'ptr' and 'itr.' 'ptr' is an owning pointer to a region containing a cyclic graph. 'itr' is a pointer to a node in the graph. What is the type of 'itr' in Rust?


Assuming you're using a region crate like bumpalo, the type of itr is &'a T, where 'a is the lifetime of ptr. This means that ptr has to be anchored in a stack frame. I haven't looked at Verona specifically, but region systems all have this restriction (for example, ML Kit, the originator of regions, required a lexical "letregion" construct), unless they use dependent types.



When I first heard Microsoft was working on Rust-style safety, the context was adding it to C#. But this sounds like it's a completely new language. Have there been any public discussions about what its syntax and semantics will be like?


I would consider the example case of F# -- originally a research language that, though it graduated to a life of its own, keeps feeding features "back into" C#.




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

Search: