# Chapter 44. Smart pointers As we can see, Isolated[T] is rather hard to work with and effectively turns an existing ref into a “unique ref”. It is most useful when the ref type stems from a library that we have no control over. If we have the control over the used pointer type and the pointer is used in a concurrent setting then ref should be avoided and instead a more refined “smart pointer” type should be used. For example, the “smartptrs” module from the “threading” package provides the SharedPtr, ConstPtr and UniquePtr types. A SharedPtr is a reference-counted pointer type that uses atomic instructions and thus can be shared between threads. A ConstPtr is a SharedPtr that enforces that the data it wraps can only be used for read accesses. And finally a UniquePtr is a pointer that has a single owner and can only be moved around. The following snippet outlines how SharedPtr can be used to create a singly linked list: import threading/smartptrs type MyList = object 1 data: string next: SharedPtr[MyList] 2 var head, tail: SharedPtr[MyList] 3 proc send(x: sink string) = withMyLock headLock: tail = newSharedPtr MyList(data: x, next: move tail) 4 if head.isNil: head = tail 5 271 1 The node type a linked list consists of. 2 The next field is of type SharedPtr[MyList] so that there can be more references to it than just the owning reference. This makes list traversals convenient to write as we can avoid the destructive moves during traversal. 3 The head and tail of the list have to be of type SharedPtr[MyList] too. 4 Appending to the list works much like insertion in the Isolated[T] case. 5 Since a SharedPtr supports a copy operation, both head and tail can point to the same object. The program using SharedPtr arguably can be a little easier than its Isolated variant, but both are no match for a seq container that is wrapped in a lock or a dedicated channel data structure. Pointers are hard to use, especially in a multithreading setting. Modern Nim code avoids pointers for this reason. It is far easier to program in a world of values with restricted aliasing capabilities.