# MVar Docs

# Introduction

MVar is a low-level library for concurrent programming in TypeScript and JavaScript. It provides a single data type of the same name, inspired by Haskell's MVar. An MVar represents an abstract resource that can be shared by multiple concurrent tasks. Access-operations on MVars are atomic and serve as synchronization primitives between concurrent tasks.

An MVar is always in one of two states: It's either empty or holds some value. The two most important operations are put for writing to the MVar and take for reading its contents. Unlike traditional variables, the put methods first checks if the MVar is currently empty. If that's the case, then put writes the supplied value to the MVar; otherwise, it queues the value for later consumption. Similarly, take first checks if the MVar is currently full. In that case, take returns the contents wrapped in a promise which is synchronously resolved. Otherwise, take returns a promise, which is resolved as soon as the MVar becomes full. When the promise resolves, the MVar contents are replaced with the next value, that was queued by put if one is available; otherwise, it's left empty.

# Why MVar?

MVar is developed as part of a runtime-system-extension for another programming-language called Idris. Existing concurrency libraries were either too heavyweight or too high-level for this purpose. Thus, the goal of MVar is to support library-authors and compiler-implementors to provide higher-level concurrency abstractions.

# Why not?

Application-developers, on the other hand, are advised to choose a higher-level library for concurrency. For instance, a redux-store is very similar to an MVar. It also synchronizes control-flow and additionally manages application-state through state-reducers.

# Installation

MVar is available as a npm-package.

When using npm:

npm i mvar

When using yarn:

yarn mvar

# Importing

TypeScript / ES6

import {MVar} from 'mvar'

ES5 (CommonJS)

var MVar = require('mvar').MVar

ES5 (UMD build)

var MVar = mvar.MVar

# Example

Let's write a simple counter-application using MVar. The application will have buttons to increment and decrement the counter. We will use an MVar to mediate the button-clicks through a synchronized communication-channel and implement an explicit event-loop on top of it:

# API

# MVar.newEmpty

Create an MVar which is initially empty.

const mvar = MVar.newEmpty()

# MVar.new

Create an MVar which contains the supplied value.

const mvar = MVar.new(x)

# MVar.prototype.take

Return the contents of the MVar wrapped in a promise.

If the MVar is empty, the promise resolves once the MVar becomes full. If the MVar is full, the returned promise resolves synchronously with the contents.

When the promise is resolved, the MVar is left empty.

mvar.take()

# MVar.prototype.put

Put a value into an MVar.

If the MVar is empty, sets the contents of the MVar. If the MVar is full, queues the value until the MVar becomes empty.

mvar.put(x)

# MVar.prototype.read

Read the contents of an MVar wrapped in a promise.

If the MVar is empty, the returned promise is resolved once the MVar becomes full. If the MVar is full, the returned promise is synchronously resolved with the contents.

Read does not alter the contents of the MVar.

mvar.read()

# MVar.prototype.swap

Take a value from an MVar, put a new value into the MVar and return the old value wrapped in a promise.

If the MVar is empty, the promise resolves once the MVar becomes full. If the MVar is full, the returned promise resolves synchronously with the contents.

Queues the supplied value for later consumption.

mvar.swap(x)

# MVar.prototype.tryTake

A synchronous version of take.

If the MVar is empty, throws an exception. If the MVar is full, returns the contents of the MVar.

After tryTake executed, the MVar is left empty.

mvar.tryTake()

# MVar.prototype.tryPut

A synchronous version of put.

If the MVar is empty, sets the contents of the MVar and returns true. If the MVar is full, does nothing and returns false

mvar.tryPut(x)

# MVar.prototype.isEmpty

Check whether a given MVar is empty.

If the MVar is empty, returns true. If the MVar is full, returns false.

mvar.isEmpty()

# MVar.prototype.tryRead

A synchronous version of read.

If the MVar is empty, throws an exception. If the MVar is full, returns the contents of the MVar.

tryRead does not alter the contents of the MVar.

mvar.tryRead()