Unique Type

A feature available in the CleanLanguage (and some other research languages) where a value of such type must be used in a linear way: there can be only one reference to it at any given time.

UniqueTypes are useful to model concepts that require destructive update, including:

Very similar to LinearTypes (I'm not sure what the difference is, or whether there is any difference).


Like monads, a way of dealing with SideEffects in languages which do not have them. If the uniqueness invariant is preserved, then the object can be mutated in place rather than copied everywhere--allowing both the advantages of ReferentialTransparency while having mutable state. (OTOH, one must ask how ReferentiallyTransparent an expression is if I can't hold on to it forever...)

In FunctionalProgrammingLanguages, a longstanding technique for writing code which resembles mutable-state code is threading (which has nothing to do with multithreading or other concurrency mechanisms). If you have an object which you want to "mutate", you adopt the following conventions in mutator functions:

This is called "threading" as objects of this sort were "threaded" through a program. This technique, while useful, is a pain for the programmer. Plus, when threading is used, the language may not know that mutable updates are possible. UniqueTypes are a way of formalizing this technique; both to allow the compiler optimization and to avoid the need to declare "threaded" arguments everywhere.

Was this the motivation for implicit parameters?


When a type is unique, it means that values of that type cannot be duplicated. I.e. if world 's type is unique, that means that you cannot do the following:

  let world1 = print_line world "Please buy Cincom stock"
  let world2 = print_line world "Please sell Cincom stock"

sleep (3600*24*7)

if world.stock_raised "Cincom" then world = world1 else world = world2

Conceptually, the computer has only 1 register that is capable of holding values of type "world".

-- StephanHouben


I don't quite get it, please help. Suppose I have a simple dag (B->A, C->A)...

...and I want to mutate A. How is the threading technique / unique type going to help, since I have (inherently?) two copies of A, corresponding to the two dag pointers. Threading one of them will leave the other one hanging with an old version of A, which is clearly unintended and will fail the unique type check. But then, how do I manage to mutate A at all? -- CristiPp? Note that this sharing of side-effects is intrinsically non-purely functional (break referential transparency), since there is no concept of object identity. IMHO, uniqueness types mostly help make imperative constructs (efficiently) referentially transparent. As always, the problem can be solved with more indirection (very much in the spirit of mutable cells in ML, or the way some Lisp compilers implement mutable closures). You could, in the general case, thread a heap, with pointers represented as keys in that heap. For graphs, the usual representation as a pair of arcs and nodes works fine. -- AnonymousDonor


EditText of this page (last edited June 2, 2008) or FindPage with title or text search