Skip to main content

Scopes in Julia

Julia is a high-level general-purpose dynamic programming language intended to address the needs of high-performance numerical analysis and computational science, without the need of separate compilation to be fast.

Scopes

The region in a program where a variable is known is called the scope of the variable. A variable which can be accessed from anywhere in the program is called a top-level or global scope. A variable defined in a local scope can only be accessible from that scope.

Global and local scopes

Let's look at an example:

   # global scope
   x = 1
   # local scope
   function scopes()
       println(x) # x is a global scope and accessible
       y = 1.0    # y is local to the function scopes
   end

Asking the julia shell to print the value of y results in an error, since it is defined in a local scope inside the function scopes and not as a global variable like x.

  julia> println(y)

  ERROR: UndefVarError: y not defined
  Stacktrace:
  [1] top-level scope at none:0

for, while, try, or let

In Julia, any variable defined in a for, while, try or let block will be local unless it is used by an enclosing scope before the block.

   # example on for, while, try or let blocks
   y = 3
   for i = 1:10 #for loop is similar to the while loop
       y = i + 3
       if y == 6 #local variable inside a for-scope
	   println("The value of local y: $(y)")
       end
   end

However, global variables are not accessible in for and while loops as can be seen in the example below and results in a ERROR: UndefVarError: y not defined

   # inaccessible global variables in for and while loops
   y = 3
   while y < 10 #while-loop
       y += 1
       if y == 5
	   println("The value of local y: $(y)")
       end
   end

let blocks

To create a new local binding for a variable use the let block

    ## without let block in a for loop
    anon = Array{Any}(undef, 2)
    for i = 1:2
	anon[i] = () -> println(i)
	i += 1
    end
    # anon function is called in julia to get

    julia> anon[1]()
    2

    julia> anon[2]()
    3
    ## using let block for i values to stick
    anon = Array(Any)(undef, 2)
    for i = 1:2
	let i = i
	    anon[i] = () -> println(i)
	end
	i += 1
    end
    # anon function is called in julia to now get
    julia> anon[1]()
    1

    julia> anon[2]()
    2

global and local prefix

The prefix keywords global and local can be used to decide which one you want to use if variables with same name in different scopes exist. Although, this is not a good practice as it would be harder to keep track even if Julia provides a neat way to implement such instances. A little example:

   x = 9
   function funscope(n)
       x = 0 # x is in the local scope of the function
       for i = 1:n
	   local x # x is local to the for loop
	   x = i + 1
	   if (x == 7)
	       println("This is the local x in for: $x") #> 7
	   end
       end
       println("This is the local x in funscope: $x") #> 0
       global x = 15
   end

Compound expressions begin…end, and conditionals if..elseif..else..end, do not introduce a local scope.

Using global scope variables should be minimized as it has an effect on the performance of the program and restricting the scope of a variable is better.

Comments