This is a feature request proposal Brain Storming
The proposal (initially)
- add construct
global let
to julia
global let
...
end
- Scripts (without) module declaration should assume being inside a
global let
- add
our
andmy
as synonym toglobal
andlocal
Inside a global let all variables and functions are global by default,
unless explicitly declared local
What does this fix and how does it help
- allow local variables in a file (file scope)
- make it easier to use the repl
- bridge or eliminate the gap between file scope and repl scope
- promote variable declaration before use (variable autovivification considered harmful)
I will explain below how this is this case
first some quirks
Currently this code below generate an error inside a file raise an error and a warning
s = 0
for i = 1:10
t = s + i
s = t
println("$s")
end
println("$s")
┌ Warning: Assignment to `s` in soft scope is ...
ERROR: LoadError: UndefVarError: s not defined
this code still raise an error
local s = 0
for i = 1:10
t = s + i
s = t
println("$s")
end
println("$s")
ERROR: LoadError: UndefVarError: s not defined
and this code still an error
global s = 0
for i = 1:10
t = s + i
s = t
println("$s")
end
println("$s")
┌ Warning: Assignment to `s` in soft scope is ...
ERROR: LoadError: UndefVarError: s not defined
Now put the code inside a let, and the problem is solved
let
global s = 0
for i = 1:10
t = s + i
s = t
println("$s")
end
println("$s")
end
And s
is global and available for me outside the let
all 3 variations will work, the difference is the visibility of s
outside the let
I understand that the Julia way to fix this was to add global or local next to the first use of s inside the loop
and if I want s to be local that would not be so bad, but for a global s
this is very counter intuitive
Mimicking file scope
Example
# file one.jl
let
global x =1
local y = 2
local function addx( a )
println( x + a)
end
global function addy( a )
println(y + a)
end
addy(3)
addx(3)
end
#file two.jl
include("one.jl")
println(x)
addy(10)
#println(y) #raise error
#addx(10) #raise error
If we have global let file one.jl would look like
# file one.jl
global let
x =1
local y = 2
local function addx( a )
println( x + a)
end
function addy( a )
println(y + a)
end
addy(3)
addx(3)
end
And would work just the same
Also if global let
becomes implicit, file one.jl could look like this and still work just the same, allowing local variables that are file scoped
# file one.jl
x =1
local y = 2
local function addx( a )
println( x + a)
end
function addy( a )
println(y + a)
end
addy(3)
addx(3)
The case for my
and our
my and our are much shorter than global and local,will make the code look nicer and might motivate more developers to declare that variable scope before use
# file one.jl
x =1
my y = 2
my function addx( a )
println( x + a)
end
function addy( a )
println(y + a)
end
addy(3)
addx(3)
or
# file one.jl
our let
x =1
my y = 2
my function addx( a )
println( x + a)
end
function addy( a )
println(y + a)
end
addy(3)
addx(3)
end
Show stoppers
module
must be declared at the top level and cannot be declared inside a let , I am not sure what the impact of allowing module
declaration inside let
s would be, and this is a big problem
But if making global lets implicit is impossible for some reason I could not preview, I still think that having the syntax variation of global let
, my
and our
is still worth it
our let
my y = 1
addy(a)
a + y
end
...
end
vs
let
y = 1
global addy(a)
a + y
end
...
end
Anyway, hope to get some feedback, do you think global lets is a good idea, does it have a chance?