0

I have been looking at some Lua code recently and multiple times the author assigns a local variable, altering the local variable seemingly with the expected outcome of also altering the assigning variable as he does not do anything with the local variable after. Is this the case or do these changes not affect the original values.

Gene Construct

local gene = {}
gene.into = 0
gene.out = 0
gene.weight = 0.0
gene.enabled = true
gene.innovation = 0`

Code

function nodeMutate(genome)
if #genome.genes == 0 then
    return
end

genome.maxneuron = genome.maxneuron + 1

local gene = genome.genes[math.random(1,#genome.genes)]
if not gene.enabled then
    return
end
gene.enabled = false

local gene1 = copyGene(gene)
gene1.out = genome.maxneuron
gene1.weight = 1.0
gene1.innovation = newInnovation()
gene1.enabled = true
table.insert(genome.genes, gene1)

local gene2 = copyGene(gene)
gene2.into = genome.maxneuron
gene2.innovation = newInnovation()
gene2.enabled = true
table.insert(genome.genes, gene2)
end
7
  • your question cannot be answered without knowing in which scope relation those two code segments are. also your senteces are quite confusing: "the author assigns a local variable, altering the local variable seemingly with the expected outcome of also altering the assigning variable" whaaat?? Commented Apr 20, 2017 at 13:28
  • I'm sorry it's confusing, I'm having a hard time explaining it. The author seems to assign values to local variables, then edit these local variables without then assigning these local variables, as if these local variables are acting as pointers and changes made to the local variable will affect the variable that was assigned to the local variable. The code example I gave is from a function, where he assigned a local variable gene, then edits a value within gene. The function then ends, with no other processing on the local variable gene. Commented Apr 20, 2017 at 13:30
  • paste the entire function so we don't have to guess. without context your code does not make much sense. some values are copied by reference in Lua. assuming that the section you name "gegen construct" is creating a local variable that is then put into table genome.genes you can then later of course alter that gene's values by using a reference like in your "Code" section. Please read lua.org/manual/5.3 befor you continue Commented Apr 20, 2017 at 13:48
  • I've added the whole function, the purpose of the function should include changing the assigning gene's enabled to false but he only does this on the local variable, not the original. Commented Apr 20, 2017 at 14:14
  • 1
    without knowing what copyGene does (no code provided) this cannot be answered. but the name suggests that the function returns a copy of the provided gene. Therefor changes to gene1 or gene2 should not affect gene. But that's not 100% sure without having seen copyGenes implementation. Commented Apr 20, 2017 at 14:20

2 Answers 2

3

Changes to gene may affect genome.genes[math.random(1,#genome.genes)] because gene is a reference. From the Lua Manual - Values and Types:

Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.

This means that when you assign a variable to an object you copy the reference to that object, not the object itself.

For example:

local a = {1,2,3}
local b = a
b[1] = 'a'

The table a now contains {'a',2,3} because b is a reference to a.

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

3 Comments

@AlexL but you realize that he wrote "may" affect? The name copyGene suggetst that it is not a reference...
@AlexL gene is a reference to genome.genes, but as @Piglet points out gene1 and gene2 most likely are copies. If you want to know for sure print(tostring(gene), tostring(gene1), tostring(gene2)) if they are different memory addresses they are different objects.
to correct my comment it is a reference of course, but not necessarily a reference to gene :)
0

From my reading of the code I'd think the following:

local gene1 = copyGene(gene)  -- local copy, distinct from original 'gene'
-- (modifications of 'gene1')
table.insert(genome.genes, gene1) -- add modified copy to 'genome.genes'

So I'd guess that copyGene produces a copy of gene, meaning that gene isn't modified (only gene1, gene2). References to these are held in local variables and these references indeed go out of scope at the end of the block. But the modified copy is added to the list (/ array / sequence, whatever you want to call it) genome.genes which does produce an externally visible effect (because that variable – genome – comes in from outside).

My higher-level impression of the code is that genome.genes is a list of genes that may or may not be enabled. Each run through this function randomly picks one of these genes and if it is enabled, (1) disables it and (2) adds two modified enabled copies to the genome.genes (which may then be the base for new copies in later runs).

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.