Does c/c++/java/PHP have closure? - java

So far I only see closure in javascript:
var name=...;
$(..).onclick(function() {
//here I can reference to name
});
Does this feature exist in c/c++/java/PHP?
If exists,one hello world example available?

As for PHP, you can enable access to a specific variable inside a closure method like this:
$xVar = "var";
$closure = function() use ($xVar) {
echo $xVar;
}
$closure();
And it's also possible to alter this variable inside the closure:
$xVar = "var";
$closure = function($newVar) use (&$xVar) {
$xVar = $newVar;
}
$closure("new var content");

C no, as functions aren't first-class objects.
C++ not yet, but it does with the upcoming standard (commonly referred to as C++0x), with so called lambda expressions:
std::string name;
auto mylambda = [&](){ std::cout << name; };
// ^ automatically reference all objects in the enclosing scope.

C++11 has closures, as does PHP. Im not sure about Java.

At one point, closures (Project Lambda) were going to be part of Java 7, but they are currently listed as "Deferred to Java 8 or later".

http://en.wikipedia.org/wiki/Closure_%28computer_science%29#PHP
For PHP
<?php
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World');
$greet('PHP');
?>

PHP has those too, since 5.3. They're not as flexible (in that you can't use $this), but still very useful.
Lisp and its dialects also have closures.

For C, they are available as a non-standard extension called blocks.

Related

Nashorn access non-static Java method

In Java 7 (1.7), I could access a Java method from JavaScript by running this:
ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
jse.eval("importClass(net.apocalypselabs.symat.Functions);");
jse.eval("SyMAT_Functions = new net.apocalypselabs.symat.Functions();");
String input = "notify(\"Foo\");"; // This is user input
jse.eval("with(SyMAT_Functions){ "+input+" }");
Which would run the notify() function from the Functions java class:
public class Functions {
private Object someObjectThatCannotBeStatic;
public void notify(Object message) {
JOptionPane.showMessageDialog(null, message.toString());
}
/* Lots more functions in here, several working with the same non-static variable */
}
How do I access the Functions class in Java 1.8 with the Nashorn engine? My goal is to run different code for the first snippet if the user has Java 1.8, while still allowing people with 1.7 to use the app.
I've tried http://www.doublecloud.org/2014/04/java-8-new-features-nashorn-javascript-engine/ , https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html , and How to instantiate a Java class in JavaScript using Nashorn? without luck. None of them seem to allow me the same thing as Java 1.7 did, instead assuming I only want to access static functions and objects.
The most common error I get:
I start with...
ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
jse.eval("var SyMAT_Functions;with (new JavaImporter(Packages.net.apocalypselabs.symat)) {"
+ "SyMAT_Functions = new Functions();}");
...then...
jse.eval("with(SyMAT_Functions){ "+input+" }");
...spits out...
TypeError: Cannot apply "with" to non script object in <eval> at line number 1
I was able to reproduce. First of all, Nashorn doesn't try to make it difficult to use Java objects (non-static or otherwise) in general. I have used it in other projects and not had any major issue converting from Rhino in Java 7 beyond what is covered in the migration guide. However, the issue here appears to deal with the use of the with statement which is "not recommended" and is even disallowed in strict mode of ECMAScript 5.1, both according to MDN.
Meanwhile, I found a thread on the Nashorn-dev mailing list discussing a similar case. The relevant part of the response was:
Nashorn allows only script objects (i.e., objects created by a JS
constructor or JS object literal expression) as scope expression for
"with" statement. Arbitrary objects . . . can not be used as 'scope' expression for
'with'.
In jdk9, support has been added to support script objects mirror other
script engines or other globals (which are instances of ScriptObjectMirror).
It's not the most elegant solution but, without using JDK 9, I was able to get your intended use of with to function by writing a proxy object inside the Javascript to mirror the public API of the Java class:
package com.example;
import javax.script.*;
public class StackOverflow27120811
{
public static void main(String... args) throws Exception {
ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
jse.eval(
"var real = new Packages.com.example.StackOverflow27120811(); " +
"var proxy = { doSomething: function(str) { return real.doSomething(str); } }; "
);
jse.eval("with (proxy) { doSomething(\"hello, world\"); } ");
}
public void doSomething(String foo) {
System.out.println(foo);
}
}
Attila Szegedi pointed out the non-standard Nashorn Object.bindProperties function. While it can't be expected to work with anything but the Nashorn engine, it does eliminate the complexity of re-declaring all of the public API inside the proxy object. Using this approach, the first jse.eval(...) call can be replaced by:
jse.eval(
"var real = new Packages.com.example.StackOverflow27120811(); " +
"var proxy = { }; " +
"Object.bindProperties(proxy, real); " // Nashorn-only feature
);
I decided to compile and bundle the "old" Rhino interpreter with my application instead of using Nashorn.
https://wiki.openjdk.java.net/display/Nashorn/Using+Rhino+JSR-223+engine+with+JDK8

