9

What is the syntax to create the function, but then add it's implementation further down in code?

So roughly like this:

  • Define function doX
  • Call doX (further down in the code)
  • doX implemention (i.e. all functions down at the bottom of the file)
2
  • You cannot call the function before it is defined, but perhaps Paul's answer meets your needs. Commented Sep 6, 2012 at 0:31
  • possible duplicate of Lua function range problem Commented Sep 6, 2012 at 8:00

4 Answers 4

15

You only need to have a variable to reference. local funcName is sufficient for your purposes with one caveat. This will work:

local funcName
function callIt()
  print(funcName())
end
function defineIt()
  funcName = function() return "My Function" end
end
defineIt()
callIt()

As long as you define it (defineIt) before you call it (callIt), it should work as expected. You can't do something like this though (and this is the caveat):

local funcName
print(funcName())
funcName = function() return "My Function" end

You will get an error: attempt to call local 'funcName' (a nil value).

Sign up to request clarification or add additional context in comments.

4 Comments

You don't need to wrap the function definition in defineIt. It'll work just fune with funcName = function()... as a separate line. That is after all what local function funcName() does.
oh...so there's really no way to call funcName prior to having actually defined the function then? i.e. you still need to make sure defineIt is called before your first call to funcName itself?
@Greg: yes. If you really want to be able to call it before you "define" it, you can use local funcName = function() end, but it won't do anything useful (it won't throw runtime error either). You can then later set it to something else that does useful work for you.
@Nicol, right, I just wanted to emphasize the order of define/use operations.
12

oh...so there's really no way to call funcName prior to having actually defined the function then? i.e. you still need to make sure defineIt is called before your first call to funcName itself?

I wanted to clarify this point, and I felt that an answer would be the better way than a comment.

Lua is a much simpler language than C or C++. It is built on some simple foundations, with some syntactic sugar to make parts of it easier to swallow.

There is no such thing as a "function definition" in Lua. Functions are first-class objects. They are values in Lua, just like the number 28 or the string literal "foo" are values. A "function definition" simply sets a value (namely, the function) into a variable. Variables can contain any kind of value, including a function value.

All a "function call" is is taking the value from a variable and attempting to call it. If that value is a function, then the function gets called with the given parameters. If that value is not a function (or a table/userdata with a __call metamethod), then you get a runtime error.

You can no more call a function that hasn't been set in a variable yet than you can do this:

local number = nil
local addition = number + 5
number = 20

And expect addition to have 25 in it. That's not going to happen. And thus, for the same reason, you can't do this:

local func = nil
func(50)
func = function() ... end

As Paul pointed out, you can call a function from within another function you define. But you cannot execute the function that calls it until you've filled in that variable with what it needs to contain.

Comments

9

As others have written, you cannot call a function at runtime that has not been assigned prior to the call. You have to understand that:

function myFunc() print('Something') end

Is just a syntax sugar for this:

myFunc = function() print('Something') end

Now, it makes sense that this kind of code would not work the way you want it to:

print(greeter(io.read())) -- attempt to call global 'greeter' (a nil value)
function greeter(name) return 'Hello '..name end

When you use the greeter variable, its value is nil, because its value is set only on the next line.

But if you want to have your "main" program on the top and the functions at the bottom, there is simple way to achieve this: create a "main" function and call it as the last thing on the bottom. By the time the function is called, all the functions will be set to the corresponding global variables:

-- start of program, your main code at the top of source code
function main()
    local name = readName()
    local message = greeter(name)
    print(message)
end

-- define the functions below main, but main is not called yet,
-- so there will be no errors
function readName() io.write('Your name? '); return io.read() end
function greeter(name) return 'Hello, ' .. name end

-- call main here, all the functions have been assigned,
-- so this will run without any problems
main()

1 Comment

Good answer, a main() function is a pretty standard way of achieving this in Python
0

The simplest pattern to define a local function after a syntactic call site is:

local doX;                  -- Introduce the name as a local.
local function callDoX()    -- Define another function
  doX();                    --   that calls it.
end;
doX = function()            -- To define the function, *assign* its name
  print("In doX.");         -- to a function value.
end;
callDoX();                  -- Invoke the caller.

Note that the definition of doX cannot use the usual shorthand function definition syntax:

local function doX()        -- DOES NOT WORK in this scenario.
  print("In doX.");
end;

The reason is that each use of local defines a new variable (see the Visibility Rules), so the above would define a different variable, also called doX, than the one that callDoX refers to. The later definition must use the variable assignment syntax instead.


Comparison to other answers:

  • The answer by Paul Kulchenko is misleadingly complicated by wrapping the assignment inside another function; that is not necessary, and obscures the crucial use of the variable assignment syntax.

  • The answer by Nicol Bolas provides useful background but does not actually answer the question with working code.

  • The answer by Michal Kottman uses the shorthand function definition syntax. This only works when the names are not local. Local names are preferable, when feasible, due to not polluting the global namespace.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.