I've been learning currying in Lua and came across the following code:
function addup(x)
local sum = 0
local function f(n)
if type(n) == "number" then
sum = sum + n
return f
else
return sum
end
end
return f(x)
end
print(addup (1) (2) (3) ()) --> 6
print(addup (4) (5) (6) ()) --> 15
I assume that the (1) (2) (3) () part means that the values are passed to the function in succession rather than simultaneously. My problem is that I can't quite figure out how exactly these values are passed and how the function manipulates them. So the first value goes to x, but what happens to the second? Is it passed as n into the inner function? Then where goes the third one?
My other problem is with the line:
return f
Here a function returns itself without any value or even parentheses. I know that you can pass in a string or a table to a function omitting the parentheses but it is not the case here. So what's going on?
I looked in the manuals but didn't find anything on either of these features. I'd really appreciate an explanation or a link to a manual that covers this in detail. Thanks.
Update: link to the tutorial I referred to - http://lua-users.org/wiki/CurriedLua
As it was pointed out in one of the anwsers, there is no (x)(y) syntax in lua. What it is, is a series of function calls. This wasn't actually mentioned in the tutorial but was my assumption which turned out to be wrong, so I edited this bit out.
The issue is solved. Thank you for all your answers, they were very helpful.
There is no (x)(y) syntax in Lua. That's why you don't find anything in the manual. (x)(y) on its own will cause a syntax error
addup (1) (2) (3) () is a sequence of function calls. To understand this you have to carefully read addup's code and realize that a function call is nothing but a function value followed by the call operator and that functions are just values that you can return as any other type.
This expression is evaluated from left to right.
The call operator () operates on the value to its left.
So first we evaluate addup(1) which calls the global function addup.
addup defines a local number value local sum = 0 and a local function value f.
local function f(n)
if type(n) == "number" then
sum = sum + n
return f
else
return sum
end
end
and then returns the return value of that function called with addup's argument x
return f(x)
sum is an upvalue to f, that's a value that was in scope where f was defined. so every time you call f it has access to sum.
So n becomes x in function f. As n is a number value f will add n to sum and return a itself f.
So addup(1) evaluates to a reference to f, a function value with the upvalue sum == 1.
Now we have this returned function value to the left of (2) which is another function call to f. This time n is 2. Again it is a number so it will be added to sum and f will return itself again.
Now f is called with (3). Same as above.
Finally f is called with (). This time n is nil and f returns sum. So addup (1) (2) (3) () ultimately evaluates to 6 befor it is handed to print.
Not sure where you got that example from but doesn't make too much sense to me. There are simpler ways to explain upvalues and closures. Code like that is unecessarily hard to read.
something like this, by analogy:
local _L = {}
function addup(x)
local sum = 0
_L["f"] = function (n)
if type(n) == "number" then
sum = sum + n
return _L["f"]
else
return sum
end
end
return _L["f"](x)
end
print(addup (1) (2) (3) ()) --> 6
print(addup (4) (5) (6) ()) --> 15
"return f" - returns a reference to a function inside the local namespace, which is just a table.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With