JavaScript in Android

Is it possible to use JavaScript in Android?? if so, how? Please provide some examples.
Thanks.
I am way late to the party here, but I had this exact need. iOS 7 now includes JavaScriptCore
natively and it is really easy to use (despite limited documentation). The problem is that
I didn't want to use it unless I could also use something similar on Android. So I created the AndroidJSCore project. It allows you to use your JavaScript code natively in Android without requiring a bulky WebView and injection. You can also seamlessly make asynchronous
calls between Java and Javascript.
Update 27 Mar 17: AndroidJSCore has been deprecated in favor of LiquidCore. LiquidCore is based on V8 rather than JavascriptCore, but works essentially same. See the documentation on using LiquidCore as a raw Javascript engine.
From the documentation:
... to get started, you need to create a JavaScript JSContext. The execution of JS code
occurs within this context, and separate contexts are isolated virtual machines which
do not interact with each other.
JSContext context = new JSContext();
This context is itself a JavaScript object. And as such, you can get and set its properties.
Since this is the global JavaScript object, these properties will be in the top-level
context for all subsequent code in the environment.
context.property("a", 5);
JSValue aValue = context.property("a");
double a = aValue.toNumber();
DecimalFormat df = new DecimalFormat(".#");
System.out.println(df.format(a)); // 5.0
You can also run JavaScript code in the context:
context.evaluateScript("a = 10");
JSValue newAValue = context.property("a");
System.out.println(df.format(newAValue.toNumber())); // 10.0
String script =
"function factorial(x) { var f = 1; for(; x > 1; x--) f *= x; return f; }\n" +
"var fact_a = factorial(a);\n";
context.evaluateScript(script);
JSValue fact_a = context.property("fact_a");
System.out.println(df.format(fact_a.toNumber())); // 3628800.0
You can also write functions in Java, but expose them to JavaScript:
JSFunction factorial = new JSFunction(context,"factorial") {
public Integer factorial(Integer x) {
int factorial = 1;
for (; x > 1; x--) {
factorial *= x;
}
return factorial;
}
};
This creates a JavaScript function that will call the Java method factorial when
called from JavaScript. It can then be passed to the JavaScript VM:
context.property("factorial", factorial);
context.evaluateScript("var f = factorial(10);")
JSValue f = context.property("f");
System.out.println(df.format(f.toNumber())); // 3628800.0
Do you mean something like making a native app using Javascript? I know there are tools like Titanium Mobile that let you make native apps using web tools/languages.
You could also make Web Apps. There are loads of resources and tutorials out there for that. Just search "Android Web App tutorial" or something similar.
Yes you can, just create a wrap up code that points to html page and includes your javascript and css.
There are different libraries that can help you with this:
http://www.phonegap.com/
http://www.sencha.com/products/touch/
http://jquerymobile.com/
Just posting this for posterity but React Native is a great solution in this space. You can write a complete app in JS using native views under the hood, or embed a JS component inside an existing Java app. https://reactnative.dev/

Why is Rhino unhappy with this javascript?

