HKTonyLee
HKTonyLee

Reputation: 3310

Difference(s) between named function & anonymous function (Lua)

What is the differences between these myFuncs?

Code 1

function wrapper()
    local someVariable = 0;
    function myFunc(n)
        if n > 0 then return myFunc(n-1) end
    end
    return myFunc;
end

Code 2

function wrapper()
    local someVariable = 0;
    local myFunc = function(n)
        if n > 0 then return myFunc(n-1) end
    end
    return myFunc;
end

Code 3

function wrapper()
    local someVariable = 0;
    local myFunc;
    myFunc = function(n)
        if n > 0 then return myFunc(n-1) end
    end;
    return myFunc;
end

Because when I refer the function name myFunc inside the myFunc itself. Their behavior are not the same. (eg. the upvalue someVariable... problematic :-S )

Upvotes: 4

Views: 377

Answers (2)

Paul Kulchenko
Paul Kulchenko

Reputation: 26794

Nicol's answer is mostly correct, but there is one thing that is worth pointing out:

In Code 2 MyFunc doesn't need to be a global variable, it can be a local variable in some outer scope, which will become an upvalue for this function you are creating (the same comment also applies to Code 1). For example, this will print 100:

local function myFunc(n) return 100 end
function wrapper()
    local someVariable = 0;
    local myFunc = function(n)
        if n > 0 then return myFunc(n-1) end
    end
    return myFunc;
end
print(wrapper()(1))

So, to summarize, there are four ways you can use to define myFunc:

  1. local myFunc; myFunc = function(n) ... return myFunc(n-1) end
  2. local function myFunc(n) ... return myFunc(n-1) end
  3. local myFunc = function(n) ... return myFunc(n-1) end
  4. myFunc = function(n) ... return myFunc(n-1) end

1 and 2 are full equivalents. 3 will not do what you expect as it will use whatever definition of myFunc is available when local myFunc is executed (which may point to an upvalue for MyFunc or a global variable). 4 will work, but only because it will assign the newly created function to (again) either an upvalue or a global variable (and reference the same value in the body of the function).

Upvotes: 2

Nicol Bolas
Nicol Bolas

Reputation: 474226

[edit: I misread your code #2.]

Code #1 sets the global value of myFunc to the function. So every time you call wrapper, you will be setting this one global to a new value. Furthermore, any references to your myFunc call will be to this global (which is modifiable), not to a local (which would be an upvalue of the closure).

Code #2 sets a local variable myFunc. However, because of the rules of Lua, that local variable only comes into scope after the statement defining it is complete. This allows you to do things like this:

local x = x or 5

The x in the expression is a previously declared local or global. The new x doesn't come into scope until after the x or 5 expression has been evaluated.

The same goes for your function definition. Therefore any references to myFunc will be to a global variable, not a local.

Code #3 creates a local variable myFunc. Then it sets into that variable a function. Because the function is created after the local variable comes into scope, references to myFunc in the function will refer to the local variable, not to a global one.

Note that local function X is equivalent to local X; X = function.... Not to local X = function....

Upvotes: 5

Related Questions