Dincio
Dincio

Reputation: 1072

lua not modifying function arguments

I've been learning lua and can't seem to make a simple implementation of this binary tree work...

function createTree(tree, max)
    if max > 0 then
        tree = {data = max, left = {}, right = {}}
        createTree(tree.left, max - 1)
        createTree(tree.right, max - 1)
    end
end

function printTree(tree)
    if tree then
        print(tree.data)
        printTree(tree.left)
        printTree(tree.right)
    end
end

tree = {}
createTree(tree, 3)
printTree(tree)

the program just returns nil after execution. I've searched around the web to understand how argument passing works in lua (if it is by reference or by value) and found out that some types are passed by reference (like tables and functions) while others by value. Still, I made the global variable "tree" a table before passing it to the "createTree" function, and I even initialized "left" and "right" to be empty tables inside of "createTree" for the same purpose. What am I doing wrong?

Upvotes: 2

Views: 3882

Answers (3)

Dimitry
Dimitry

Reputation: 2348

It is safe to think that for the most of the cases lua passes arguments by value. But for any object other than a number (numbers aren't objects actually), the "value" is actually a pointer to the said object.

When you do something like a={1,2,3} or b="asda" the values on the right are allocated somewhere dynamically, and a and b only get addresses of those. Thus, when you pass a to the function fun(a), the pointer is copied to a new variable inside function, but the a itself is unaffected:

function fun(p)
   --p stores address of the same object, but `p` is not `a`
   p[1]=3--by using the address you can 
   p[4]=1--alter the contents of the object
   p[2]=nil--this will be seen outside

   q={}
   p={}--here you assign address of another object to the pointer
   p=q--(here too)
end

Functions are also represented by pointers to them, you can use debug library to tinker with function object (change upvalues for example), this may affect how function executes, but, once again, you can not change where external references are pointing.

Strings are immutable objects, you can pass them around, there is a library that does stuff to them, but all the functions in that library return new string. So once, again external variable b from b="asda" would not be affected if you tried to do something with "asda" string inside the function.

Upvotes: 2

Mike V.
Mike V.

Reputation: 2205

It is probably necessary to initialize not by a new table, but only to set its values.

function createTree(tree, max)
    if max > 0 then
        tree.data = max
        tree.left = {}
        tree.right = {}
        createTree(tree.left, max - 1)
        createTree(tree.right, max - 1)
    end
end

Upvotes: 6

lhf
lhf

Reputation: 72312

in Lua, arguments are passed by value. Assigning to an argument does not change the original variable.

Try this:

function createTree(max)
    if max == 0 then
        return nil
     else
        return {data = max, left = createTree(max-1), right = createTree(max-1)}
     end
end

Upvotes: 5

Related Questions