How to force a variable to be local in coffeescript? - coffeescript

Given the following code:
outer=1
f=->
local=1
outer=0
local+outer
coffeescript creates a var for local but re-ueses outer:
var f, outer;
outer = 1;
f = function() {
var local;
local = 1;
outer = 0;
return local + outer;
};
Which is what your expect.
However, if you use a local variable in a function it depends on the outer scope if the variable is declared local or not. I know this is a feature, but it was causing some bugs, because I have to check all outer scopes for variables with the same name (which are declared before my function). I wonder if there is a way to prevent this type of bug by declaring variables local?

This kind of error usually comes up when you aren't using appropriately descriptive variable names. That said, there is a way to shadow an outer variable, despite what the accepted answer says:
outer=1
f=->
do (outer) ->
local=1
outer=0
local+outer
This creates an IIFE, with outer as it's one argument. Function arguments shadow outer variables just like the var keyword, so this will have the behavior you expect. However, like I said, you should really just name your variables more descriptively.

No, that feature is explicitly not available in CoffeeScript (emphasis mine):
This behavior is effectively identical to Ruby's scope for local variables. Because you don't have direct access to the var keyword, it's impossible to shadow an outer variable on purpose, you may only refer to it. So be careful that you're not reusing the name of an external variable accidentally, if you're writing a deeply nested function.

You can inject plain JavaScript into your CoffeeScript using backticks:
outer=1
f=->
local=1
`var outer=0`
local+outer
For most cases I try to avoid this and would rather rename the outer variables, indicating their scope/context within their name. However, sometimes this is helpful, e.g., when using the debug module, where I always want to have a debug() function available for logging, as in this example:
#logging fn for module setup and other global stuff
debug = require("debug")("foo")
class Bar
#local logging fn to allow Bar instances to log stuff
`var debug = require("debug")("foo:bar")`
If you want to keep plain JS at a minimum just declare the variable and then assign is using CoffeeScript:
`var debug`; debug = require("debug") "foo:bar"
The example compiles to:
// Generated by CoffeeScript 1.7.1 -- removed empty lines for SO answer
var Bar, debug;
debug = require("debug")("foo");
Bar = (function() {
function Bar() {}
var debug;
debug = require("debug")("foo:bar");
return Bar;
})();
I like this direct way of declaring variables better than the (IMHO) slower and less readable IIFE hack.

As Aaron pointed out, shadowing is indeed possible:
outer=1
f=->
do (outer) ->
local=1
outer=0
local+outer
Since the outer value is not needed inside the local function, it can be initialized with null just in case that at some point the variable outer is removed from the outer scope (which would cause an error).
#outer=1
f=->
do (outer=null) ->
local=1
outer=0
local+outer

important = 10 # global
main = ->
agentId = '007'
console.log 'global `important`', important # refers to the global variable
((important) -> # place the local variables as the arguments
important = 20
console.log 'local `important`', important # locally scoped
console.log 'parent scope value', agentId # even access variables from the above scopes
)() # not passing anything, so the local varibales would be left undefined at first
console.log 'global `important`', important # the global variable remains untouched
main()

Related

define help for variable in Matlab

