Functions as Values
In Lua, a function is a value, just like a number, a text or a table. type says so: type(print) is "function". And like any value, a function can be stored in a variable. In fact, local function double(n) is just a shorter way of creating a function and storing it in a local variable, like this:
local double = function(n)
return n * 2
end
local twice = double
print(double(4), twice(10))
print(type(double), type(double(4)))This prints:
8 20
function numberfunction(n) … end without a name creates a function, and local double = stores it in a variable. local twice = double doesn't call anything, because there are no parentheses: it stores the same function under a second name. type(double) asks about the function itself, while type(double(4)) asks about the number it returned.
The most useful part: a function can be passed to another function as an argument. This function goes through a list and changes every item with a function that it gets as a parameter:
local function applyToAll(list, change)
local result = {}
for _, value in ipairs(list) do
table.insert(result, change(value))
end
return result
end
local function double(n)
return n * 2
end
local prices = {2, 3, 5}
print(table.concat(applyToAll(prices, double), " "))
print(table.concat(applyToAll(prices, function(n) return n + 1 end), " "))This prints:
4 6 10
3 4 6Inside applyToAll, change is a parameter like any other, but it holds a function, so applyToAll calls it: change(value). applyToAll doesn't know what the change will be; the caller decides. The second call doesn't even give its function a name. It writes the function right in the parentheses of the call. A function without a name is called an anonymous function. It's handy for short functions that you need in one place only, and a short one can fit on a single line.
When you pass a function, write it without parentheses: double, not double(5). With parentheses, you call it right away and pass its result, the number 10:
local function applyToAll(list, change)
local result = {}
for _, value in ipairs(list) do
table.insert(result, change(value))
end
return result
end
local function double(n)
return n * 2
end
local prices = {2, 3, 5}
print(table.concat(applyToAll(prices, double(5)), " "))The program ends with an error:
main.lua:4: attempt to call a number value (local 'change')applyToAll got the number 10 in change and tried to call it. You'll see functions passed to other functions often: in the next exercise, you'll give one to table.sort.
Instructions
On Saturdays, every price at Emma's stall is 2 coins higher. Write a function saturdayPrice with a parameter price that returns price + 2. Then pass it to applyToAll together with prices, and print the result joined with table.concat(…, " "). The program prints 7 10 22 14 5.
At the end of the day, Emma sells everything for half price. Print the prices divided by 2 with //, but this time, don't write a named function: write an anonymous function right in the call of applyToAll. The program prints 2 4 10 6 1.
Now write a function that takes a function: a local function countIf with two parameters, list and check. It returns how many items of list the function check returns true for.
Use countIf with anonymous functions to find out how many prices are over 7 coins and how many are under 5. The program prints:
Over 7: 3
Under 5: 1Start programming for free
7/11