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
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 fornotImmutable.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:
List .. List— Alias for List.Concat.-List— Alias for List.Reverse.List + List— Alias for List.Concat.List + value— Alias for List.Append.List - List— Alias for List.PullAll.List - value— Alias for List.Pull.List * List— Alias for List.Intersection.
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:
Dictionary .. Dictionary— Alias for Dictionary.Defaults.-Dictionary— Alias for Dictionary.Invert.Dictionary + Dictionary— Alias for Dictionary.Merge.Dictionary - List— Alias for Dictionary.Omit.Dictionary * List— Alias for Dictionary.Pick.