How to prevent closure compiler from removing unused local variable? - google-closure-compiler

I am facing one scenario as below,
function a() {
var $$ = this;
eval("some script");
}
using closure compiler with simple level, it will remove the $$ var in the simplified output, but this variable maybe used by the code "some script" from script developers, so is there anyway to let closure compiler keep var $$ in the output? Thanks!

Borrowing from Solution: Export the Symbols You Want to Keep I suggest you use a bracket notation to create this var. I'm assuming that your global element is window.
function a() {
window['$$'] = this;
eval("some script");
}
It might not be pretty, but this does work;
With an output of
function a() {
window.$$ = this;
eval("some script");
}

No not really. You might be able to find a workaround, but it's not guaranteed to work in future compiler versions.
You would need to rework you code not to utilize eval like that.

Use the Function constructor:
var a = new Function('var $$ = this; eval("some script");');
If you want to avoid escaping the contents of "some script", you can pass it in as parameter:
var a = new Function('script', 'var $$ = this; eval(script);');
This keeps needed locals out of the compiler's analysis.

Related

Function that self destructs

I read some post where Hadley made a joke about a self destructing function. I thought this would be relatively simple to implement but turns out it's not.
Here is an attempt to write a function named self_delete that is a quine and attempts to self destruct after printing its body. The idea was to search for the function's name in .GlobalEnv and delete it but that doesn't work. I would like to understand why this is the case.
self_delete<- function(){
print(body(self_delete))
rm(list=lsf.str(pattern="self_delete"))
}
Calling the above prints the following as expected but does not delete itself from .Globalenv, what am I missing? I did try with rm and ls too with no luck
self_delete()
{
print(body(self_delete))
rm(list = lsf.str(pattern = "self_delete"))
}
You forgot to set the envir argument to rm(), so it's trying to delete self_delete from the calling frame, not from globalenv().
This works:
self_delete <- function(){
print(body(self_delete))
rm("self_delete", envir = globalenv())
}

In functional programming, can a function call another function that was declared outside of it's scope and not passed as a parameter?

Does using a function declared outside the scope of the function it is being used in violate a Functional principle like immutability? Or is that referring specifically to data like arrays, strings, etc.
For example:
var data ["cat", "dog", "bird"];
function doThing (val) {
return val + ", go away!"
}
function alterData (data) {
return data.map(doThing);
}
alterData(data);
Would the above code be acceptable? or would the "doThing" function need to be passed into the alterData function as an argument?
The reason I am confused is because in Functional Programming examples I often see functions native to the language being used without being first passed to the function. However, the examples are never complicated enough to show how one would work with a library of functions.
Regards
Functional programming is no different from procedural in that regard—you write definitions that you can reuse anywhere that they are in scope. You control what's in scope where with a variety of mechanisms, for example with module definitions, module export lists and module imports. So for example (in Haskell):
module My.Module
-- List of definitions exported from this module
( doThing
, alterData
) where
-- Any definitions exported from `My.Other.Module` will be in scope
-- in this one
import My.Other.Module
-- Can't name this `data` because it's a reserved word in Haskell
yourData :: [String]
yourData = ["cat", "dog", "bird"]
doThing :: String -> String
doThing val = val ++ ", go away!"
alterData :: [String] -> [String]
alterData strings = map doThings strings
TL;DR
It's fine to rely on scoping in FP code.
Immutability means that something represented by a name can't change its value. I wouldn't call it a "principle" of functional programming, though.
Anyway, this is not related to scoping at all. Passing things as arguments makes sense if you want to parametrize a function over another function - essentially making it a Higher-Order function. A good example of such is fold (also known as reduce) - but map is also one.
In your case alterData function isn't adding much value, though. mapping something over something is so common, that it's typically better to provide only the one-element function, as it's fundamentally more reusable.
If you've passed doThing to alterData, you'd make that function essentially useless; why would I use it, if I could simply use map? However, packing the operation together with the mapping can sometimes be an useful abstraction.
It is fine have doThing the way it is.
You need to do this :
var data = ["cat", "dog", "bird"];
var doThing = function (val) {
return val + ", go away!"
}
function alterData (data) {
return data.map(doThing);
}
alterData(data);

