2

My question is regarding the below code snippet:

function add_node(list, v)
 list={next=list, val=v}
end

function print_linked_list(list)
 local l=list
 while l do
  print(l.val)
  l=l.next
 end
end

root=nil
root={next=root, val=0}
add_node(root, 1)
--root={next=root, val=2}
print_linked_list(root)

If I do the operation through the currently commented "root={nxt=root, val=1}" it works as expected. The print function will traverse the list and print both values. If I add a new node through the add_node function at the top of the script, which has essentially the same code in it, it'll only print the first created node.

Why is it that putting the operation in a function does not properly modify the list? The only thing I can think of is that the node created in add_node(list, v) is local only.

Finally, how can I get around this while keeping the code readable?

Colin
  • 23
  • 4

1 Answers1

2

The only thing I can think of is that the node created in add_node(list, v) is local only.

That's correct. Function parameters are implicitly local. All you need to do is return the value instead of assigning it:

function add_node(list, v)
  return {next=list, val=v}
end

And later:

root = add_node(root, 1)
luther
  • 5,195
  • 1
  • 14
  • 24
  • The thing that confused me is that although parameters are local, lists are a reference type. They're mutable from a function, right? So why can I modify list without returning, but can't add a new node? – Colin Feb 16 '18 at 06:11
  • @Colin - You are given a reference to a container, your reference is the same as invoker's reference (reference was copied). So, you can change everything inside this container. Or you can create another container. But you can't change reference owner by invoker: invoker's reference will remain pointing to the old container, you don't have access to invoker's variables, they are private. – Egor Skriptunoff Feb 16 '18 at 09:37
  • Because a new node is an entirely new table, not a modification of the old one. Semantically, you can think of all Lua values as references. Tables are special because you can mutate them (usually by assigning to an index *inside* it), but a variable that refers to a table is no different from one that refers to a number or string. When you assign directly to a variable, you lose the old reference. – luther Feb 16 '18 at 09:38
  • Oh! Ok, that makes a lot more sense. I think I've got it now. Thank you all! – Colin Feb 16 '18 at 23:48