When I ran the Julia code below, there was an error: UndefVarError: globalValue not defined.
I thought that the globalValue is a global variable, but it is not. Thus, if I add the command "global globalValue" inside the for loop, my code will work. So, could anyone please have a look at it let me know what happened? Thanks in advance!
globalValue = 1.0;
tempValue = 0.1;
for ii = 1:10
# global globalValue; if I add this command, my code will work
tempValue = 5.0; ## I have a function to update "tempValue"
if globalValue < tempValue
globalValue = tempValue;
end
end
It seems you are on Julia >= 0.7, where the scoping rules have changed.
Long story short, in a local scope, such as your for-loop, global variables are only inherited for reading but not for writing. There are two ways around it:
put an explicit global in front of the assignment (what you figured out yourself)
wrap everything in a "global local scope" like let ... end block (globalValue isn't really a global variable anymore)
In your case, the second option would look like
let
globalValue = 1.0;
tempValue = 0.1;
for ii = 1:10
tempValue = 5.0;## I have a function to update "tempValue"
if globalValue < tempValue
globalValue = tempValue;
end
end
end
You can find more information here:
https://discourse.julialang.org/t/repl-and-for-loops-scope-behavior-change/ (in particular this post by Stefan, who is one of the authors of Julia
https://docs.julialang.org/en/stable/manual/variables-and-scoping/#scope-of-variables-1
Although I find this a bit annoying myself, there are good reasons for why the change has been made. Also, on should try to avoid changing globals anyway. Let me quote the manual here (see link above):
Avoiding changing the value of global variables is considered by many
to be a programming best-practice. One reason for this is that
remotely changing the state of global variables in other modules
should be done with care as it makes the local behavior of the program
hard to reason about. This is why the scope blocks that introduce
local scope require the global keyword to declare the intent to modify
a global variable.
Related
for j in 1:10
δ= y[j,:]
diff_prob = ODEProblem(Proteo_Deg, u0,t_span,δ)
diff_sol = solve(diff_prob)
end
A for loop creates a local scope, and so new variables that you introduce in a loop only exist within that loop.
A common way around this is to initialize the variable before the loop. (Outside of the REPL, you generally want to avoid global variables, so for eg. if this is in a script file, place both the initialization and then the loop within a function.) One thing to consider is what your goal with the loop is. Currently, you're computing 10 ODE solutions, but then throwing them out because they're all assigned to the same variable diff_sol. Maybe you want to save them in an array?
diff_solutions = Array{ODESolution}(undef, 10)
for j in 1:10
δ = y[j,:]
diff_prob = ODEProblem(Proteo_Deg, u0,t_span,δ)
diff_solutions[j] = solve(diff_prob)
end
Now, diff_solutions contains all 10 ODE solutions and is available to access outside of the loop too. If this is in a function, you can then return diff_solutions after the loop.
In SML,if I am correct, variables are immutable by default. So when we try to redefine a variable
val y = 100;
val y = 0.6;
y
the environment will have two entries for y. The new entry hides the original entry.
Isn't it the same effect as if we modified the value in the original entry from 100 to 0.6?
If the original entry was created outside a function call, and the new entry was created in a function call, then when the function call returns, we can access the original entry.
If both entries were created in the same "scope", like the example above, is the original entry not accessible?
Effectively, isn't it the same in SML as in an imperative language such as C? What is the point of making a variable immutable in SML and creating a new entry when redefining a variable?
Thanks.
Isn't it the same effect as if we modified the value in the original entry from 100 to 0.6
No. Consider code that references the previous environment through use of a closure like
val x = 7
val f = fn () => x
val x = 8
val _ = print (Int.toString (f ())) (* prints 7 *)
If the original entry was created outside a function call, and the new entry was created in a function call, then when the function call returns, we can access the original entry.
Sure, its statically scoped.
If both entries were created in the same "scope", like the example above, is the original entry not accessible?
It is still accessible, just not by that identifier. Consider the example above.
What is the point of making a variable immutable in SML and creating a new entry when redefining a variable?
One use of this is changing the type of a variable while still using the same identifier (which you do in the example you post!). Take for instance (in C):
int i = 7;
i = 7.0;
Here, i will still be of type int. Cf., in SML:
val i : int = 7
val i : real = 7.0
I've added type annotations for illustration, but even without this has the same behaviour. After the second binding, i has type real.
To amend kopecs' answer:
What is the point of making a variable immutable in SML and creating a new entry when redefining a variable?
That is the wrong way to phrase the question. :) Immutability by default has many merits, but that would be off-topic.
The actual question is: Why does SML allow multiple bindings for the same variable in a single scope? Instead of making it an error?
And that's a fair question. There is no deep reason. It merely turns out to be convenient sometimes. For example, to avoid spurious identifier clashes when using open. Or to allow redefining previous definitions in an interactive session.
This question already has answers here:
In MATLAB, can I have a script and a function definition in the same file?
(7 answers)
Closed 6 years ago.
I write some program at Matlab. I do it in .m file. And it's 300+ strings of code now, so it became not very comfortable for reading. My idea is to use it like in C++: I want to create local functions at the end of this file and put pieces of code into them. It would be easy to read and it would consist of some logical parts.
But I faced the fact that local functions can be created only in body of other function! So I can't create this:
x = 1;
y = 2;
z = myLocalFnc(x,y);
function res = myLocalFnc (a,b)
res = a.*b;
end
This generate error:
Function definitions are not permitted in this context.
I can do it by including the whole code into one function:
function myBigFcn
x = 1;
y = 2;
z = myLocalFnc(x,y);
end
function res = myLocalFnc (a,b)
res = a.*b;
end
But now all the variables became local and it return to workspace nothing.
Modify input/output for this function any time I create some variable - I don't think I walk the right way... Here are described advantages and disadvantages of this method.
I know I can create function in additional .m file, save it and use in my script - OK, but a lot of them are single-operation, I don't want to create so much new files.
My question is ARE any other methods of code organizing?
If you really want your main thing to be a script (I don't recommend this), you can put all the other functions in separate .m files and call those from within the script.
The other option, as you've noted is to put the entire contents of your "main" part into a function at the top of your code. You can return all the necessary values via the output arguments or save them to a .mat file if you need access to them later.
As a side note, the ability to put local functions within a script (what you're trying to do) is present in R2016b which will be released later this Fall.
Update
If you want an easy way to convert your code to a function. You can easily save all variables to a struct at the end of your function automatically and just return this struct.
function output = my_script_that_is_now_a_function(inputs)
% Do stuff
% Now save all variables in a struct and return it
tmpfile = tempname;
save(tmpfile);
output = load(tmpfile);
delete(tmpfile);
end
One option, if you don't mind saving a file locally, is to restructure your code into multiple functions (all in the same file) and pass the necessary variables as output. You then have a short script which calls this function and creates the necessary variables.
For example, say your script looks like this
numPoints = 5;
a = randn(numPoints);
b = sin(a);
c = a + b;
You could restructure it to look like
function data = main()
data.numPoints = 5;
data.a = getA(data.numPoints);
data.b = getB(data.a);
data.c = getC(data.a, data.b);
function a = getA(numPoints)
a = randn(numPoints);
function b = getB(a)
b = sin(a);
function c = getC(a, b)
c = a + b;
and create a script file which looks like
data = main();
You then have a struct called data which contains all of your variables. If you really want them to be contained in separate variables (i.e. not in a struct) then there are a couple of ways to do it. One is to unpack them manually,
a = data.a;
b = data.b;
c = data.c;
clear data;
Another is to save the struct, and then reload it (this has the advantage of keeping a copy of the workspace that you used for this fun of the function, for later analysis).
save('workspace.mat', '-struct', 'data');
load('workspace.mat');
I have a for loop in lua, and I'm trying to set variables inside that for loop using the iterator variable. I need it to set these variables:
damage1
damage2
damage3
damage4
damage5
damage6
damage7
damage8
damage9
damage10
damage11
Of course I'm not going to assign them all, as that would be breaking the rules of D.R.Y. (Don't Repeat Yourself). This is what I figured would work:
for i = 0, 11 do
damage..i = love.graphics.newImage('/sprites/damage/damage'..i..'.png')
end
Don't mind the love.graphics.newImage(), that's just a function in the framework I'm using. Anyways, can someone help?
Thanks in advance.
If you want to set global variables, set _G["damage"..i].
If you want to set local variables, you're out of luck.
Consider setting damage[i] instead.
If your variables are local variables, its impossible to do what you want since Lua erases the names during compilation. If your variables are properties of a table (like global variables are) then you can use the fact that table access is syntax sugar for accessing a string property in a table:
--using a global variable
damage1 = 17
--is syntax sugar for acessing the global table
_G.damage1 = 17
--and this is syntax sugar for acessing the "variable1" string property
--of the global table
_G["damage1"] = 17
--and you can build this string dynamically if you want:
_G["damage"..1] = 17
However, as lhf said, it would probably be much more simpler if you stored the variables in an array instead of as separate variables:
damages = {10, 20, 30, 40}
for i=1,4 do
damages[i] = damages[i] + 1
end
Wouldn't this be the best thing to do?
damages = {}
for i = 0,11 do
table.insert(damages, love.graphics.newImage("/sprites/damage/damage"..i..".png"));
end
And then call by damages[0], damages[1]. etc.
I am trying to understand how CoffeeScript variables are scoped.
According to the documentation:
This behavior is effectively identical to Ruby's scope for local
variables.
However, I found out that it works differently.
In CoffeeScript
a = 1
changeValue = -> a = 3
changeValue()
console.log "a: #{a}" #This displays 3
In Ruby
a = 1
def f
a = 3
end
puts a #This displays 1
Can somebody explain it, please?
Ruby's local variables (starting with [a-z_]) are really local to the block they are declared in. So the Ruby behavior you posted is normal.
In your Coffee example, you have a closure referencing a. It's not a function declaration.
In your Ruby example, you don't have a closure but a function declaration. This is different. The Ruby equivalent to your Coffee is:
a = 1
changeValue = lambda do
a = 3
end
changeValue()
In closures, local variables present when the block is declared are still accessible when the block is executed. This is (one of the) powers of closures!
The a variable being used inside the changeValue function is the global a variable. That CoffeeScript will be compiled into the following JavaScript:
var a, changeValue;
a = 1;
changeValue = function() {
return a = 3;
};
changeValue();
console.log("a: " + a);
In order for changeValue to not alter the a variable (i.e. use a local variable), you would either need to have an argument to the function named a (which would create a as a variable local to that function) or declare a as a local variable inside the function using var a = 3; (not sure what the CoffeeScript for that would be, I'm not a CoffeeScript guy).
Some examples of JavaScript variable scope.