I have been successfully using my code with the javascript library in the ANTLR javascript target in a few browsers, but now I want to use Rhino on the server and I am having some trouble. I have some simple java code that references the Rhino 1.7R2 release's js-14.jar file.
Context context = Context.enter();
Scriptable scope = context.initStandardObjects();
context.evaluateReader(scope, new FileReader("C:\\antlr3-all.js"), "antlr", 1, null);
This fails with an EcmaError whose message is:
TypeError: Cannot call property namespace in object [JavaPackage org.antlr].
It is not a function, it is "object". (antlr#259)
The javascript line that it's referring to is:
org.antlr.namespace("org.antlr.runtime.tree");
This org.antlr.namespace was declared as a function earlier in the file, so I am not sure what to think of this. I also don't see that "namespace" is a reserved word in javascript or in Rhino in particular.
Here's the declaration of org.antlr.namespace at line 56:
org.antlr.namespace = function() {
var a=arguments, o=null, i, j, d;
for (i=0; i<a.length; i=i+1) {
d=a[i].split(".");
o=org.antlr.global;
// ANTLR is implied, so it is ignored if it is included
for (j=0; j<d.length; j=j+1) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
return o;
};
The ANTLR javascript target page mentions that Rhino is a tested platform, so I am thinking that I might just be misusing Rhino. Does anyone have any tips?
TypeError: Cannot call property
namespace in object [JavaPackage
org.antlr].
It takes your org.antlr as a java package and tries to make a call to the object namespace. So defining the function like this does not work.
Defining each part of the functions namespace by itself worked for me:
org = new function() {//Define the structure one piece at a time
this.antlr = new function(){
this.namespace = '';
return this;
};
return this;
};
org.antlr.namespace = function() {print('Help'); return 0;}
Sorry that I can't give a more detailed answer, I don't know mutch about javascript^^.
I guess that since org and org.antlr are undefined you can't assign to them.

Rhino, adding code from multiple javascript files

I am embedding some javascript in a Java application using Rhino. I am following the example on the Rhino website, executing a script by calling the Context's evaluateString method and passing the actual script in as a String.
I have a whole bunch of existing javascript code that I would like to make use of. I don't want to concatenate it all into an enormous String and pass it in to evaluateString. I would rather be able to load the code in so that I can call it from the code that I do pass into evaluateString (kind of like the AddCode method works in Microsoft's scripting control). I would like to add code like I can currently add variables by using the ScriptableObject.putProperty method.
Is there a way to do this? Can someone provide a code snippet or a link to the documentation. Thanks!
From the documentation and examples it looks like references to previously evaluated objects are controlled by scopes.
Context context = Context.enter();
try {
ScriptableObject scope = context.initStandardObjects();
Object out = Context.javaToJS(System.out, scope);
ScriptableObject.putProperty(scope, "out", out);
context.evaluateString(scope,
"function foo() { out.println('Hello, World!'); }", "<1>", 1, null);
context
.evaluateString(scope, "function bar() { foo(); }", "<2>", 1, null);
context.evaluateString(scope, "bar();", "<3>", 1, null);
} finally {
Context.exit();
}
(Rhino 1.7 release 2)
I know some people use Rhino directly to get the latest version, but the Java 6 implementation can evaluate scripts like this:
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
engine.eval("function foo() { println('Hello, World!'); }");
engine.eval("function bar() { foo(); }");
engine.eval("bar();");
In my code I had that need (utility scripts and such), and I just simply concatenated them together in a giant StringBuilder and evaled it (Java 6). Its the only way since javascript can't do (without Java wrapper objects) otherJSScript.someUsefulFunction().

How can I convert OO Perl to Java?

I inherited large monolithic body of OO Perl code that needs to be gradually converted to Java (per client request). I know both languages but am rusty on my Perl skills. Are there any tools (Eclipse plugins?) that you folks can recommend to ease the pain?
Does OO code use Moose? If yes, it is possible to convert class declarations automatically using introspection.
To gradually convert Perl to Java, you can include Java code into Perl program with Inline::Java.
There is Perl on JVM project, maybe it can be used to compile Perl to Java?
I'd say PLEAC is one of the greatest resources.
The inccode.com allows you to automatically convert the perl code to java code. Nevertheless the conversion of perl variables is slightly tricky due to dynamic typing in perl. The scalar variable in perl can contain the reference to any type and the real referenced type is known when the code is executed.
Translator uses VarBox class for encapsulating all predefined types: ref(HASH), ref(ARRAY) and BoxModule for encapsulating the reference to Perl Modules.
The example show perl script which call two modules to print “hello world”. The module LibConsole is instantiated in script and the module LibPrinter is accessed by calling the method in LibConsole.
#!/usr/bin/perl
use strict;
use test::LibPrinter;
use test::LibConsole;
hello_on_console( "hello world");
hello_on_printer( "hello world");
sub get_console
{
my $console = test::LibConsole->new();
return $console;
}
sub get_printer
{
##cast(module="test::LibPrinter")
my $printer = get_console()->get_printer();
return $printer;
}
sub hello_on_console
{
my ($hello) = #_;
my $console = get_console();
$console->output ($hello);
}
sub hello_on_printer
{
my ($hello) = #_;
my $printer= get_printer();
$printer->output ($hello);
}
Translator must now the types of both modules and while perl don’t define specific operators for declaring the object there’s an assumption that method named “new” return the reference to module. When the method which return reference to module is named otherwise the annotation cast(module=”{class}”) can be used to inform translator about the type of the module.
The identified type of the variable will be propagate because the translator control the conformity of types in assignments.
public class hello extends CRoutineProcess implements IInProcess
{
VarBox call ()
{
hello_on_console("hello world");
return hello_on_printer("hello world");
}
BoxModule<LibConsole> get_console ()
{
BoxModule<LibConsole> varConsole = new BoxModule<LibConsole>(LibConsole.apply());
return varConsole;
}
BoxModule<test.LibPrinter> get_printer ()
{
BoxModule<LibPrinter> varPrinter = new BoxModule<LibPrinter>(get_console().getModule().get_printer());
return varPrinter;
}
VarBox hello_on_console (VarBox varHello)
{
BoxModule<LibConsole> varConsole = new BoxModule<LibConsole>(get_console());
return varConsole.getModule().output(varHello);
}
VarBox hello_on_printer (VarBox varHello)
{
BoxModule<LibPrinter> varPrinter = new BoxModule<LibPrinter>(get_printer());
return varPrinter.getModule().output(varHello);
}
}
The translated code requires runtime library to be executed.

Categories