Skip to content

utilities for "soft" global scope in interactive Julia environments

License

Notifications You must be signed in to change notification settings

JuliaLang/SoftGlobalScope.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SoftGlobalScope

CI

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.

In Julia 1.5, "soft scoping" became the default for the built-in Julia REPL, and the SoftGlobalScope module simply calls through to the standard-library REPL.softscope function. The advantage of using the SoftGlobalScope library is that it also works with previous Julia versions.

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 and was ultimately reverted. 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. In Julia 1.5, softscope_include_string(m, x) is equivalent to include_string(REPL.softscope, m, x) using the softscope transformation function provided by Julia's REPL standard library.

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.

About

utilities for "soft" global scope in interactive Julia environments

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Languages