
- Lua Tutorial
- Lua - Home
- Lua Basics
- Lua - Overview
- Lua - Environment
- Lua - Basic Syntax
- Lua - Comments
- Lua - Print Hello World
- Lua - Variables
- Lua - Data Types
- Lua - Operators
- Lua - Loops
- Lua - Generic For
- Lua - Decision Making
- Lua - Date and Time
- Lua Functions
- Lua - Functions
- Lua - Multiple Results
- Lua - Named Arguments
- Lua - Default/Optional Arguments
- Lua - Closures
- Lua - Uses of Closures
- Lua - Local Functions
- Lua - Anonymous Functions
- Lua - Functions in Table
- Lua - Proper Tail Calls
- Lua Strings
- Lua - Strings
- Lua - String Concatenation
- Lua - Loop Through String
- Lua - String to Int
- Lua - Split String
- Lua - Check String is NULL
- Lua Arrays
- Lua - Arrays
- Lua - Multi-dimensional Arrays
- Lua - Array Length
- Lua - Iterating Over Arrays
- Lua - Slicing Arrays
- Lua - Sorting Arrays
- Lua - Merging Arrays
- Lua - Sparse Arrays
- Lua - Searching Arrays
- Lua - Resizing Arrays
- Lua - Array to String Conversion
- Lua - Array as Stack
- Lua - Array as Queue
- Lua - Array with Metatables
- Lua - Immutable Arrays
- Lua - Shuffling Arrays
- Lua Iterators
- Lua - Iterators
- Lua - Stateless Iterators
- Lua - Stateful Iterators
- Lua - Built-in Iterators
- Lua - Custom Iterators
- Lua - Iterator Closures
- Lua - Infinite Iterators
- Lua - File Iterators
- Lua - Table Iterators
- Lua - Numeric Iterators
- Lua - Reverse Iterators
- Lua - Filter Iterators
- Lua - Range Iterators
- Lua - Chaining Iterators
- Lua Tables
- Lua - Tables
- Lua - Tables as Arrays
- Lua - Tables as Dictionaries
- Lua - Tables as Sets
- Lua - Table Length
- Lua - Table Iteration
- Lua - Table Constructors
- Lua - Loop through Table
- Lua - Merge Tables
- Lua - Nested Tables
- Lua - Accessing Table Fields
- Lua - Copy Table by Value
- Lua - Get Entries from Table
- Lua - Table Metatables
- Lua - Tables as Objects
- Lua - Table Inheritance
- Lua - Table Cloning
- Lua - Table Sorting
- Lua - Table Searching
- Lua - Table Serialization
- Lua - Weak Tables
- Lua - Table Memory Management
- Lua - Tables as Stacks
- Lua - Tables as Queues
- Lua - Sparse Tables
- Lua Lists
- Lua - Lists
- Lua - Inserting Elements into Lists
- Lua - Removing Elements from Lists
- Lua - Iterating Over Lists
- Lua - Reverse Iterating Over Lists
- Lua - Accessing List Elements
- Lua - Modifying List Elements
- Lua - List Length
- Lua - Concatenate Lists
- Lua - Slicing Lists
- Lua - Sorting Lists
- Lua - Reversing Lists
- Lua - Searching in Lists
- Lua - Shuffling List
- Lua - Multi-dimensional Lists
- Lua - Sparse Lists
- Lua - Lists as Stacks
- Lua - Lists as Queues
- Lua - Functional Operations on Lists
- Lua - Immutable Lists
- Lua - List Serialization
- Lua - Metatables with Lists
- Lua Modules
- Lua - Modules
- Lua - Returning Functions from Modules
- Lua - Returning Functions Table from Modules
- Lua - Module Scope
- Lua - SubModule
- Lua - Module Caching
- Lua - Custom Module Loaders
- Lua - Namespaces
- Lua - Singleton Modules
- Lua - Sharing State Between Modules
- Lua - Module Versioning
- Lua Metatables
- Lua - Metatables
- Lua - Chaining Metatables
- Lua Coroutines
- Lua - Coroutines
- Lua File Handling
- Lua - File I/O
- Lua - Opening Files
- Lua - Modes for File Access
- Lua - Reading Files
- Lua - Writing Files
- Lua - Closing Files
- Lua - Renaming Files
- Lua - Deleting Files
- Lua - File Buffers and Flushing
- Lua - Reading Files Line by Line
- Lua - Binary File Handling
- Lua - File Positioning
- Lua - Appending to Files
- Lua - Error Handling in File Operations
- Lua - Checking if File exists
- Lua - Checking if File is Readable
- Lua - Checking if File is Writable
- Lua - Checking if File is ReadOnly
- Lua - File Descriptors
- Lua - Creating Temporary Files
- Lua - Working with Large Files
- Lua Advanced
- Lua - Error Handling
- Lua - Debugging
- Lua - Garbage Collection
- Lua - Object Oriented
- Lua - Web Programming
- Lua - Database Access
- Lua - Game Programing
- Lua Useful Resources
- Lua - Quick Guide
- Lua - Useful Resources
- Lua - Discussion
Lua - Uses of Closures
A closure function is an inner function which closes over local variable of the enclosing function. A closure is a powerful mechanism in Lua. In this chapter, we're discussing various scenarios and usage of closures.
Iterator
We can create custom iterators to navigate colletions using closures. Generic for loop uses iterator to traverse collection and iterating state is maintained within the closure.
main.lua
function listIterator(list) local i = 0 local n = #list -- size of the list -- closure function to get next element return function() i = i + 1 if i <= n then return list[i] end end end list = {'A', 'B', 'C', 'D', 'E'} for element in listIterator(list) do print(element) end
Output
When the above code is built and executed, it produces the following result −
A B C D E
Encapsulation
Using enclosure, we can implement encapsulation in Lua similar to private variable in object oriented languages, by keeping data within scope of a function and modification to data is possible through returned closure.
main.lua
function newAccount(balance) local account = {} -- closure to add amount to balance account.deposit = function(amount) balance = balance + amount return balance end -- closure to deduct amount to balance account.withdraw = function(amount) balance = balance - amount return balance end -- closure to get updated balance account.getBalance = function() return balance end return account end -- create an account, with balance 100 account = newAccount(100) -- add 50 to the balance and print the updated balance as 150 print(account.deposit(50)) -- get updated balance 150 -- balance is not accessible via any other means print(account.getBalance())
Output
When the above code is built and executed, it produces the following result −
150 150
High Order Functions
While defining a higher order function which can take a function as argument or return a function. A closure plays an important role. A closure allows to retain context of the passed or returned function.
main.lua
function multiplyBy(factor) return function(x) return x * factor end end double = multiplyBy(2) triple = multiplyBy(3) -- prints 10 print(double(5)) -- prints 15 print(triple(5))
Output
When the above code is built and executed, it produces the following result −
10 15
Callback functions
In event driven programming, during an event or in asynchronous method calls, a closure can be used as a callback function which can access the data of the enviroment where callback function is created.
Factory Functions
Using closures, we can create factory functions which can create new functions as shown in above example where multiplyBy() function is used to create multiple multiplier functions. Here closure helps in generating function which have specific behavior based on captured enviroment.
Module Implementation
We can create modules by encapsulating functions and data with local scope using closures and returns a set of functions which are publically accessible to work on data.
Summary
In essence, closure provides a powerful and flexible option in Lua programming to create functions which can carry surrounding context. This helps in functional programming, increasing expressiveness of the programming language.