Clojure RT/Compiler: How to Iterate through forms? - java

I am working on a Java project that has some Clojure involved. I know how to run compile and run clojure code:
public static void main(String[] args) throws Exception {
RT.init();
runCode();
}
public static Object runCode() {
String str = "(ns my-ns)" +
"(defn add [a b] (+ a b))" +
"(println (add 1 2))";
Compiler.load(new StringReader(str));
/* I know how to invoke it: */
Var foo = RT.var("my-ns", "add");
return foo.invoke(1,2);
}
What would be very useful at the point is to have a way to iterate over forms in Java, and in some sense "analyze" the compiler output. Basic things I want to know is:
What is the text source of a form?
What function is being called in a form.
What arguments are being passed to the function (forms are ok)
Be able to do this on top level forms, or drill in as needed.
Is there a way to do this using the clojure compiler, or runtime (or other Java classes in Clojure?) I see such compiler methods as analyze, for example:
Expr target = analyze(C.EXPRESSION, RT.second(form));
Though its not clear to me yet how form was constructed, and there are no Javadoc :-). Do I need to go The Compiler Source and figure out how it works?

Related

Complete Current Statement behaves differently in Scala in IntelliJ

I recently upgraded my IDEA and now using IntelliJ IDEA 2022.2 Ultimate Edition.
I found the Complete Current Statement in Scala code behaves differently as in Java code, which is very annoying.
For example in Java code:
public static void main(String[] args) {
String foo = "bar"
}
Press Complete Current Statement shortcut(shift+cmd+enter for me) anywhere in line #2, will add a ; at the end of the line, and an auto-indent will be applied too:
public static void main(String[] args) {
String foo = "bar";
}
Then press Complete Current Statement again will bring you to a new line when there is nothing more to adjust.
public static void main(String[] args) {
String foo = "bar";
}
In previous version of IntelliJ, I roughly remember the behavior is same for Scala code.
But in this version of IntelliJ, when I try to do samething in Scala code, for example:
def foo (): Unit = {
throw new RuntimeException
}
When I press Complete Current Statement in line #2, nothing happens.
Could anyone please help me checkout why or how should I config to align with Java code's behavior? Thank you very much!
You don't need to use that in Scala because semicolons are optional, and almost never used. Actually, your Scala code sample is already what you would call a "complete statement".
For formatting what I do and recommend is having set File -> Settings -> Tools -> Actions on save and check Reformat code and optionally Optimize imports, and it will do both whenever you save your source file using Ctrl + S. I believe it's Cmd + S on your Mac.
This uses the default Intellij Formatter for Scala. Scala also has it's own Formatter called Scalafmt with customizable setups more control of formatting different Scala features based on your preferences. This is located at Settings -> Editor -> Code Style -> Scala.
If for some reason you would still like to use your shortcut key, then the only thing the Complete current statement can do to your Scala code is auto-indenting the current line, which for some reason it doesn't so it seems to be a bug on Intellij's side. But what you can do is replace the Auto-Indent Lines shortcut key to use your Complete current statement shortcut key instead and get the same behavior.

Creating a Java Object in Scala

I have a Java class "Listings". I use this in my Java MapReduce job as below:
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
Listings le = new Listings(value.toString());
...
}
I want to run the same job on Spark. So, I am writing this in Scala now. I imported the Java class:
import src.main.java.lists.Listings
I want to create a Listings object in Scala. I am doing this:
val file_le = sc.textFile("file// Path to file")
Listings lists = new Listings(file_le)
I get an error:
value lists is not a member of object src.main.java.lists.Listings
What is the right way to do this?
Based on what you've said, I think you may be forgetting the differences between Scala syntax and Java syntax.
Try this:
val lists: Listings = new Listings(SomeString)
Please note that specifying the type in Scala is completely optional. Also, use a var if you're going to be changing the value of lists.
The way you have it, Scala is trying to interpret it by its ability to call methods/access values of an object without the '.', so you're actually telling Scala this:
Listings.lists = new Listings(SomeString)

