--[[ A 'Symbol' is an opaque marker type that can be used to signify unique statuses. Symbols have the type 'userdata', but when printed to the console, the name of the symbol is shown. ]] local Symbol = {} --[[ Creates a Symbol with the given name. When printed or coerced to a string, the symbol will turn into the string given as its name. ]] function Symbol.named(name) assert(type(name) == "string", "Symbols must be created using a string name!") local self = newproxy(true) local wrappedName = ("Symbol(%s)"):format(name) getmetatable(self).__tostring = function() return wrappedName end return self end --[[ Create an unnamed Symbol. Usually, you should create a named Symbol using Symbol.named(name) ]] function Symbol.unnamed() local self = newproxy(true) getmetatable(self).__tostring = function() return "Unnamed Symbol" end return self end return Symbol