global scope in Julia - julia

I have a piece of code in Julia here:
i = 1
while true
if i == 10
break
end
global i += 1 #A
for k = 1:1
println(i) #B
end
end
println(i)
My question is why global i += 1 #A is required inside while loop, but println(i) #B inside the for loop is not requiring any global declaration?
Is global declaration required only for the modification of variables? The if i == 10 statement after the while declaration is using the global scope.

In Julia, loop bodies introduce local scopes the same as function bodies. If you assign to a variable that isn’t already a local or explicitly declared to be global, then it is, by default, a new local variable. Combining those two facts implies that assigning to i inside of the loop causes it to be a new local. On the other hand, if you don’t assign to it and only access it then it must be a variable from some outer scope, local or global, but in this case global.
Regarding the second question: a variable in a given scope can only have one meaning—it’s either local or global. It can’t be local in one part of the loop body and global in a different part (unless there’s an inner nested scope, but then that’s a different scope region). If it’s declared global anywhere, it’s global everywhere both before and after that declaration. If it’s local then it’s local everywhere.

Related

Julia v1.6 update seems to have changed the rules for overwriting existing global variable in soft local scope

I've just updated Julia to v1.6.3 from v1.5.0 in Atom, and I'm running Julia in some script.jl file (I'm using shift+enter to run the highlighted code). According to Julia's documentation, for both two versions,
Julia Doc (v1.5.0 and v1.6.3)
So (if I understand the doc correctly) if you already have a global variable named x, and if you try to assign value to variable x in a for loop (which creates a soft scope) in non-interactive context, Julia will create another local variable x and the original global variable x would not be modified.
But I noticed same lines of code yield different outcomes in v1.5.0 and v1.6.3, the lines of code are as follows:
x = 0
for i = 1:10
x += 10
end
In v1.5.0, it would give me error saying "UndefVarError: x not defined", which makes sense since in the soft scope (within for loop), it would create a new local variable x, but we didn't assign value to this new local variable. But in v1.6.3, the code works out fine and x got change in global scope as well. I'm guessing instead of creating a new local variable x, it uses the global variable x and assigns value to that.
But I'm still not sure exactly what happened here, does this mean in v1.6.3 (and perhaps onwards), in a soft scope, we can directly use variable that is created in global scope and change its value without even yielding any warning? This change seems to me would cause more room for ambiguity.

I'm getting the following error: "top-level scope at ./REPL[1]:4" when I run my julia program

So here's the code I was trying to execute in Julia:
i = begin
i = 5
while(i<=10)
println(i)
i+=1
end
end
It's just basically a simple code to print the value of i from 5 to 10 but it's messing with me
Are you in the REPL? What you are probably running into is that begin does not introduce its own scope, so i = 5 declares i as a global variable. Because while does introduce its own scope, if you do println(i), it only looks for i in its local scope where it is not defined, because i exists only as a global variable. You can add a line global i at the beginning of the body of the while loop to tell all code after that to use the global i, but note that global variables come with their own performance caveats. An arguably better solution would be to use let instead of begin, which does introduce a new scope, but note that then you can of course not access i afterwards, because it is now only local to the let block.
This behavior will actually be changed in the upcoming release of Julia 1.5, so your code should then just work.
Your issue is scope. When you enter into a loop, variables created inside the loop are local to the loop and destroyed after it exits. i is not currently defined inside your while loop, so you get the error. The quick fix is to tell Julia you want the loop to have access to the global i variable you defined at the top by adding global i immediately after the while statement. You also don't need the begin block, and naming the block i is immediately overwritten by the next statement defining i.

Auto assignment

Recently I have been working with a set of R scripts that I inherited from a colleague. It is for me a trusted source but more than once I found in his code auto-assignments like
x <<- x
Is there any scope where such an operation could make sense?
This is a mechanism for copying a value defined within a function into the global environment (or at least, somewhere within the stack of parent of environments): from ?"<<-"
The operators ‘<<-’ and ‘->>’ are normally only used in functions,
and cause a search to be made through parent environments for an
existing definition of the variable being assigned. If such a
variable is found (and its binding is not locked) then its value
is redefined, otherwise assignment takes place in the global
environment.
I don't think it's particularly good practice (R is a mostly-functional language, and it's generally better to avoid function side effects), but it does do something. (#Roland points out in comments and #BrianO'Donnell in his answer [quoting Thomas Lumley] that using <<- is good practice if you're using it to modify a function closure, as in demo(scoping). In my experience it is more often misused to construct global variables than to work cleanly with function closures.)
Consider this example, starting in an empty/clean environment:
f <- function() {
x <- 1 ## assignment
x <<- x ## global assignment
}
Before we call f():
x
## Error: object 'x' not found
Now call f() and try again:
f()
x
## [1] 1
<<-
is a global assignment operator and I would imagine there should hardly ever be a reason to use it because it effectively causes side effects.
The scope to use it would be in any case when one wants to define a global variable or a variable one level up from current environment.
Alan gives a good answer: Use the superassignment operator <<- to write upstairs.
Hadley also gives a good answer: How do you use "<<-" (scoping assignment) in R?.
For details on the 'superassignment' operator see Scope.
Here is some critical information on the operator from the section on Assignment Operators in the R manual:
"The operators <<- and ->> are normally only used in functions, and cause a search to be made through parent environments for an existing definition of the variable being assigned. If such a variable is found (and its binding is not locked) then its value is redefined, otherwise assignment takes place in the global environment."
Thomas Lumley sums it up nicely: "The good use of superassignment is in conjuction with lexical scope, where an environment stores state for a function or set of functions that modify the state by using superassignment."
For example:
x <- NA
test <- function(x) {
x <<- x
}
> test(5)
> x
#[1] 5
That's a simple use here, <<- will do a parent environment search (case of nested functions declarations) and if not found assign in the global environment.
Usually this is a really bad ideaTM as you have no real control on where the variable will be assigned and you have chances it will overwrite a variable used for another purpose somewhere.

Julia: local in module scope

When generating a not explicitly generated version of a function, #ngenerate runs
eval(quote
local _F_
$localfunc # Definition of _F_ for the requested value of N
_F_
end)
Since eval runs in the scope of the current module, not the function, I wonder what is the effect of local in this context. As far as I know, the languange documentation only mentions the use of local inside function definitions.
To give some background why this question arose: I frequently need to code loops of the form
function foo(n::Int)
s::Int = 0
for i in 1:1000000000
for j in 1:n
s += 1
end
end
return s
end
where n <= 10 (of course, in my actual code the loops are such that they cannot just be reduced to O(1)). Because this code is very simple for the compiler but demanding at runtime, it turns out to be beneficial to simply recompile the loops with the required value of n each time foo is called.
function clever_foo(n::Int)
eval(quote
function clever_foo_impl()
s::Int = 0
for i in 1:1000000000
s += $(Expr(:call,:+,[1 for j in 1:n]...))
end
return s
end
end)
return clever_foo_impl()
end
However, I am not sure whether I am doing this the right way.
It's to prevent _F_ from being visible in the global method cache.
If you'll call clever_foo with the same n repeatedly, you can do even better by saving the compiled function in a Dict. That way you don't have to recompile it each time.

What is the exact definition of a closure?

I've read through previous topics on closures on stackflow and other sources and one thing is still confusing me. From what I've been able to piece together technically a closure is simply the set of data containing the code of a function and the value of bound variables in that function.
In other words technically the following C function should be a closure from my understanding:
int count()
{
static int x = 0;
return x++;
}
Yet everything I read seems to imply closures must somehow involve passing functions as first class objects. In addition it usually seems to be implied that closures are not part of procedural programming. Is this a case of a solution being overly associated with the problem it solves or am I misunderstanding the exact definition?
No, that's not a closure. Your example is simply a function that returns the result of incrementing a static variable.
Here's how a closure would work:
function makeCounter( int x )
{
return int counter() {
return x++;
}
}
c = makeCounter( 3 );
printf( "%d" c() ); => 4
printf( "%d" c() ); => 5
d = makeCounter( 0 );
printf( "%d" d() ); => 1
printf( "%d" c() ); => 6
In other words, different invocations of makeCounter() produce different functions with their own binding of variables in their lexical environment that they have "closed over".
Edit: I think examples like this make closures easier to understand than definitions, but if you want a definition I'd say, "A closure is a combination of a function and an environment. The environment contains the variables that are defined in the function as well as those that are visible to the function when it was created. These variables must remain available to the function as long as the function exists."
For the exact definition, I suggest looking at its Wikipedia entry. It's especially good. I just want to clarify it with an example.
Assume this C# code snippet (that's supposed to perform an AND search in a list):
List<string> list = new List<string> { "hello world", "goodbye world" };
IEnumerable<string> filteredList = list;
var keywords = new [] { "hello", "world" };
foreach (var keyword in keywords)
filteredList = filteredList.Where(item => item.Contains(keyword));
foreach (var s in filteredList) // closure is called here
Console.WriteLine(s);
It's a common pitfall in C# to do something like that. If you look at the lambda expression inside Where, you'll see that it defines a function that it's behavior depends on the value of a variable at its definition site. It's like passing a variable itself to the function, rather than the value of that variable. Effectively, when this closure is called, it retrieves the value of keyword variable at that time. The result of this sample is very interesting. It prints out both "hello world" and "goodbye world", which is not what we wanted. What happened? As I said above, the function we declared with the lambda expression is a closure over keyword variable so this is what happens:
filteredList = filteredList.Where(item => item.Contains(keyword))
.Where(item => item.Contains(keyword));
and at the time of closure execution, keyword has the value "world," so we're basically filtering the list a couple times with the same keyword. The solution is:
foreach (var keyword in keywords) {
var temporaryVariable = keyword;
filteredList = filteredList.Where(item => item.Contains(temporaryVariable));
}
Since temporaryVariable is scoped to the body of the foreach loop, in every iteration, it is a different variable. In effect, each closure will bind to a distinct variable (those are different instances of temporaryVariable at each iteration). This time, it'll give the correct results ("hello world"):
filteredList = filteredList.Where(item => item.Contains(temporaryVariable_1))
.Where(item => item.Contains(temporaryVariable_2));
in which temporaryVariable_1 has the value of "hello" and temporaryVariable_2 has the value "world" at the time of closure execution.
Note that the closures have caused an extension to the lifetime of variables (their life were supposed to end after each iteration of the loop). This is also an important side effect of closures.
From what I understand a closure also has to have access to the variables in the calling context. Closures are usually associated with functional programming. Languages can have elements from different types of programming perspectives, functional, procedural, imperative, declarative, etc. They get their name from being closed over a specified context. They may also have lexical binding in that they can reference the specified context with the same names that are used in that context. Your example has no reference to any other context but a global static one.
From Wikipedia
A closure closes over the free variables (variables which are not local variables)
A closure is an implementation technique for representing procedures/functions with local state. One way to implement closures is described in SICP. I will present the gist of it, anyway.
All expressions, including functions are evaluated in an environement, An environment is a sequence of frames. A frame maps variable names to values. Each frame also has a
pointer to it's enclosing environment. A function is evaluated in a new environment with a frame containing bindings for it's arguments. Now let us look at the following interesting scenario. Imagine that we have a function called accumulator, which when evaluated, will return another function:
// This is some C like language that has first class functions and closures.
function accumulator(counter) {
return (function() { return ++counter; });
}
What will happen when we evaluate the following line?
accum1 = accumulator(0);
First a new environment is created and an integer object (for counter) is bound to 0 in it's first frame. The returned value, which is a new function, is bound in the global environment. Usually the new environment will be garbage collected once the function
evaluation is over. Here that will not happen. accum1 is holding a reference to it, as it needs access to the variable counter. When accum1 is called, it will increment the value of counter in the referenced environment. Now we can call accum1 a function with local state or a closure.
I have described a few practical uses of closures at my blog
http://vijaymathew.wordpress.com. (See the posts "Dangerous designs" and "On Message-Passing").
There's a lot of answers already, but I'll add another one anyone...
Closures aren't unique to functional languages. They occur in Pascal (and family), for instance, which has nested procedures. Standard C doesn't have them (yet), but IIRC there is a GCC extension.
The basic issue is that a nested procedure may refer to variables defined in it's parent. Furthermore, the parent may return a reference to the nested procedure to its caller.
The nested procedure still refers to variables that were local to the parent - specifically to the values those variables had when the line making the function-reference was executed - even though those variables no longer exist as the parent has exited.
The issue even occurs if the procedure is never returned from the parent - different references to the nested procedure constructed at different times may be using different past values of the same variables.
The resolution to this is that when the nested function is referenced, it is packaged up in a "closure" containing the variable values it needs for later.
A Python lambda is a simple functional-style example...
def parent () :
a = "hello"
return (lamda : a)
funcref = parent ()
print funcref ()
My Pythons a bit rusty, but I think that's right. The point is that the nested function (the lambda) is still referring to the value of the local variable a even though parent has exited when it is called. The function needs somewhere to preserve that value until it's needed, and that place is called a closure.
A closure is a bit like an implicit set of parameters.
Great question! Given that one of the OOP principles of OOP is that objects has behavior as well as data, closures are a special type of object because their most important purpose is their behavior. That said, what do I mean when I talk about their "behavior?"
(A lot of this is drawn from "Groovy in Action" by Dierk Konig, which is an awesome book)
On the simplest level a close is really just some code that's wrapped up to become an androgynous object/method. It's a method because it can take params and return a value, but it's also an object in that you can pass around a reference to it.
In the words of Dierk, imagine an envelope that has a piece of paper inside. A typical object would have variables and their values written on this paper, but a closure would have a list of instructions instead. Let's say the letter says to "Give this envelope and letter to your friends."
In Groovy: Closure envelope = { person -> new Letter(person).send() }
addressBookOfFriends.each (envelope)
The closure object here is the value of the envelope variable and it's use is that it's a param to the each method.
Some details:
Scope: The scope of a closure is the data and members that can be accessed within it.
Returning from a closure: Closures often use a callback mechanism to execute and return from itself.
Arguments: If the closure needs to take only 1 param, Groovy and other langs provide a default name: "it", to make coding quicker.
So for example in our previous example:
addressBookOfFriends.each (envelope)
is the same as:
addressBookOfFriends.each { new Letter(it).send() }
Hope this is what you're looking for!
An object is state plus function.
A closure, is function plus state.
function f is a closure when it closes over (captured) x
I think Peter Eddy has it right, but the example could be made more interesting. You could define two functions which close over a local variable, increment & decrement. The counter would be shared between that pair of functions, and unique to them. If you define a new pair of increment/decrement functions, they would be sharing a different counter.
Also, you don't need to pass in that initial value of x, you could let it default to zero inside the function block. That would make it clearer that it's using a value which you no longer have normal access to otherwise.

Resources