How to invoke Xtend code from Java?

I have a code generator, which takes a syntax tree and converts it into a source file (text).
Basically, it traverses through all nodes of the tree, maps the node to text and appends the resulting texts to a StringBuilder.
Now I want the node to text mappers to be implemented using Xtend like this:
public class NodeXMapper
{
private XtendRunner xtendRunner = ...;
public String map(final NodeX aNode)
{
return xtendRunner.runScript("def String map(NodeX aNode) {
''' «aNode.fieldX» - «aNode.fieldY» '''
}", aNode);
}
}
xtendRunner.runScript(String aScript, final Object... aParams) is a method, which passes the parameters aParams to Xtend script aScript and returns the result.
How can I implement that method?
Update 1: Here I found this piece of code, which seems to run Xtend code in Java:
// setup
XtendFacade f = XtendFacade.create("my::path::MyExtensionFile");
// use
f.call("sayHello",new Object[]{"World"});
But I can't find XtendFacade class in the Type hiearchy view of Eclipse.
The interpreter you found was for the old Xtend1 language, which is not what you are looking for.
The new Xtend you are referring to is compiled, so there is no interpreter.
However, you could build an interpreted expression language using Xbase. See the documentation and Github for an example on how to do that. Then you could run the interpreter of your expression language from Java.

Making A Javascript Function Available To Java Code

Problem Description
A somewhat contrived example to illustrate my question. Imagine we have some library of javascript functions that is already maintained and updated daily by an army of frontend devs. To be specific, imagine one such function looks like this:
function employeesForStore(store) {
var dictionary = {
"downtown": ["Joe", "Mary", "Steve"],
"uptown": ["Jules", "Vincent", "Matt"],
// and so on for hundreds of locations
};
return dictionary[store];
}
NOTE: Please ignore the details of this function's implementation. The actual function may be far more complex than simple JSON dictionary lookups, and assume we don't know any implementation details about the js function. All we know is it takes a String argument and returns and array of Strings.
Now we would like to take advantage of this function in our Java code. That is, in our Java code, we'd like to "load" this function, and then be able to call it multiple times, passing it String args and receiving String[] or ArrayList<String> results.
From searching SO and google so far, I understand that this will involve using:
javax.script.ScriptEngineManager
javax.script.ScriptEngine
and perhaps scriptEngine.getContext() for passing values into the function and receiving results.
I am a bit hazy on the details of the above, especially since most examples I've found involve running javascript code a single time, rather than making javascript function available to Java.
Example Code I'd Like To See
Assuming the js function is in the file "my_functions.js", load that file into Java so all of its functions will be available for use.
Call employeesForStore("downtown") and store its results in a native java String[] or List<String> in a variable called downtownResults.
Same as 2, but call employeesForStore("uptown") and store in variable uptownResults
Create an interface to act as a facade to your JavaScript code.
Here is an example using the Rhino implementation embedded in Oracle's Java 1.7 implementation:
package demo;
import java.io.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import javax.script.*;
public class StoreData {
public static interface Stores {
public String[] employees(String store);
}
public static Stores stores() throws IOException, ScriptException {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("JavaScript");
AtomicReference<Stores> ref = new AtomicReference<>();
engine.put("ref", ref);
String adapt = "ref.set("
+ "new Packages.demo.StoreData.Stores({employees:employeesForStore})"
+ ");";
try (Reader myFns = new FileReader("my_functions.js")) { // TODO encoding
engine.eval(myFns);
engine.eval(adapt);
return ref.get();
}
}
public static void main(String[] args) throws IOException, ScriptException {
List<String> employees = Arrays.asList(stores().employees("uptown"));
System.out.println(employees);
}
}
By specifying an interface we let Rhino coerce the JavaScript types to Java types (String, String[], etc.)
The JRE spec makes no guarantees about what scripting engines should be provided so it may be wise to rely on an external engine. I don't know if Nashorn will change this.
You can use Rhino API to execute JS code in java
This tutorial covers the examples requested.

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