smut

Types

Represents a handle to an individual shared, mutable value of type a.

pub type State(a) =
  @internal State(a)

Values

pub fn get(state: State(a)) -> Result(a, Nil)

Retrieve the current value of state.

Global state, in general, is problematic. I have done my (admittedly non-expert) best to ensure this library runs smoothly, but if anything goes wrong, this function will return Error(Nil). It does not return a more informative error message, because if something has gone wrong, your program, which relies on this state, is probably hosed.

(In future versions, I may attempt to provide some facilities for attempting to recover from certain kinds of errors, but that’s all very contingent.)

pub fn get_and_update(
  with: fn(a) -> a,
  state: State(a),
) -> Result(a, Nil)

Return the value of state and then update it with the given function.

This operation is guaranteed to be “atomic”; that is, no other process can affect the value of state between its retrieval and replacement.

// Our updater function, which we define ahead of time to make the
// call to get_and_update more readable.
let f = fn(n) { n + 2 }

let assert Ok(val) = smut.get(state)
echo val
// 8001
let assert Ok(same_val) = smut.get_and_update(f, state)
echo same_val
// Guaranteed to be 8001 as long as no other process changed `state`
// between the calls to smut.get and smut.get_and_update.
let assert Ok(new_val) = smut.get(state)
// Guaranteed to be 8003 as long as no other process changed `state`
// between the calls to smut.get_and_update and the second call
// to smut.get.
pub fn init() -> types.TableHandle

Create a table to hold shared, mutable state values and return a handle to it.

You should call this function as early in your program as possible, preferably in your main function, and pass this handle around.

pub fn new(
  table: types.TableHandle,
  initial_val: a,
) -> Result(State(a), types.SmutError)

Insert a new initial_val of type a into the global state table, returning a handle for reads, writes, and updates.

pub fn set(new_val: a, state: State(a)) -> Nil

Replace the current value of state with the given new_val.

The majority of the time, you will probably want to use one of

  • update()
  • update_and_get()
  • get_and_update()

instead. An operation like

let assert Ok(cur_val) = smut.get(state)
let new_val = update_state(cur_val)
smut.set(state, new_val)

is not guaranteed to be atomic; another process could futz with the value of state between the call to smut.get() and smut.set(). The update family of functions ensure “atomic” updates.

pub fn update(with: fn(a) -> a, state: State(a)) -> Nil

Update the current value of state with the given update function.

This operation is guaranteed to be “atomic”; that is, no other process can affect the value of state between its retrieval and replacement; its value immediately after the function call will be the value returned by with.

pub fn update_and_get(
  with: fn(a) -> a,
  state: State(a),
) -> Result(a, Nil)

Update the value of state with the given function, then return the new value.

// Our updater function, which we define ahead of time to make the
// call to update_and_get more readable.
let f = fn(n) { n + 2 }

let assert Ok(val) = smut.get(state)
echo val
// 8001
let assert Ok(new_val) = smut.update_and_get(f, state)
echo new_val
// Guaranteed to be 8003 as long as no other process changed `state`
// between the calls to smut.get and smut.update_and_get.
pub fn with_timeout(state: State(a), ms: Int) -> State(a)

Change the default retrieval timeout (for retrievals that require a timeout) for this particular value to ms milliseconds.

The default timeout is otherwise 5000 ms.

Search Document