utilities for "soft" global scope in interactive Julia environments
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

SoftGlobalScope

Build Status

SoftGlobalScope is a package for the Julia language that simplifies the variable scoping rules for code in global scope. It is intended for interactive shells (the REPL, IJulia, etcetera) to make it easier to work interactively with Julia, especially for beginners.

In particular, SoftGlobalScope provides a function softscope that can transform Julia code from using the default "hard" scoping rules to simpler "soft" scoping rules in global scope only.

Hard and soft global scopes

Starting in Julia 0.7, when you assign to global variables in the context of an inner scope (a for loop or a let statement) you need to explicitly declare the variable as global in order to distinguish it from declaring a new variable. We refer to this as "hard" scoping rules. For example, the following code gives an warning in 0.7:

julia> s = 0
0

julia> for i = 1:10
           s = s + i
       end
┌ Warning: Deprecated syntax `implicit assignment to global variable `s``.
└ Use `global s` instead.

and an error in Julia 1.0:

julia> s = 0
0

julia> for i = 1:10
           s = s + i   # wrong: defines a new local variable s
       end
ERROR: UndefVarError: s not defined

To make it work in 1.0, you need a global declaration:

julia> for i = 1:10
           global s = s + i
       end

julia> s      # should be 1 + 2 + ⋯ + 10 = 55
55

This only applies to global variables; similar code inside a function (or whenever s is a local variable) works fine without any added keyword:

julia> function f(n)
           s = 0
           for i = 1:n
               s = s + i
           end
           return s
       end
f (generic function with 1 method)

julia> f(10)
55

There were various reasons for this scoping rule, e.g. to facilitate static analysis by the compiler, and it isn't too onerous in "serious" Julia code where little code executes in global scope.

However, for interactive use, especially for new users, the necessity of the global keyword, and the difference between code in local and global scopes, can be confusing. The SoftGlobalScope package exists to make it easier for interactive shells to automatically insert the global keyword in common cases, what we term "soft" global scope.

Usage

The SoftGlobalScope module exports two functions softscope and softscope_include_string, and a macro @softscope:

You can transform the expression using softscope(module, expression) to automatically insert the necessary global keyword. For example, assuming that the module Main has a global variable s (as above), you can do:

julia> softscope(Main, :(for i = 1:10
           s += i
       end))
:(for i = 1:10
      #= REPL[3]:2 =#
      global s += i
  end)

You can then execute the statement with eval. Alternatively, you can decorate the expression with the @softscope macro:

julia> s = 0;

julia> @softscope for i = 1:10
           s += i
       end

julia> s
55

This macro should only be used in the global scope (e.g., via the REPL); using this macro within a function is likely to lead to unintended consequences.

You can execute an entire sequence of statements using "soft" global scoping rules via softscope_include_string(module, string, filename="string"):

julia> softscope_include_string(Main, """
       s = 0
       for i = 1:10
           s += i
       end
       s
       """)
55

(This function works like include_string, returning the value of the last evaluated expression.)

In Julia 0.6, no code transformations are required, so softscope returns the original expression and softscope_include_string is equivalent to include_string.

Contact

SoftGlobalScope was written by Steven G. Johnson and is free/open-source software under the MIT/Expat license. Please file bug reports and feature requests at the SoftGlobalScope github page.