In Matlab, it is easy to generate "help" for a function, as follows.
function out = foo()
% helpful information about foo
end
When we execute help foo, we get "helpful information about foo".
However, suppose we would like to define help for a variable, probably as a definition. How could we do such a thing? It would be nice if we could do something like
x = 3; % m ... position
help x
and get "m ... position". However, I don't believe such functionality exists.
The only reasonable way I see around this is to define every variable as a struct with keys value and description.
x.value = 3;
x.description = 'm/s ... position';
This requires we define every variable as a struct, which is kind of annoying and, I worry (should I?), unperformant (it's simulation code and these variables are accessed repeatedly).
Is there another solution I'm not considering? Should I be worried about making every variable a struct?
Your code should be self-documenting. Instead of variable name x, use position.
Furthermore, all variables should be local, so you can easily look for its definition (with comment) within the function you are editing.
Variables declared further away (with larger scope within the function) should have longer, more self-explanatory names than variables with a smaller scope (e.g. use within a short loop.
There are only two three cases where variables are declared outside the function’s scope:
Class properties. You can actually document these.
In a script, you have access to variables that already existed before the script started. A good reason not to use scripts or depend on the base namespace in larger projects.
Global variables. You should never use global variables for many reasons. Just don’t.

How to avoid global variable declaration when using Perl's dynamic scoping?

I am trying to write a perl script that calls a function written somewhere else (by someone else) which manipulates some of the variables in my script's scope. Let's say the script is main.pl and the function is there in funcs.pm. My main.pl looks like this:
use warnings;
use strict;
package plshelp;
use funcs;
my $var = 3;
print "$var\n"; # <--- prints 3
{ # New scope somehow prevents visibility of $pointer outside
local our $pointer = \$var;
change();
}
print "$var\n"; # <--- Ideally should print whatever funcs.pm wanted
For some reason, using local our $pointer; prevents visibility of $pointer outside the scope. But if I just use our $pointer;, the variable can be seen outside the scope in main.pl using $plshelp::pointer (but not in funcs.pm, so it would be useless anyway). As a side-note, could someone please explain this?
funcs.pm looks something like this:
use warnings;
use strict;
package plshelp;
sub change
{
${$pointer} = 4;
}
I expected this to change the value of $var and print 4 when the main script was run. But I get a compile error saying $pointer wasn't declared. This error can be removed by adding our $pointer; at the top of change in funcs.pm, but that would create an unnecessary global variable that is visible everywhere. We can also remove this error by removing the use strict;, but that seems like a bad idea. We can also get it to work by using $plshelp::pointer in funcs.pm, but the person writing funcs.pm doesn't want to do that.
Is there a good way to achieve this functionality of letting funcs.pm manipulate variables in my scope without declaring global variables? If we were going for global variables anyway, I guess I don't need to use dynamic scoping at all.
Let's just say it's not possible to pass arguments to the function for some reason.
Update
It seems that local our isn't doing any "special" as far as preventing visibility is concerned. From perldoc:
This means that when use strict 'vars' is in effect, our lets you use a package variable without qualifying it with the package name, but only within the lexical scope of the our declaration. This applies immediately--even within the same statement.
and
This works even if the package variable has not been used before, as package variables spring into existence when first used.
So this means that $pointer "exists" even after we leave the curly braces. Just that we have to refer to it using $plshelp::pointer instead of just $pointer. But since we used local before initializing $pointer, it is still undefined outside the scope (although it is still "declared", whatever that means). A clearer way to write this would be (local (our $pointer)) = \$var;. Here, our $pointer "declares" $pointer and returns $pointer as well. We now apply local on this returned value, and this operation returns $pointer again which we are assigning to \$var.
But this still leaves the main question of whether there is a good way of achieving the required functionality unanswered.
Let's be clear about how global variables with our work and why they have to be declared: There's a difference between the storage of a global variable, and visibility of its unqualified name. Under use strict, undefined variable names will not implicitly refer to a global variable.
We can always access the global variable with its fully qualified name, e.g. $Foo::bar.
If a global variable in the current package already exists at compile time and is marked as an imported variable, we can access it with an unqualified name, e.g. $bar. If a Foo package is written appropriately, we could say use Foo qw($bar); say $bar where $bar is now a global variable in our package.
With our $foo, we create a global variable in the current package if that variable doesn't already exist. The name of the variable is also made available in the current lexical scope, just like the variable of a my declaration.
The local operator does not create a variable. Instead, it saves the current value of a global variable and clears that variable. At the end of the current scope, the old value is restored. You can interpret each global variable name as a stack of values. With local you can add (and remove) values on the stack.
So while local can dynamically scope a value, it does not create a dynamically scoped variable name.
By carefully considering which code is compiled when, it becomes clear why your example doesn't currently work:
In your main script, you load the module funcs. The use statement is executed in the BEGIN phase, i.e. during parsing.
use warnings;
use strict;
package plshelp;
use funcs;
The funcs module is compiled:
use warnings;
use strict;
package plshelp;
sub change
{
${$pointer} = 4;
}
At this point, no $pointer variable is in lexical scope and no imported global $pointer variable exists. Therefore you get an error. This compile-time observation is unrelated to the existence of a $pointer variable at runtime.
The canonical way to fix this error is to declare an our $pointer variable name in the scope of the sub change:
sub change {
our $pointer;
${$pointer} = 4;
}
Note that the global variable will exist anyway, this just brings the name into scope for use as an unqualified variable name.
Just because you can use global variables doesn't mean that you should. There are two issues with them:
On a design level, global variables do not declare a clear interface. By using a fully qualified name you can simply access a variable without any checks. They do not provide any encapsulation. This makes for fragile software and weird action-at-a-distance.
On an implementation level, global variables are simply less efficient than lexical variables. I have never actually seen this matter, but think of the cycles!
Also, global variables are global variables: They can only have one value at a time! Scoping the value with local can help to avoid this in some cases, but there can still be conflicts in complex systems where two modules want to set the same global variable to different values and those modules call into each other.
The only good uses for global variables I have seen are to provide additional context to a callback that cannot take extra parameters, roughly similar to your approach. But where possible it is always better to pass the context as a parameter. Subroutine arguments are already effectively dynamically scoped:
sub change {
my ($pointer) = #_;
${$pointer} = 4;
}
...
my $var = 3;
change(\$var);
If there is a lot of context it can be come cumbersome to pass all those references: change(\$foo, \$bar, \$baz, \#something_else, \%even_more, ...). It could then make sense to bundle that context into an object, which can then be manipulated in a more controlled manner. Manipulating local or global variables is not always the best design.
There's too much wrong with your code to just fix it
You've used package plshelp in both the main script and the module, even though the main entry point is in main.pl and your module is in funcs.pm. That's just irresponsible. Did you imagine that the package statement was solely for advertising for help and it didn't matter what you put in there?
Your post doesn't say what is wrong with what you have written, but it's surprising that it doesn't throw an error.
Here's something close that does what you seem to expect. I can't really explain things as your own code is so far from working
Functions.pm
package Functions;
use strict;
use warnings;
use Exporter 'import';
our #EXPORT_OK = 'change';
sub change {
my ($ref) = #_;
$$ref = 4;
}
main.pl
use strict;
use warnings 'all';
use Functions 'change';
my $var = 44;
print "$var\n";
change(\$var);
print "$var\n";
output
44
4

MATLAB bug? "Undefined function or variable" error when using same name for function and variable

It is occasionally convenient to use a function as a "constant" variable of sorts in MATLAB. But when I was using this feature recently, I ran into an unexpected error. When I run the MWE below, I get the error Undefined function or variable 'a'. despite the function being clearly available in the same file. When I comment out the if statement, the error goes away. This seems to imply that MATLAB is pre-interpreting a as a variable even though the variable assignment line is never reached, ignoring the fact that there is a function by the same name. Is this a MATLAB bug or is it somehow the desired behavior?
Here is the MWE:
function matlabBugTest( )
if false
a = 'foo';
end
a
end
function b = a()
b = 'bar';
end
Follow-up:
I know it seems weird to intentionally use the same name for a variable and a function, so I'll give an example of where this can be useful. For instance, you may want to use a function to store some constant (like a file path), but also want to be able to use a different value in case the function cannot be found. Such a case might look like:
if ~exist('pathConstant.m', 'file')
pathConstant = 'C:\some\path';
end
load(fullfile(pathConstant, 'filename.ext'));
I know that language design decisions are often difficult and complicated, but one of the more unfortunate consequences of MATLAB's choice here to ignore the function by the same name is that it breaks compatibility between functions and scripts/command line. For instance, the following runs without issue in a script:
if false
a = 'foo';
end
a
where the function a (shown above) is saved in its own file.
It has to do with how Matlab performs name-binding at compilation time. Because matlabBugTest has a line that assigns a value to a, a is determined to be a variable, and the later line with a is a reference to that variable and not a call to the local function. More modern versions of Matlab, like my R2015a install, gives a more clear error message:
At compilation, "a" was determined to be a variable and this variable is uninitialized. "a" is also a function name and previous versions of MATLAB would have called the
function. However, MATLAB 7 forbids the use of the same name in the same context as both a function and a variable.
It's not so much a bug, as it is an ambiguity introduced by the naming scheme that was given a default resolution method, which can be annoying if you have never encountered the problem before and m-lint doesn't mark it. Similar behavior occurs when variables are poofed into the workspace without initialization beforehand.
So the solution is to either change the name of the function or the variable to different things, which I would argue is good practice anyways.
In considering your follow-up example, I have noticed some interesting behavior in moving things around in the function. Firstly, if the function is either external or nested, you get the behavior discussed very well by Suever's answer. However, if the function is local, you can get around the limitation (at least you can in my R2014b and R2015a installs) by invoking the function prior to converting it to a variable as long as you initialize it or explicitly convert it to a variable at some point. Going through the cases, the following bodies of matlabBugTest perform thusly:
Fails:
a
if false
a = 'foo';
end
a
Runs:
a
if true
a = 'foo';
end
a
Runs:
a = a;
if false % runs with true as well.
a = 'foo';
end
a
I'm not entirely sure why this behavior is the way it is, but apparently the parser handles things differently depending on the scope of the function and the order of what symbols appear and in what contexts.
So assuming this behavior hasn't and will not change you could try something like:
pathConstant = pathConstant;
if ~exist('pathConstant.m', 'file')
pathConstant = 'C:\some\path';
end
load(fullfile(pathConstant, 'filename.ext'));
Though, entirely personal opinion here, I would do something like
pathConstant = getPathConstant();
if ~exist('pathConstant.m', 'file')
pathConstant = 'C:\some\path';
end
load(fullfile(pathConstant, 'filename.ext'));
Concerning breaking "compatibility between functions and scripts/command line", I don't really see this as an issue since those are two entirely different contexts when it comes to Matlab. You cannot define a named function on the command line nor in a script file; therefore, there is no burden on the Matlab JIT to properly and unambiguously determine whether a symbol is a function call or a variable since each line executes sequentially and is not compiled (aside from certain blocks of code the JIT is designed to recognize and optimize like loops in scripts). Now as to why the above juggling of declarations works, I'm not entirely sure since it relies on the Matlab JIT which I know nothing about (nor have I taken a compiler class, so I couldn't even form an academic reason if I wanted).
The reason that you get this behavior is likely that Matlab never have implemented scope resolution for any of their statements. Consider the following code,
(a)
if true
a = 'foo';
end
disp(a)
This would actually display "foo". On the other hand would,
(b)
if false
a = 'foo';
end
disp(a)
give you the error Undefined function or variable "a". So let us consider the following example,
(c,1)
enterStatement = false;
if enterStatement
a = 'foo';
end
disp(a)
(c,2)
enterStatement = mod(0,2);
if enterStatement
a = 'foo';
end
disp(a)
TroyHaskin clearly states the following in his answer
It has to do with how Matlab performs name-binding at compilation time. Because matlabBugTest has a line that assigns a value to a, a is determined to be a variable, and the later line with a is a reference to that variable and not a call to the local function
Matlab does not support constant expressions and does only a limited amout of static code analysis. In fact, if the if statement takes argument false, or if enterStatement is false, Matlab provides a warning, This statement (and possibly following ones) cannot be reached. If enterStatement is set to false Matlab also generates another warning, Variable a is used, but might be unset. However if enterStatement = mod(0,2), so to say if enterStatement calls a function, you get no warning at all. This means that if the example in the question was allowed then (c,2) would compile based on how the function were evaluated and that is a contradiction. This would mean that the code would have to compile based on its runtime results.
Note: Sure it could be good if Matlab could generate an error in case the enterStatement was an expression instead of a constant false, but whether or not this is possible it would depend on implementation I guess.

I'm confused about Scala function and closure

When I read book I saw the following is a function:
val plusOne=(x:Int)=>x+1
well, when the function invoke a variable it becomes a closure:
The following is a closure:
val count=1
val plusOne=(x:Int)=>x+count
Is that right - If a function used any variable, then it will become closure?
No, that's not right.
What you are seeing there, is just a nested function. The defining feature of a closure is that it closes over its enclosing lexical environment, and thus extends the lifetime of the variables in that enclosing environment beyond the lifetime of that enclosing environment.
See this for an example:
def makeAdder(inc: Int) = (x: Int) => x + inc
val threeAdder = makeAdder(3)
threeAdder(20) //=> 23
threeAdder(39) //=> 42
Even though the method makeAdder has exited and thus the local variable inc has gone out of scope, the closure returned by makeAdder still has access to it, because it closes over the lexical environment of makeAdder. So, a nested function with free variables becomes a closure as soon as its enclosing lexical scope ends and it escapes from it.
Yes, that is right.
You can read more about it on TutorialsPoint: Scala closures.
This definition of a closure is not specific to scala.
I think yout Code is wrong.
If count is var.. like..
var count = 1
Then the function value of plusOne is created and closed at runtime, so we can call it closure.
But in your example count is val type. so the function value is always closed at compile time.. so it's not closure.

Perl scoping and the life of local variables

How long does the memory location allocated by a local variable in Perl live for (both for arrays, hashes and scalars)? For instance:
sub routine
{
my $foo = "bar";
return \$foo;
}
Can you still access the string "bar" in memory after the function has returned? How long will it live for, and is it similar to a static variable in C or more like a variable declared off the heap?
Basically, does this make sense in this context?
$ref = routine()
print ${$ref};
Yes, that code will work fine.
Perl uses reference counting, so the variable will live as long as somebody has a reference to it. Perl's lexical variables are sort of like C's automatic variables, because they normally go away when you leave the scope, but they're also like a variable on the heap, because you can return a reference to one and it will just work.
They're not like C's static variables, because you get a new $foo every time you call routine (even recursively). (Perl 5.10 introduced state variables, which are rather like a C static.)