Retrieving variables from functions

Since generally variables inside functions have a local scope(I assume),what's the best way, in any functional language, to retrieve variables from functions, like that, in pseudo language
function test = (
firstVariable = calculateSomething()
secondVariable = calculateSomethingElse()
)
(
function finalCalculation = (
test() /*call the previously defined function*/
result = firstVariable+secondVariable /*how do I get those?*/
)
Edit: I'm not being general. This problem is applicable to all functional languages. The problem itself resides in the concept of retrieving a variable from another function, avoiding global scopes. Anyway, for sake of simplicity, and the structure of the example, let's say javascript.
Functions can return a result:
result function test = (
result.firstVariable = calculateSomething()
result.secondVariable = calculateSomethingElse()
return result
)
function finalCalculation = (
result = test()
)
However, this question smells like either you actually dont have any real problem at hand, or your actual problem is something else and you turned it into something too academic. Questions tagged as java,javascript,C and C++ rarely result in reasonable answers, as this languages are just too different in their details.
in javascript the IIFE and Closure principles
var f = (function() {
var localFunc = function(){};
var localVar1 = 3;
var localVar2 = 4;
// publish
return {
localFunc: localFunc,
localVar: localVar1
}
})();
f.localFunc(); // ok
f.localVar2; // nok
I don't known if i answered the question
Looks like a leak of fundamental knowledge. Key words are global variables, return value, and getter/setter : You should specify the languange you want to use and ask some concrete questions.

Calling user specified R function in inline C++ body

I have been working with the R package "RcppArmadillo". I already used it to define two cxxfunction(they have been debugged are fine to use):
calc1 <- cxxfunction(signature(A="integer", B="integer"),...)
calc2 <- cxxfunction(signature(A="integer", K="integer"),...)
Now I'm writing the body part of another cxxfunction main and wish to call calc1 and calc2 within the for loops there, like:
body_main = '
...
for(int i=0; i<N; i++){
// This is where I want to call calc1.
// (?)
for(int j=0; j<N; j++){
// This is where I want to call calc2.
// (?)
}
}
'
Is there anyway that I can achieve that? Can that be done in an inline fashion?
I haven't seen an example of inline usage of RcppArmadillo(or Rcpp, RcppGSL) in which people write a subroutine within the body part - specifically, I mean code looks like this:
body_example = '
// Subroutine
SEXP(/*or something else*/) func_0(SEXP A, SEXP B){
...
return ...;
}
// Then call it from the main part
...
AB = func_0(A, B);
...
'
My question probably looks naive but it haunts me nevertheless. Can anyone help explain this? I'd appreciate that a lot!
You could switch from using cxxfunction() from package inline to using Rcpp attributes and its sourceCpp(). That way you get the predictable function headers at the C++ level, see the Rcpp atributes vignette.
Or split calc1 and calc2 into 'worker' and 'wrapper', have cxxfunction() around the wrapper allowing you to call the worker.
The key issue here really is that cxxfunction() exists to create an R-callable function, and it generates internal randomized function headers.
Lastly, a package would help too.

Calling JScript functions from VBScript - Parentheses

I'm trying to bring some sanity to a legacy Classic ASP application, and as part of this I'm trying to write a Fluent API for some JScript classes that I have created.
e.g. myClass().doSomething().doSomethingElse()
The concept is outlined here (in VBScript)
This is my sample JScript class:
var myClass = function () {
this.value = '';
}
myClass.prototype = function () {
var doSomething = function (a) {
this.value += a;
return this;
},
doSomethingElse = function (a, b) {
this.value += (a + b);
return this;
},
print = function () {
Response.Write('Result is: ' + this.value + "<br/>");
}
return {
doSomething: doSomething,
doSomethingElse: doSomethingElse,
print: print
};
}();
/// Wrapper for VBScript consumption
function MyClass() {
return new myClass();
}
In the existing VBScript code I'm then trying to chain the methods together:
dim o : set o = MyClass()
'' This works
o.doSomething("a")
'' This doesn't work
o.doSomething("b").doSomethingElse("c", "d")
'' This for some reason works
o.doSomething("e").doSomethingElse("f", "g").print()
When the functions have more than one parameter I get the "Cannot use parentheses when calling a Sub" VBScript error. Strangely, it seems to work when followed by another method.
I understand that parentheses should be ommitted when calling a sub. However:
1. Why is it being recognised as a Sub if there is a return value?
2. Is there any way around this in order to implement my Fluent API?
The rule is: No param list () when calling a 'named piece of code' as a sub. The nasty trap is: For single parameter npcs, the () may look like param list (), but are (interpreted as) pass-me-by-value ().
Your set o = MyClass() calls my MyClass() as a function; that is clear from the assignment.
Your o.doSomething("a") calls .doSomething as a sub, the () are seen as pass-me-per-value (); doSomething "a" would be the correct call.
The first part of your o.doSomething("b").doSomethingElse("c", "d") works, because o.doSomething("b"). is/uses a function call to get an object whose .doSomethingElse() is to be called; the second part .doSomethingElse("c", "d") can't work, because it isn't a sub call (no return value used/assigned) and the () can't be seen as pass-me-by-value (). o.doSomething("b").doSomethingElse "c", "d" would be correct.
The first part o.doSomething("e").doSomethingElse("f", "g").print() (upto the .print) is a function call (to get the object that will .print), so the () are param list (); the () after .print are wrong, but the compiler/interpreter let them slip by.
To sum up: don't use () when you don't want something back.
WRT comment:
To put it the other way around: use () when you want something back!
set o1 = MyClass() <- return value should go into o1
set o2 = o.S(1, 2).S(3, 4).S(5, 6) <- first two return values are needed/used for the next call; last return value goes into o2.
o.S(1, 2).S(3, 4).S 5, 6 <- last return value is discarded - no sub call
The () rule is about what you do (use the return value or not), not about what the npc is.
You can put call at the start of each line of vbscript. This will accept brackets being put on each method call, e.g.
' This works
call o.doSomething("b").doSomethingElse("c", "d")
' This works too
call o.doSomething("e").doSomethingElse("f", "g").print()
Or just don't put the parantheses in the vbscript when it complains...
See Differences between VBScript and JavaScript
Incidentally you can write a fluent API in VBScript. I built a library to facilitate inline creation of HTML to avoid the "tag soup" garbage and I'm using it in an app right now (that's how I found this question).
Here's an example with a couple helpers wrapping the 960gs grid:
with html
.open
with head
.open
stylesheet_link "assets/stylesheets/960gs/reset.css"
stylesheet_link "assets/stylesheets/960gs/960.css"
stylesheet_link "assets/stylesheets/960gs/text.css"
stylesheet_link "assets/stylesheets/app.css"
.close
end with
with body
.open
with grid_container(12)
.open
call main
.close
end with
.close
end with
.close
end with
And then main could be similar to this:
with grid_row
with grid_column(4)
.id "nav-left"
.open
with ul
.open
li.open.contains( link_to("Google", "http://google.com") ).close
li.open.contains( link_to_if(a > b, "Microsoft", "http://microsoft.com") ).close
li.open.contains( link_to_unless(a > b, "Apple", "http://apple.com") ).close
.close
end with
.close
end with
with grid_column("8 push_2")
.id "main-content"
.open
h1.open.contains("Title Here").close
do until recordset.eof
p.class("record").open.contains(recordset("column_name")).close
recordset.movenext
loop
.close
end with
end with
The way the lib is written it could generate XML with essentially zero effort, basically any tag language that has the "nested elements with attributes" structure.
Classic ASP looks the way it does because the people who use(d) it and the people who made the tutorials just threw it out there and didn't fully understand the language and good practices. So we are stuck maintaining meandering code vomit. But if you do it right it can start to look like ruby. Heck I even implemented some ruby iteration stuff using dynamic vbscript classes a few years ago just to see if I could do it and it worked, but I lost that code a long time ago. Point being that even though vbscript is limited it still has more capability than people give it credit for, they just usually don't do things as well as could be done.

Resources