I have a script where I am doing what appears to be the exact same thing, but it works in that one and not this one. I'm hoping that a few more pairs of eyes will be able to help me find out the issue, I've already spent an hour and a half on it.
I have a proc that edits the global var, it's more complex that this but I'll use this for simplicity's sake:
proc myCustomProc { var } {
global __myGlobal
set __myGlobal [ expr $__myGlobal + 1 ]
}
I have defined a variable globally in my "main" proc:
proc FOO {} {
global __myGlobal
...
...
myCustomProc 5
puts $__myGlobal
Then I get can't read "__myGlobal": no such variable
I have the exact code with a different varname working in a different script, so I'm stumped. Obviously it's NOT identical, I just cannot find the issue.
Edit: both procs are in the same .tcl file
You can't read from a variable that is unset, and that's true whether that variable is global or not. Thus, in the code:
set __myGlobal [ expr $__myGlobal + 1 ]
It first reads the value from the global variable, then adds one to that value, then writes the result back to the global variable. (Actually, it is interpreting the contents of the variable as an expression fragment, which I'd lay good money on being something you don't want as it is slow and unsafe; put the whole expression in braces please.)
For adding one to an integer (and from Tcl 8.5 onwards) you should just use the incr command instead, as that interprets a non-existent value as if it was zero:
incr __myGlobal
But if you're doing something more complex (or working in 8.4 or before), you should instead put a check with info exists like this in front:
if {![info exists __myGlobal]} {
set __myGlobal "the default value"; # Or whatever default you want
}
You could also use a more complex expression like this:
set __myGlobal [expr {[info exists __myGlobal] ? $__myGlobal+1 : 1}]
But I usually try to avoid the ternary operator; it's often not that readable.
The short answer is, you are using $__myGlobal in the expr command before it has been set.
Related
I am new to IDL and find the KEYWORD_SET difficult to grasp. I understand that it is a go no go switch. I think its the knocking on and off part that I am having difficulty with. I have written a small program to master this as such
Pro get_this_done, keyword1 = keyword1
WW=[3,6,8]
PRINT,'WW'
print,WW
y= WW*3
IF KEYWORD_Set(keyword1) Then BEGIN
print,'y'
print,y
ENDIF
Return
END
WW prints but print, y is restricted by the keyword. How do I knock off the keyword to allow y to print.
Silly little question, but if somebody can indulge me, it would be great.
After compiling the routine, type something like
get_this_done,KEYWORD1=1b
where the b after the one sets the numeric value to a BYTE type integer (also equivalent to TRUE). That should cause the y-variable to be printed to the screen.
The KEYWORD_SET function will return a TRUE for lots of different types of inputs that are basically either defined or not zero. The IF loop executes when the argument is TRUE.
Keywords are simply passed as arguments to the function:
get_this_done, KEYWORD1='whatever'
or also
get_this_done, /KEYWORD1
which will give KEYWORD1 the INT value of 1 inside the function. Inside the function KEYWORD_SET will return 1 (TRUE) when the keyword was passed any kind of value - no matter whether it makes sense or not.
Thus as a side note to the question: It often is advisable to NOT use KEYWORD_SET, but instead resort to a type query:
IF SIZE(variable, /TNAME) EQ 'UNDEFINED' THEN $
variable = 'default value'
It has the advantage that you can actually check for the correct type of the keyword and handle unexpected or even different variable types:
IF SIZE(variable, /TNAME) NE 'LONG' THEN BEGIN
IF SIZE(variable, /TNAME) EQ 'STRING' THEN $
PRINT, "We need a number here... sure that the cast to LONG works?"
variable = LONG(variable)
ENDIF
I have defined a global variable global x=-2. Once created, global variables cannot be reassigned, i.e., x=7 will not change the -2 value of x. For this reason I clear the variable.
>> clear x
I check that the variable does not exist any more.
>> exist("x")
ans = 0
But when I create the global variable again with a new value, for example, global x=7 I get the global variable in the old value.
>> global x=7
>> x
x = -2
Why is this happening? Is the variable x not really deleted?
What you see is expected behaviour. It looks weird but consider the following example:
global x = 5;
function say_x ()
global x = 3;
disp (x);
endfunction
say_x ();
x = 7;
say_x ();
Which returns:
5
7
Note that you need declare x within functions to access the global variable. Also note that assigning to it the value of 3 does not work. The reason is that lines such as persistent x = 3 or global x = 3 are only evaluated the first time. This means that when you call say_x(), x already has a value so it never assigns to it the value of 3 (the right hand side never even gets evaluated).
Now; on to your actual issue which is all of this happening in the main/base namespace/symbol table, mixed up with what clear() is supposed to do. You are running this:
global x = 1;
clear x;
global x = 2;
x # you are surprised that x is 1 instead of 2
First, note that clear() does not actually clears the values of the variables. It will remove their names from the symbol table. Note the help text from clear():
-- Command: clear [options] pattern ...
Delete the names matching the given patterns from the symbol table.
With "normal" variables, the names won't be anywhere else and you will effectively remove their value. But that's not true with global variables. Their values will remain somewhere, ready to be made accessible the next time a global variable with their name gets defined.
What is happening when you try to define x again, is that the name already exists in the symbol table of global variables. So you are bringing it back to the current symbol table (just like what happens inside a function) and the right hand side (= 2) never gets evaluated.
As you already found, to actually remove names from the global symbol table, you need to use clear -global (as it is documented on the help text of clear).
We need to use the option -global to effectively delete the global variable: clear -global x
Example:
>> global x=-2
>> clear -global x
>> exist("x")
ans = 0
>> global x=7
>> x
x = 7
This must be a bug in Octave, because clear command alone seems to work fine clearing the global variable: no error message, and the "exist" check outputs the expected.
(Hope it helps, it took me some minutes to find the solution ;))
Edit:
I have a kludgy piece of code that looks like this:
readcsvfile()
dopreprocessingoncsvfile()
readanothercsvfile()
moreprocessing()
# etc ...
Over a few days, this has gradually got longer and more complex, and therefore takes over a minute or two to run now, and I'm not very patient :-P . Given that R is so great at saving the environment, I mean the variables in the R environment, an easy way to accelerate this is:
if( !exists("init.done") {
readcsvfile()
dopreprocessingoncsvfile()
readanothercsvfile()
moreprocessing()
init.done = T
}
However, I like it to be a bit more fine-grained, not least because sometimes I might tweak a function in the processing, so I want to rerun it, without watching the whole world reload, so I've changed it to:
if( !exists("somedata" ) ) {
somedata <- readcsvfile()
}
# ... etc ... same for the others
However, sometimes I make one of the following mistakes, and let's face it, I'm also just plain lazy, so why write a big long if statement if there is a more concise way? I make the following mistakes often:
mistype the name of the variable in the if, which 'detects' itself by my noticing that it keeps running every time I run the script
miss off the second bracket in the if clause, which takes 10-15 seconds to detect, modify, and rerun, which is annoying :-P
Sooo.... my proposd solution is to write a function cacheVar whose definition looks a bit like:
cacheVar <- function( varname, expression ) {
if( !exists(varname ) {
setValueMagic( varname, evalMagic(expression) )
}
}
... and whose usage looks like:
cacheVar("foo", {
# some expression that calculates the value of foo
})
... where the expression is evaluated only if value 'varname' doesn't already exist.
I guess the missing information to flesh this out is:
does this exist already?
how to write setValueMagic in R?
how to write evalMagic in R?
Edit: a bit more complicated, since we need to assign into the parent frame, possibly using parent.env or parent.frame, something like that.
Imagine this scenario:
I have a ZPT in Zope where I define, into a metal block, a global variable.
This variable takes its value from an expression like this
global myVar id | nothing;
global anotherVar 1;
where nothing could be replaced with python:0 or python:False or None and so on.
Now imagine that into another block, I'll do something like
global myVar2 myVar | anotherVar | nothing;
where nothing could be everything that I specified above.
Now suppose that id hasn't a value and so myVar took nothing (or the other possible values; it's makes not difference at all).
What I expected was that myVar2 took anotherVar's value, since anotherVar has a value. But with great surprise, I notice that this isn't true and myVar2 took myVar value; that means nothing.
If I understand what is happening, I'll suppose that this kind of statement only control over existence of that variable and not over it's value.
Obviously I can make that kind of statement into a pythonic way and, of course, it works "well" (namely, as I expected)
So, someone can confirm or disprove what I suppose there ?
What you are asking is not Plone or Zope specific, you are dealing with a TALES statement here, which, together with TAL and METAL form the page template language implemented by Zope Page Templates (and, incidentally, also by chameleon, plus several other implementations in different programming languages).
You are using a TALES path expression when you use the | character, and it is not the same as a Python or expression. Each path named in the expression will by resolved, and only if it doesn't exist will the next path be used. From the specification:
When a TALES path expression is evaluated, it attempts to traverse each path, from left to right, until it succeeds or runs out of paths.
Since all your paths resolve to existing variable names, they all exist and the first one will be used, regardless of it's value.
You want to use a python: expression instead:
myVar2 python:myVar or anotherVar or None;
Note that in TAL there rarely is a need for the global keyword. You probably want to define these items on your root element of your document instead; variables are visible within the same scope as the XML or HTML element they are defined on:
<html tal:define="myVar id | nothing; anotherVar 1;">
<!-- myVar and anotherVar are visible in the whole HTML document -->
</html>
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.