# V Work In Progress ***This document describes features that are not implemented, yet. Please refer to [docs.md](https://github.com/vlang/v/blob/master/doc/docs.md) for the current state of V*** ## Table of Contents * [Concurrency](#concurrency) * [Variable Declarations](#concurrency-variable-declarations) ## Concurrency ### Variable Declarations Objects that are supposed to be used to exchange data between coroutines have to be declared with special care. Exactly one of the following 4 kinds of declaration has to be chosen: ```v a := ... mut b := ... shared c := ... atomic d := ... ``` - `a` is declared as *constant* that can be passed to other coroutines and read without limitations. However it cannot be changed. - `b` can be accessed reading and writing but only from one coroutine. That coroutine *owns* the object. A `mut` variable can be passed to another coroutine (as receiver or function argument in the `go` statement or via a channel) but then ownership is passed, too, and only the other coroutine can access the object.1 - `c` can be passed to coroutines an accessed *concurrently*.2 In order to avoid data races it has to be locked before access can occur and unlocked to allow access to other coroutines. This is done by the following block structure: ```v lock c { // read, modify, write c ... } ``` Several variables may be specified: `lock x, y, z { ... }`. They are unlocked in the opposite order. - `d` can be passed to coroutines and accessed *concurrently*, too.3 No lock is needed in this case, however `atomic` variables can only be 32/64 bit integers (or pointers) and access is limited to a small set of predefined idioms that have native hardware support. To help making the correct decision the following table summarizes the different capabilities: | | *default* | `mut` | `shared` | `atomic` | | :--- | :---: | :---: | :---: | :---: | | write access | | + | + | + | | concurrent access | + | | + | + | | performance | ++ | ++ | | + | | sophisticated operations | + | + | + | | | structured data types | + | + | + | | ### Strengths #### default - very fast - unlimited access from different coroutines - easy to handle #### `mut` - very fast - easy to handle #### `shared` - concurrent access from different coroutines - data type may be complex structure - sophisticated access possible (several statements within one `lock` block) #### `atomic` - concurrent access from different coroutines - reasonably fast ### Weaknesses #### default - read only #### `mut` - access only from one coroutine at a time #### `shared` - lock/unlock are slow - moderately difficult to handle (needs `lock` block) #### `atomic` - limited to single (max. 64 bit) integers (and pointers) - only a small set of predefined operations possible - very difficult to handle correctly 1 The owning coroutine will also free the memory space used for the object when it is no longer needed. 2 For `shared` objects the compiler adds code for reference counting. Once the counter reaches 0 the object is automatically freed. 3 Since an `atomic` variable is only a few bytes in size allocation would be an unnecessary overhead. Instead the compiler creates a global.