Skip to main content

Permafrost

Permafrost is a library for creating and manipulating immutable data structures, specifically List and Dictionary.

Immutable data structures provide a variety of benefits as a result of not being able to be modified after creation, including being:

  • easier to reason about, and test,
  • easier to use in concurrent environments.

Types

Immutable

type Immutable = List | Dictionary

Both List and Dictionary share some common methods and metavalues via Immutable.

Immutable objects have two metavalues to help determine their type:

  • __immutable - A boolean that is always true.
  • __type - A string that is either "List" or "Dictionary".

All Immutable objects are deeply frozen, meaning that they cannot be modified in any way, including any nested tables which are converted to Immutables at time of creation.

Any attempt to modify an Immutable object will result in an error.

Metamethods

  • tostring(Immutable) — Returns a JSON-encoded string of the Immutable object.
  • Immutable == Immutable — Alias for Immutable.Equals.
  • Immutable ~= Immutable — Alias for not Immutable.Equals.

List

type List = {any}

Inherits behaviours from Immutable (type).

Methods

Methods from Immutable and List can be accessed via the object using colon notation with an underscore before the method name:

List.Method(list, ...) == list:_Method(...)

For example, with Filter:

local list = List.new({ 1, 2, 3 })

local filtered = list:_Filter(function(element)
  return element == 1
end) -- { 1 }

Metamethods

In addition to the metamethods from Immutable, List also has the following metamethods:

Dictionary

type Dictionary = {[string]any}

Inherits behaviours from Immutable (type).

Methods from Immutable and Dictionary can be accessed via the object using colon notation with an underscore before the method name:

Dictionary.Method(dictionary, ...) == dictionary:_Method(...)

For example, with FilterKeys:

local dictionary = Dictionary.new({ a = 1, b = 2 })

local filtered = dictionary:_FilterKeys(function(key)
  return key == "a"
end) -- { a = 1 }

Metamethods

In addition to the metamethods from Immutable, Dictionary also has the following metamethods:

Show raw api
{
    "functions": [],
    "properties": [],
    "types": [
        {
            "name": "Immutable",
            "desc": "Both List and Dictionary share some common methods and metavalues via Immutable.\n\nImmutable objects have two metavalues to help determine their type:\n- `__immutable` - A boolean that is always true.\n- `__type` - A string that is either \"List\" or \"Dictionary\".\n\nAll Immutable objects are deeply frozen, meaning that they cannot be modified in any way,\nincluding any nested tables which are converted to Immutables at time of creation.\n\nAny attempt to modify an Immutable object will result in an error.\n\n#### Metamethods\n\n- `tostring(Immutable)` — Returns a JSON-encoded string of the Immutable object.\n- `Immutable == Immutable` — Alias for [Immutable.Equals](/api/Immutable#equal).\n- `Immutable ~= Immutable` — Alias for `not` [Immutable.Equals](/api/Immutable#equal).",
            "lua_type": "List | Dictionary",
            "source": {
                "line": 1769,
                "path": "src/init.lua"
            }
        },
        {
            "name": "List",
            "desc": "Inherits behaviours from [Immutable] (type).\n\n#### Methods\n\nMethods from [Immutable](/api/Immutable) and [List](/api/List) can be accessed via the object\nusing colon notation with an underscore before the method name:\n\n```lua\nList.Method(list, ...) == list:_Method(...)\n```\n\nFor example, with Filter:\n\n```lua\nlocal list = List.new({ 1, 2, 3 })\n\nlocal filtered = list:_Filter(function(element)\n  return element == 1\nend) -- { 1 }\n```\n\n#### Metamethods\n\nIn addition to the metamethods from [Immutable], List also has the following metamethods:\n\n- `List .. List` — Alias for [List.Concat](/api/List#concat).\n- `-List` — Alias for [List.Reverse](/api/List#reverse).\n- `List + List` — Alias for [List.Concat](/api/List#concat).\n- `List + value` — Alias for [List.Append](/api/List#append).\n- `List - List` — Alias for [List.PullAll](/api/List#pullall).\n- `List - value` — Alias for [List.Pull](/api/List#pull).\n- `List * List` — Alias for [List.Intersection](/api/List#intersection).",
            "lua_type": "{any}",
            "source": {
                "line": 1807,
                "path": "src/init.lua"
            }
        },
        {
            "name": "Dictionary",
            "desc": "Inherits behaviours from [Immutable] (type).\n\nMethods from [Immutable](/api/Immutable) and [Dictionary](/api/Dictionary) can be accessed via the\nobject using colon notation with an underscore before the method name:\n\n```lua\nDictionary.Method(dictionary, ...) == dictionary:_Method(...)\n```\n\nFor example, with FilterKeys:\n\n```lua\nlocal dictionary = Dictionary.new({ a = 1, b = 2 })\n\nlocal filtered = dictionary:_FilterKeys(function(key)\n  return key == \"a\"\nend) -- { a = 1 }\n```\n\n#### Metamethods\n\nIn addition to the metamethods from [Immutable], Dictionary also has the following metamethods:\n\n- `Dictionary .. Dictionary` — Alias for [Dictionary.Defaults](/api/Dictionary#defaults).\n- `-Dictionary` — Alias for [Dictionary.Invert](/api/Dictionary#invert).\n- `Dictionary + Dictionary` — Alias for [Dictionary.Merge](/api/Dictionary#merge).\n- `Dictionary - List` — Alias for [Dictionary.Omit](/api/Dictionary#omit).\n- `Dictionary * List` — Alias for [Dictionary.Pick](/api/Dictionary#pick).",
            "lua_type": "{[string]: any}",
            "source": {
                "line": 1841,
                "path": "src/init.lua"
            }
        }
    ],
    "name": "Permafrost",
    "desc": "Permafrost is a library for creating and manipulating immutable data structures, specifically\n[List] and [Dictionary].\n\nImmutable data structures provide a variety of benefits as a result of not being able to be\nmodified after creation, including being:\n- easier to reason about, and test,\n- easier to use in concurrent environments.",
    "source": {
        "line": 1747,
        "path": "src/init.lua"
    }
}