# Lua Functional Programming/Functions

In Lua, as in Lisp, functions are a kind of data type; you can assign them to variables and pass them around in your code.

## Defining Functions

Functions can be defined in the "ordinary" way, and we can call them.

```> function double(x) return x*2 end
> return double(1)
2
```

We can access the function object created simply by using its name without any parentheses. Thus we can pass the function as an argument, store it in a data structure, etc.

```> return double
function: 0x806a5e8
> a = {double} -- creates an array
> return double == a
true
```

So-called lambda expressions or anonymous inline functions can also be created in Lua. They are similar to the "ordinary" functions described above in almost every way.

```> return function(x) return x*2 end
function: 0x806b950
> return (function(x) return x*2 end)(1)
2
```

Note that functions and other variables share the same namespace in Lua (and in most other languages), unlike Lisp. In fact, in Lua, a function is just another kind of data you can store in a variable.

## Functional Arguments

Function objects can be passed to other functions as arguments. To invoke an argument as a function, just append the parenthesised list that you want to invoke it with. Using the `double` function defined earlier, we can do things like

```> function dofunction(f) return f(21) end
> return dofunction(double)
42
```

The "canonical" example of a function that takes another function as a parameter is `map`. Unfortunately `map` does not come with Lua, so we'll have to code it ourselves.

```function map(func, array)
local new_array = {}
for i,v in ipairs(array) do
new_array[i] = func(v)
end
return new_array
end
```

This is a simple `map` implementation that only works with one array. But it works well:

```> return table.concat(map(double, {1,2,3}),",")
2,4,6
```

A more complex `map` implementation that works with more than one array is possible:

```function mapn(func, ...)
local new_array = {}
local i=1
local arg_length = table.getn(arg)
while true do
local arg_list = map(function(arr) return arr[i] end, arg)
if table.getn(arg_list) < arg_length then return new_array end
new_array[i] = func(unpack(arg_list))
i = i+1
end
end
```

And let's use it:

```> t = mapn(function(a,b) return a+b end, {1,2,3}, {4,5,6})
> return table.concat(t,",")
5,7,9
```

Sort is built-in, though, and we can pass a sorting function if we want.

```> t = {1,4,2,5,6,7,3}
> table.sort(t, function(a,b) return a<b end)
> return table.concat(t,",")
1,2,3,4,5,6,7
```

On Lisp provides an example of a remove-if implementation in Lisp. Remove-if is not built-in into Lua, so we might as well code a Lua implementation which is equivalent to the Lisp code below.

```function cdr(arr)
local new_array = {}
for i = 2, table.getn(arr) do
table.insert(new_array, arr[i])
end
return new_array
end
function cons(car, cdr)
local new_array = {car}
for _,v in cdr do
table.insert(new_array, v)
end
return new_array
end
function lisp_remove_if(func, arr)
if table.getn(arr) == 0 then return {} end
if func(arr) then
return lisp_remove_if(func, cdr(arr))
else
return cons(arr, lisp_remove_if(func, cdr(arr)))
end
end
```

Compare with the following Lisp code:

```(defun our-remove-if (fn lst)
(if (null lst)
nil
(if (funcall fn (car lst))
(our-remove-if fn (cdr lst))
(cons (car lst) (our-remove-if fn (cdr lst))))))
```

Both the Lua and Lisp code above are tail-recursive safe (see Tail Recursion below). (Most implementations for both languages support tail-recursion optimising.) Just for comparison, here's how I would code a "pure" Lua version:

```function lua_remove_if(func, arr)
local new_array = {}
for _,v in arr do
if not func(v) then table.insert(new_array, v) end
end
return new_array
end
```

In Lua, we have to define the helper functions `cdr` and `cons` which is built-in into Lisp, but using the `remove_if` is quite easy:

```> t = lisp_remove_if(function(x) return math.mod(x,2)==0 end, {1,2,3,4,5})
> return table.concat(t,",")
1,3,5
```