Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to design an api to a persistent collection in C#?
    primarykey
    data
    text
    <p>I am thinking about creating a persistent collection (lists or other) in C#, but I can't figure out a good API. </p> <p>I use '<a href="http://en.wikipedia.org/wiki/Persistent_data_structure" rel="nofollow">persistent</a>' in the <a href="http://clojure.org/data_structures#Data%20Structures-Collections" rel="nofollow">Clojure sense</a>: a persistent list is a list that behaves as if it has value semantics instead of reference semantics, but does not incur the overhead of copying large value types. Persistent collections use copy-on-write to share internal structure. Pseudocode: </p> <pre><code>l1 = PersistentList() l1.add("foo") l1.add("bar") l2 = l1 l1.add("baz") print(l1) # ==&gt; ["foo", "bar", "baz"] print(l2) # ==&gt; ["foo", "bar"] # l1 and l2 share a common structure of ["foo", "bar"] to save memory </code></pre> <p>Clojure uses such datastructures, but additionally in Clojure all data structures are immutable. There is some overhead in doing all the copy-on-write stuff so Clojure provides a workaround in the form of <a href="http://clojure.org/transients" rel="nofollow">transient</a> datastructures that you can use if you are sure you're not sharing the datastructure with anyone else. If you have the only reference to a datastructure, why not mutate it directly instead of going through all the copy-on-write overhead.</p> <p>One way to get this efficiency gain would be to keep a reference count on your datastructure (though I don't think Clojure works that way). If the refcount is 1, you're holding the only reference so do the updates destructively. If the refcount is higher, someone else is also holding a reference to it that's supposed to behave like a value type, so do copy-on-write to not disturb the other referrers. </p> <p>In the API to such a datastructure, one could expose the refcounting, which makes the API seriously less usable, or one could not do the refcounting, leading to unnecessary copy-on-write overhead if every operation is COW'ed, or the API loses it's value type behaviour and the user has to manage when to do COW manually. </p> <p>If C# had copy constructors for structs, this would be possible. One could define a struct containing a reference to the real datastructure, and do all the incref()/decref() calls in the copy constructor and destructor of the struct. </p> <p>Is there a way to do something like reference counting or struct copy constructors automatically in C#, without bothering the API users?</p> <p><strong>Edit:</strong> </p> <ul> <li>Just to be clear, I'm just asking about the API. Clojure already has an implementation of this written in Java. </li> <li>It is certainly possible to make such an interface by using a struct with a reference to the real collection that is COW'ed on every operation. The use of refcounting would be an optimisation to avoid unnecessary COWing, but apparently isn't possible with a sane API. </li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload