This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

11.5 – Sets and Bags

Suppose you want to list all identifiers used in a program source; somehow you need to filter the reserved words out of your listing. Some C programmers could be tempted to represent the set of reserved words as an array of strings, and then to search this array to know whether a given word is in the set. To speed up the search, they could even use a binary tree or a hash table to represent the set.

In Lua, an efficient and simple way to represent such sets is to put the set elements as indices in a table. Then, instead of searching the table for a given element, you just index the table and test whether the result is nil or not. In our example, we could write the next code:

    reserved = {
      ["while"] = true,     ["end"] = true,
      ["function"] = true,  ["local"] = true,
    for w in allwords() do
      if reserved[w] then
        -- `w' is a reserved word
(Because while is a reserved word in Lua, we cannot use it as an identifier. Therefore, we cannot write while = 1; instead, we use the ["while"] = 1 notation.)

You can have a clearer initialization using an auxiliary function to build the set:

    function Set (list)
      local set = {}
      for _, l in ipairs(list) do set[l] = true end
      return set
    reserved = Set{"while", "end", "function", "local", }