luaguides

print()

print(...)

print() is Lua’s built-in function for writing values to standard output. It converts each argument to a string, joins them with tab characters, and appends a newline. It is the most direct way to inspect values during development — no imports, no libraries, no configuration required.

Signature

print(...)

The ... means it accepts any number of arguments, including none.

Return Value

print() always returns nil.

Basic Usage

print("Hello, world!")       -- Hello, world!

print(42)                    -- 42

print(true, false, nil)      -- true   false   nil

With no arguments, print() outputs a blank line:

print()                      -- (blank line)

Multiple Arguments

Arguments are separated by a single tab character (\t):

name = "Alice"
age = 32
print("Name:", name, "Age:", age)
-- Name:	Alice	Age:	32

Lua’s print converts values to strings using its own internal conversion rules:

  • Strings: printed as-is
  • Numbers: converted to their decimal representation
  • Booleans: "true" or "false"
  • nil: printed as the word "nil"
  • Tables: printed as "table: 0x..." (memory address — not recursively expanded)

Converting to String Explicitly

For more control over formatting, use tostring():

value = 3.14159
print(tostring(value))                    -- 3.14159
print(string.format("%.2f", value))        -- 3.14

-- tostring on a table gives the same address-style output
print(tostring({a = 1}))                   -- table: 0x7f8a3c402890

tostring() is called implicitly by print() on each argument, so print(x) and print(tostring(x)) produce identical output — except that tostring() can be customised by defining the __tostring metamethod on a table.

Customising Table Output with __tostring

Define the __tostring metamethod to control how a table is printed:

Point = {}
Point.__index = Point

function Point.new(x, y)
    return setmetatable({x = x, y = y}, Point)
end

function Point:__tostring()
    return string.format("Point(%.1f, %.1f)", self.x, self.y)
end

p = Point.new(2.5, 4.0)
print(p)            -- Point(2.5, 4.0)

Without __tostring, print(p) would output something like table: 0x7f8a3c402890.

Inspecting Variables with print

print() is most useful during development for quick checks:

function divide(a, b)
    print("divide called with", a, b)
    if b == 0 then
        print("ERROR: division by zero")
        return nil
    end
    print("result:", a / b)
    return a / b
end

divide(10, 2)
-- divide called with	10	2
-- result:	5

Limitations

print() is not suitable for production output:

  • No formatting control — tabs and newline are fixed
  • No file output — always writes to stdout
  • No structured data — tables print as addresses
  • Not thread-safe in coroutine-heavy programs (output can interleave)

For formatted output, use string.format(). For file output, use io.write() or file:write().

io.write as an Alternative

io.write() is similar to print() but offers more control:

io.write("Count: ")    -- no newline
io.write(42, "\n")    -- with newline

-- Formatted output
io.write(string.format("Pi to 3 decimals: %.3f\n", math.pi))

Key differences from print():

  • io.write() does not add a newline automatically
  • io.write() does not add tab separators between arguments
  • io.write() returns nil on error (like most io functions), not the values

See Also