In Lua, I can create an object like so:

local foo = Foo.new({10, 10}, 3, right)

or like so:

local foo = Foo.new({
    pos = {10, 10},
    len = 3,
    direction = "right"

The former is more compact, whereas the latter is more understandable and flexible.

Which is generally considered the better form of accepting arguments?

  • 1
    I don't know about Lua styles specifically, but in other realms, the way things are usually done is that required parameters are always function arguments, and optional stuff can be passed in an additional dictionary. Commented Dec 9, 2016 at 19:28
  • 5
    This is entirely your decision. You'll have to decide which one you like better, depending on your specific requirements. You might even choose different ways in the same project. Commented Dec 9, 2016 at 19:33

1 Answer 1


Lua uses positional parameter passing. So there isn't a 'natural' way to pass named arguments. You can simulate them by turning this:

--invalid code
rename(old="temp.lua", new="temp1.lua") 

into this:

rename{old="temp.lua", new="temp1.lua"}

using this:

function rename (arg)
  return os.rename(arg.old, arg.new)

More generally this is known as the introduce parameter object refactoring. You're doing the same thing in your question but just being more formal about it by insisting on the parenthesis.

Depending on arity (the number of arguments) and readability these simulated named arguments can become very helpful indeed. If the arity is small and the meaning of the values are obvious without looking at the function definition then the compact form is fine. Personally I had no idea what {10, 10}, 3, right were going to be until I looked at the table. Though I must say, a name like Foo doesn't help. Readability is far more important than saving lines of code.

@whatsisname is correct about some separating required and optional arguments but this is not required nor universal. For example:

function Window (options)
  -- check mandatory options
  if type(options.title) ~= "string" then
    error("no title")
  elseif type(options.width) ~= "number" then
    error("no width")
  elseif type(options.height) ~= "number" then
    error("no height")

  -- everything else is optional
          options.x or 0,    -- default value
          options.y or 0,    -- default value
          options.width, options.height,
          options.background or "white",   -- default
          options.border      -- default is false (nil)

See lua.org

One thing to be careful of: make every used member of the table something easy to spot. Don't bury one off somewhere weird where it's easy to miss. Another reason short functions are good.

  • This will probably be as descriptive as it will get. Thanks for your insight! Commented Dec 9, 2016 at 21:43

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.