# Scope ## Spot the Difference

``````x := 2
má x > 1 {
x = 3
scríobh(x)
}
scríobh(x)``````

Try it out now, were you right?

Now look at this program: there is a very small difference between it and the previous program. Think again about what it prints.

``````x := 2
má x > 1 {
x := 3
scríobh(x)
}
scríobh(x)``````

Try it out again:

Were you right?

The first program printed “3” and “3”, but the second program printed “3” and “2”. What is the difference between them?

Notice the third line in both programs:

• The first program: `x = 3`.
• The second program: `x := 3`.

As you know, `:=` creates a new variable and `=` puts a new value in some variable. This is the difference between the two programs.

### More Details

Lets look again at the first program:

``````x := 2
má x > 1 {
x = 3
scríobh(x)
}
scríobh(x)``````

The structure of this program is quite simple:

1. A variable `x := 2` is created on the first line.
2. The expression `x > 1` is true so the code in the `má` block is run.
3. The line `x = 3` changes the value of `x` to `3`.
4. The next line writes the variable `x`, which equals `3`, on the console.
5. Then the last line writes `x` again.

Now let’s look at the second program:

``````x := 2
má x > 1 {
x := 3
scríobh(x)
}
scríobh(x)``````
1. A variable `x := 2` is created on the first line.
2. The expression `x > 1` is true so the code in the `má` block is run.
3. A new variable `x := 3` is created.
4. Next the line `scríobh(x)` is run, but what does `x` mean here? We have two variables called `x`. When we ran the program earlier it printed “3”, so `x` must mean the second variable, the one that is defined in the `má` block.
5. `scríobh(x)` is the last line too, what does `x` mean here? If you run the program this line will print “2”: This `x` must mean the `x` on the first line.

What is happening here?

## What is Scope?

When you create a variable, what are the places in the program you can use that variable? We call these places the scope of the variable.

Generally, you can use a variable after you’ve created it, but there are some other details to be understood.

For example, look at this code:

``````scríobh("I live in")
country := "Ireland"
scríobh(country)``````

We can use the variable `country` on line 3 because line 3 comes after line 2. The following program is not correct because we cannot use the variable before we use it.

``````scríobh("I live in")
scríobh(country)
country := "Ireland"``````

Things get more complex when we use `má`, `le idir`, `nuair-a` and actions.

Look at this code:

``````má fíor {
x := 2
}
scríobh(x)``````

Is that code correct? It’s not; The scope of `x` is limited; When you create a variable in a block of code (code between `{` and `}`) you cannot use that variable from the outside. However, you can use it in any blocks that are nested in the block, like so:

``````má fíor {
x := 2
le i idir (0, 2) {
scríobh(x + i)
}
}``````

These rules apply to actions and outlines too. For example, think about this program, what does it write?

``````ainm := "Niamh"
gníomh dia_duit() {
scríobh("Dia duit", ainm)
}

dia_duit()

ainm = "Oisín"

dia_duit()

má 1 == 1 {
ainm := "Fionn"

dia_duit()
}``````

Try it out!

Were you correct? The line `ainm = "Oisín"` worked, but the line `ainm := "Fionn"` didn’t do anything. This happens because the `ainm` variable in the body of `dia_duit` is in the scope of the first variable `ainm`, and the line `ainm := "Fionn"` creates a different variable with a different scope: It has no effect.

In this picture each unique variable has a different colour, noticed that the second `ainm` variable isn’t used anywhere.

What happens when we create 2 variables with the same name? We saw this already in the program at the top of the page:

``````x := 2
má x > 1 {
x := 3
scríobh(x)
}
scríobh(x)``````

The 4th line (`scríobh(x)`) looks like it’s in the scope of both `x` variables; The one on the first line and the one on the third line. In this case it uses the closest one (the innermost one).

It’s as if the second variable hides the first one in its scope. We call this effect “shadowing”. When we create a new variable and we use a name that is already in use by another variable, we can no longer see the old variable anymore.

However: in general it is bad practice to create a variable that hides another variable. You should use a unique name for each variable: Things get confusing when you shadow a variable with another variable.

NB: You cannot create a new variable with a name that is already in use in the same block. For example, the following code does not work:

## Recursion

An action can call itself, we call this process recursion. For example, here is a program that writes “10”, “9”, “8” down to “1” on the console.

When `write_number(10)` is called, it writes “10” on the console, it then checks if `10` is greater than `1`, which of course it is so it calls `write_number(9)`. This writes “9” and then calls `write_number(8)`, then that calls `write_number(7)`, `write_number(6)` until it reaches `write_number(1)`. At that point `x > 1` is not true anymore so it stops.

If a variable is created in the action, a unique version of this variable is created every time the action is called. Specifically, when an action calls itself the different calls do not share their variables. Look at this program:

When we call `f(2)` it creates a new variable `y` that is equal to `2`. Then it checks if `x > 1` which it is. Then it calls `f(1)`. A new variable is created call `y` that is equal to `1`, this variable is different from the variable `y` we created earlier. `1` is not greater than `1` so we do not call `f(0)`. Instead we write `y` on the console, which writes “1”. Now we go back to the previous call `f(2)` and we continue on. `scríobh(y)` is the next line, but `y` is not equal to `1` here, it’s equal to `2` because this refers to the first `y` we created, not the second. This then writes “2” on the console.

## The Global Scope

Setanta has one special scope, the global scope. A variable has a global scope if it is defined at the top level of the program: the block at the top of the program. For example, `x`, `mo_ghníomh` and `MoChreatlach` in the following program have global scope. However, the variable `áitiúil` does not.

``````creatlach MoChreatlach {
gníomh ainm() {
scríobh("Setanta")
}
}

gníomh mo_ghníomh() {
áitiúil := "Dia duit"
}

x := 3``````

Global variables are special, because we can use them before we create them when we use them in an action. Lets look at some examples:

This code works: Try it out!

Code like this only works in the global scope, for example, code like this does not work. If you run it you will get an error:

We can use this to create two actions like this: This pair of actions is a bit strange, they do work but it is worth explaining how.

``````gníomh number_is_even(x) {
má x == 0 {
}
toradh number_is_odd(x - 1)
}

gníomh number_is_odd(x) {
má x == 0 {
The action `number_is_odd` calls `number_is_even` and the action `number_is_even` calls `number_is_odd`. This works because `number_is_even` can reference `number_is_odd` even though it isn’t defined yet.