Code Compilation of Java, Scala, C#, and F# Code

With JavaTools you can compile and instantly run Java, Scala, C#, and F# code provided as a string in Mathematica. For your requisite programming language, please see the respective section below. Near the end of this page we present a “platform shoot-out” speed comparison of the n-queens problem, using Mathematica running on Mathematica, Java running on JVM, Scala running on JVM, C# running on .Net, and F# running on .Net. All of these languages and platforms are easily accessible with the functions provided by JavaTools. You are encouraged to submit competing implementations in either language to info@lauschkeconsulting.net, if you think you have an implementation that beats the results presented here.

For a more detailed discussion on the merits of using Java, Scala, C#, and F# compilation and code execution directly from a Mathematica session, the reader is referred to www.lauschkeconsulting.net/nqueens.html. On that page we show the usefulness of quickly exploring solutions to difficult problems. With JavaTools the Mathematica programmer can mix different programming languages, execution platforms, programming styles, programming paradigms, and algorithmic approaches, all from one Mathematica session. Someone versed in all the languages supported by JavaTools (at this time: Java, Scala, C#, F#) can save a lot of time by using known best solutions or implementing/exploring one’s own solutions in a variety of languages. These days it is easy to find code snippets on the internet or in books and magazines. With JavaTools the Mathematica programmer can simply copy/paste that code and immediately compile and execute from the same Mathematica session, or modify the code to suit one’s needs, or explore various algorithmic approaches and methods to pick and choose. The whole environment makes it possible to “see” broader solutions, and explore a variety of solutions at once. This makes JavaTools an outstanding platform for interactively researching program design!

On that page we also show and explain some of the shortcomings of Mathematica's C compilation with examples.

Introduction

Why would I want to write and compile Java or Scala or C# or F# code directly from Mathematica? There are several reasons for that.

1. It simplifies Development.
If you write your own Java (or Scala or C# or F#) code, in the past the only way to use the resulting function library from Mathematica was to use an IDE such as Eclipse, NETBeans, IntelliJ, Visual Studio 2008, Visual Studio 2010, write your Java/Scala/C#/F# code, compile it, copy the resulting .class or .jar or .dll file to your Mathematica environment, and then load the Java libraries with JLink or the .Net assemblies with NETLink. If you actively develop/debug your code, which means writing it in the IDE and studying results in Mathematica, that is a tedious, repetitive process:

bug fix -> edit/fix/correct in IDE -> recompile -> copy library files to Mathematica environment -> kill kernel and restart and reinitialize your data -> reload JLink or NETLink -> run your function -> analyse results

If instead you can edit your code directly in the Mathematica front-end and compile it from there and immediately use the new symbol, then that simplifies the process tremendously. You never leave the Mathematica as your working environment.

2. It Simplifies Deployment.
You don’t have to include several .class and/or .jar or .dll files in your deployment. Your Java or Scala orr C# or F# code is simply in one or several strings in your Mathematica .nb or .m file that you have to deploy anyway. This keeps things neat and concise, instead of cluttered.

3. Automatic Code Generation in Mathematica
You can use the extremely advanced string manipulation functions in Mathematica to generate your code programmatically. You can write Mathematica code that generates your Java or Scala or C# or F# method, see some of the examples below.

4. Direct Access to all VM/Runtime Features/Classes
The entire feature set of the Java and .Net virtual machine/runtime is completely at your fingertips. The Java VM as well as the .Net or mono runtime provide extremely powerful classes/methods/algorithms, such as visual classes (Java: Swing, .Net: WinForms) or cryptography, concurrency frameworks, encryption/decryption frameworks, i/o, network connections and their management, Java beans, object-oriented programming, inheritance/polymorphism, etc. JavaTools exposes the entire feature set of the VM/runtime you are using, it creates no encumbrances on what you can access. You can use ANY Java or .Net class. In most cases it’s MUCH easier to use a class/method that is included in Java or .Net, than writing it yourself.

Concentrating merely on concurrency for this paragraph, both Java and .Net have enormously powerful concurrency frameworks immediately accessible by you through JavaTools. Since version 7 Java also includes the new fork/join framework, and parallelism is made extremely easy especially in Scala and F# where certain functions automatically run in parallel threads if properly written (using concurrent collections in Scala or using the asynchrous workflow concept in F#): the entire thread management in terms of thread creation, thread scheduling, thread destruction asf. is happening magically “under the hood” without you being required to write anything for this (in Java and C# that is a bit more involved, but not too hard to do). The prime numbers example in the Scala and F# sections below show that in Scala and F# you can invoke the concurrency framework of Java and .Net with virtually no additional effort at all. This is practically “auto parallelism”. You effectively get complete parallelization of your Scala or .Net methods by merely “hinting” at that intention.
If you have hardware with 8 - 16 (or more) cores, you can exploit concurrency to the fullest. Parallelism performance scales up according to Amdahl’s Law, and you get concurrency performance not achievable with Mathematica alone by running computations or other processing in concurrent threads. JavaTools’ JavaCode[], ScalaCode[], CSharpCode[], and FSharpCode[] allow you to write functions that run in concurrent threads, directly from Mathematica.

Java contains a huge number of high-level classes/objects written by some of the best Java implementors world-wide (Java is now open source, which means it contains contributions from the whole world-wide contributor community). .Net is not open source, but it also contains some extremely powerful algorithms/classes written by some of the best professionals in this business.

Note that the Java or Scala or C# or F# code you write is not scripted. You get the full speed of *compiled* code! The actual code execution happens in the Java VM or .Net  (or mono) runtime. The speed is the same as if you were running your function from a Java/Scala/C#/F# application. Except, you control it from Mathematica.

Comparison to an IDE

Although the code writing and compilation features of JavaTools cannot compare with the rich feature set of an IDE with all its bells and whistles, it includes the most important IDE features directly from Mathematica:

◆ complete compilation of correct Java/Scala/C#/F# code
◆ immediate availability of the library that contains your code: auto symbol-loading
◆ showing you where the errors are in case of non-compiling code: line numbers, arrows, error types, error descriptions
◆ basic syntax highlighting

You can do much more in an IDE, but then your focus is more on dedicated code development outside of Mathematica. These JavaTools features let you hit the ground running without having to change your working environment.

Using JavaCode[] Directly

The next few sections focus on Java code. For Scala, C#, and F# code compilation, please scroll further down.

In the first example we create a 1024 bit-strength DSA public/private key pair and sign a local file with a signature derived from the private key and output the signature, the encoded form of the public key, and the base of the public key. We use some cryptography classes from Java for this.

In[2]:=

jcc_1.gif

jcc_2.gif

jcc_3.gif

We can even use the Java console:

In[3]:=

jcc_4.gif

jcc_5.gif

jcc_6.gif

jcc_7.gif

jcc_8.gif

jcc_9.gif

Using a Java Cell with JavaCell

You can create a JavaTools Java cell simply by typing JavaCell:

jcc_10.gif

Upon submitting Shift+Enter the cell will be replaced by a new cell that we refer to as a “Java code cell” within JavaTools:

Enter Java code for a static Java method here.


You can now type the code for your Java method directly in that cell:

In[4]:=

final int add200(final int number){return 200+number;}


Upon submitting Shift+Enter JavaCode[] is called with your code for the Java method, it is compiled (if no errors are detected), and if it contained no errors (compilation succeeds), a new symbol is set up that can be used directly, as with JavaCode[]:

jcc_11.gif

jcc_12.gif

The Java cell provides basic syntax highlighting and bracket/brace/parenthesis-matching. Reserved keywords are in magenta, numbers are in blue, and identifiers are in black (like in Eclipse), bracket/brace/parenthesis-matching happens by showing the matching bracket/brace/parenthesis in red. In the following example the cursor “stands” on the right parenthesis, note that this parenthesis and its matching left parenthesis are both in red:

final int add300(final int number){return 300+number;}


The syntax highlighting happens “live” as you type/edit the Java cell:

final int add400(final int num


You can copy/paste a Mathematica string with Java code into a Java cell. The following example shows the DSAsolution code from above, copy/pasted into a Java cell:

final String[] DSAsolution(String filename) throws Exception
    {
        
java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance("DSA");
        
java.security.SecureRandom random = java.security.SecureRandom.getInstance("SHA1PRNG", "SUN");
        kpg.initialize(1024, random);
        java.security.KeyPair kp = kpg.genKeyPair();
        java.security.KeyFactory fact = java.security.KeyFactory.getInstance("DSA");
        java.security.spec.DSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(),java.security.spec.DSAPublicKeySpec.class);
        java.security.PrivateKey privateKey = kp.getPrivate();
        java.security.Signature dsa = java.security.Signature.getInstance("SHA1withDSA", "SUN");
        dsa.initSign(privateKey);
        java.io.FileInputStream fis = new java.io.FileInputStream(filename);
        java.io.BufferedInputStream bufin = new java.io.BufferedInputStream(fis);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bufin.read(buffer)) >= 0) {
            dsa.update(buffer, 0, len);
        };
        bufin.close();
        byte[] realSig = dsa.sign();
        String[] returns=new String[3];
        returns[0]=new String(realSig);
        returns[1]=new String (kp.getPublic().getEncoded());
        returns[2]=pub.getG().toString();
        return returns;
    }


Special thanks to Leonid Shifrin for providing the syntax highlighter to JavaTools!

Further Examples

Strings in the Java method code have to be escaped, as JavaCode[] needs a valid code string to compile:

In[5]:=

jcc_13.gif

jcc_14.gif

jcc_15.gif

If you have an error in your Java code that prevents compilation, JavaTools will pop up a dialog box informing you about the error. The dialog box shows all errors found, their line numbers, and the error types. Note the stray “n” character at the end of “return”:

jcc_16.gif

jcc_17.gif

As mentioned earlier, the use of JavaTools[] is not limited to math-arithmetic / numeric functions (this is, in fact, a major advantage over the Mathematica compiler, including its C compilation, as Mathematica can only compile numeric expressions, see the discussion below). Any Java method that can be written as a static method can be used, including visual (Swing) classes, or others that require object instantiations (see first example on this page). Here we create a modal dialog box with a pull-down menu to let the user make a selection and return that selection, with just a few lines of Java code:

In[6]:=

jcc_18.gif

jcc_19.gif

jcc_20.gif

jcc_21.gif

The code HAS to be correct and compile fully through as Java code, or JavaCode[] will not set up a Mathematica symbol for the method name. Bear in mind, the string passed to JavaCode[] is ACTUAL Java code that is compiled and executed! Whatever you write in the Java method, it will execute on the JVM, and therefore has to compile correctly.

One could now even use Mathematica's advanced string manipulation functions to construct the string of Java code. For example, in the previous example the list of game choices could be a Mathematica string, or be computed as a Mathematica string, based on other functions written in Mathematica.

The following creates Java Swing code for four different Java Swing dialog box types and sets up the corresponding Mathematica symbols by mapping JavaCode[] over a list of Mathematica strings representing the dialog box message types:

jcc_22.gif

jcc_23.gif

jcc_24.gif


In the following example we define the first 8 Chebyshev polynomials, which are defined as

jcc_25.gif

and store them in Java as “indexed functions” or “associative arrays” with an integer index.

jcc_26.gif

jcc_27.gif

jcc_28.gif

C# Code Compilation

On .Net or mono systems JavaTools also supports C# code compilation:

In[7]:=

jcc_29.gif

Out[7]=

jcc_30.gif

jcc_31.gif

jcc_32.gif

We can use the console as well:

In[8]:=

jcc_33.gif

Out[8]=

jcc_34.gif

jcc_35.gif

jcc_36.gif

jcc_37.gif

jcc_38.gif

jcc_39.gif

If your code contains at least one syntax error, you will get compiler errors. JavaTools fully exposes all generated errors and display them so you can debug your code. In the following example note that it says Coss instead of Cos:

jcc_40.gif

jcc_41.gif

jcc_42.gif

jcc_43.gif

Some .Net assemblies are not part of a standard start-up. For example, to use Windows Forms, you have to add the System.dll and System.Windows.Forms.dll yourself. This is like in Visual Studio: when you create a Windows Forms application, you have to add the System.dll and System.Windows.Forms.dll yourself to the project references to be able to use them. Therefore CSharpCode[] has an optional second argument where you can specify the .Net assemblies you need to add to be able to use its classes. The following example creates a simple WinForms window with C# code, but we have to add two assemblies for that:

In[9]:=

jcc_44.gif

Out[9]=

jcc_45.gif

jcc_46.gif

jcc_47.gif

jcc_48.gif

If you don’t include the list of required assemblies, the .Net compiler for C# will throw appropriate error messages:

jcc_49.gif

jcc_50.gif

jcc_51.gif

jcc_52.gif

Here we create a modal dialog (similar to the model dialog for JavaCode[] above). We use four standard .Net classes, all from System.Windows.Forms:

In[10]:=

jcc_53.gif

Out[10]=

jcc_54.gif

jcc_55.gif

jcc_56.gif

jcc_57.gif

Using a C# Cell with CSharpCell

Just like with JavaCell, you can create a JavaTools C# cell simply by typing CSharpCell:

jcc_58.gif

Upon submitting Shift+Enter the cell will be replaced by a new cell that we refer to as a “C# code cell” within JavaTools:

Enter C# code for a static C# method here.


You can now type the C# code for your .Net method directly in that cell:

In[11]:=

int add200dotnet(int number) {return 200+number;}

Out[11]=

jcc_59.gif

Upon submitting Shift+Enter CSharpCode[] is called with the user’s code for the C# method, it is compiled (if no errors are detected), and if it contained no errors (compilation succeeds), a new symbol is set up that can be used directly, as with CSharpCode[]:

jcc_60.gif

jcc_61.gif

We can use copy/paste as well:

void sortdemo(){
System.Collections.Generic.List<string> mylist = new System.Collections.Generic.List<string>();
mylist.Add("one");
mylist.Add("two");
mylist.Add("three");
mylist.Add("four");
mylist.Add("five");
mylist.Add("six");
mylist.Add("seven");
mylist.Add("eight");
mylist.Add("nine");
mylist.Add("ten");
mylist.Sort();
foreach(string s in mylist) System.Console.WriteLine(s);
}

jcc_62.gif

Again special thanks to Leonid Shifrin for providing the syntax highlighter to JavaTools!

F# Code Compilation

On .Net or mono systems JavaTools also supports F# code compilation. F# is an extremely powerful evolving functional programming language developed by Microsoft running on the .Net platform. It is very concise and efficient. The functional programming paradigm that Mathematica programmers should already be familiar with is the key concept that makes F# so powerful and efficient. All classes from the .Net runtime are accessible, so F# programmers don’t have to forego the classes they are already familiar with from their C# development (interoperability). In addition, F# has a few classes and constructs of its own which enhance the usefulness of F# even further.
Note that indentation in F# IS important! Unlike most programming languages, indentation in F# DOES have a syntactic meaning!

We start with a very simple example. The following simply implements the factorial funcion in F# using recursion:

In[12]:=

jcc_63.gif

jcc_64.gif

jcc_65.gif

The same can be obtained by using the F# pattern matcher:

In[13]:=

jcc_66.gif

jcc_67.gif

jcc_68.gif

In the next example we write a function to compute the square root of a number using Newton’s convergence method. This example shows the use of recursion, private scoped inner functions, and throwing exceptions.

In[14]:=

jcc_69.gif

jcc_70.gif

jcc_71.gif

JavaTools fully advances the exception to the top and shows you the actual exception thrown in .Net due to the failwith statement included in your F# function:

jcc_72.gif

jcc_73.gif

jcc_74.gif

The following example shows that JavaTools fully exposes all .Net objects you want returned. The function hours2weeks returns a .Net object and NOT a native type! This makes it easy to further process .Net objects in Mathematica using NETLink.

In[15]:=

jcc_75.gif

1728 hours is equivalent to 10 weeks and 2 days and 0 hours:

jcc_76.gif

jcc_77.gif

As a sidenote, this example also shows that in F# it IS possible to have a parameter on the left-hand side of an equation and assign. This is due to the fact that by default all symbols in F# are not (mutable) VARIABLES, but (immutable) symbols with VALUES associated with them. Note that h is passed in the function call, but subsequently h is found on the left-hand side of the equation, which is not possible in most programming languages. This is because h is not mutable (which means its memory would be overwritten with a new value in an assignment), but a new symbol is created with the same name h, it receives a value associated with its name h, and its former value is not overwritten, but hidden under the new symbol h. This can be very efficient, as it removes the need to use additional temporary variables.
The example also shows how easy it is to write inner private functions in F#. divAndRem is a private function of hours2weeks, it’s implemented almost like a symbol assignment, and it’s scoped. For an F# beginner it is in fact quite easy to miss that divAndRem is an inner private scoped function!

In the following example we use a .Net class, System.DateTime. JavaTools provides full access to all .Net classes (mono as well) just like with C#. And again, like in the previous example, we expose the full .Net object, not just a result of a native type. That way we can extract data by using properties and methods from the returned .Net object.

In[16]:=

jcc_78.gif

jcc_79.gif

jcc_80.gif

jcc_81.gif

jcc_82.gif

jcc_83.gif

jcc_84.gif

jcc_85.gif

jcc_86.gif

You can define your own operators, functions, and pattern matchers. In a pattern matcher the first match is returned.

In[17]:=

jcc_87.gif

jcc_88.gif

jcc_89.gif

Just like with CSharpCode[], you have to specify the assemblies that are needed by your function but are not part of the standard start-up. Therefore FSharpCode[] has an optional second argument where you can specify the .Net assemblies you need to add to be able to use its classes. The following example creates a simple WinForms window with F# code, but we have to add two assemblies for that:

In[18]:=

jcc_90.gif

jcc_91.gif

jcc_92.gif

If you don’t include the list of required assemblies, the .Net compiler for F# will throw appropriate error messages:

jcc_93.gif

jcc_94.gif

jcc_95.gif

jcc_96.gif

The following example uses the System.Net namespace in .Net to output all IP addresses for the computer that is running. Note that we have to add the System.Net.dll manually as it is not part of the standard start-up:

In[19]:=

jcc_97.gif

In[21]:=

jcc_98.gif

Out[21]//TableForm=

fe80::4472:797a:41bf:45fc%10
fe80::c89:438f:257a:310f%17
192.168.1.100
192.168.56.1

There is nothing F#-specific in this, we could have used CSharpCode[] to accomplish the same (see below). But F# is generally much more concise, and F# also has a feature called automatic type inference. For example, the code above shows that we don’t have to know the return type. In C# / CSharpCode[] we have to specify the return type, but note that in this FSharpCode[] example we didn’t have to do this. We don’t have to worry about the return type of iphostentry.AddressList, we can simply use it and return it without having to know what its type is. This is true not only for the function return type, but also for all assignments in the function itself. Note that the type of myhostname is inferred from the right-hand side, and the type of iphostentry is inferred from the right-hand side as well. This is similar to var in C#, but it doesn’t have to be written, and var can only be used in a local variable declaration, not as a method return type. In other words, we couldn’t write this method as a C# method without knowing what type iphostentry.AddressList actually is (it’s System.Net.IPAddress[], or an array of System.Net.IPAddress objects):

In[20]:=

jcc_99.gif

Out[20]=

jcc_100.gif

jcc_101.gif

fe80::4472:797a:41bf:45fc%10
fe80::88b:8e7:3f57:fe9b%11
192.168.1.100
2001:0:4137:9e76:88b:8e7:3f57:fe9b

But this requires us to know more than we’d have to know and is more explicit and elaborate and not as “zippy” as the F# version.

F# supports a very efficient “pipeline” operator, similar to the “pipe” | on Linux/Solaris/Unix systems. With |> the result is simply “piped” to the next function. In the next example we simply compute the day a week from today by “piping” 7 (days) to the AddDays method of a DateTime object:

In[21]:=

jcc_102.gif

jcc_103.gif

jcc_104.gif

Nested pipes can make for extremely efficient and concise code (like using grep or cut or sed from the Linux/Solaris/Unix command line).

The following example shows how easy it is in F# to run independent tasks in concurrent threads when using an asynchronous workflow. The author of JavaTools can not think of an easier or more concise and succinct way to invoke the .Net concurrency framework. Obviously, as Mathematica users we don’t need .Net to compute prime numbers fast (in JavaTools we also have JEulerSieve[], which beats even Mathematica), but the point here is to demonstrate very code-efficient ways to invoke the concurrency framework of the underlying platform (here: .Net).

In[22]:=

jcc_105.gif

Here we show all primes between 1,000,000 and 1,002,000, generated in parallel threads:

jcc_106.gif

jcc_107.gif

With that number range we can merely see a blip in the Task Manager as the parallel execution is threaded over the 8 cores. It is so fast that we have to make the number range really big in order to be able to see the 8 cores getting nearly pegged in the Windows Task Manager:

jcc_108.gif

jcc_109.gif



Just like with JavaCode[] and CSharpCode[], the JavaTools function FSharpCode[] shows you the compile errors generated when the code of the function has errors. This is the factorial function example from above, but note that we use nn instead of n in the else part to generate a compilation error:

jcc_110.gif

jcc_111.gif

jcc_112.gif

Using an F# Cell with FSharpCell

Just like with JavaCell and CSharpCell, you can create a JavaTools F# cell simply by typing FSharpCell:

jcc_113.gif

Upon submitting Shift+Enter the cell will be replaced by a new cell that we refer to as a “F# code cell” within JavaTools:

Enter F# code for an F# method here.


You can now type the F# code for your .Net method directly in that cell:

In[23]:=

let add300fsharp (h : int) =
     h+300

Upon submitting Shift+Enter FSharpCode[] is called with the user’s code for the F# method, it is compiled (if no errors are detected), and if it contained no errors (compilation succeeds), a new symbol is set up that can be used directly, as with FSharpCode[]:

jcc_114.gif

jcc_115.gif

We can use copy/paste as well:

let (/%) x y = x % y = 0
  let multipleof = function
  | x when x /% 15 -> \ M15 \
  | x when x /% 3  -> \ M3 \
  | x when x /% 5  -> \ M5 \
  | x              -> x.ToString()


Again special thanks to Leonid Shifrin for providing the syntax highlighter to JavaTools!

Scala Code Compilation: ScalaCode[]

WARNING: Note that the Scala code compilation takes MUCH longer to complete than the Java, C#, or F# code compilations. This is entirely normal and to be expected (for various technical and legacy reasons not explained here), but keep in mind that the Scala code executes on the Java Virtual Machine (JVM), guaranteeing extremely fast code exeucution (in fact, the examples below suggest that Scala code executing on the JVM even beats C# or F# code executing on the .Net runtime!) -- and the performance enhancements as seen from the user’s perspective are not based on compile times, but execution times on the virtual machine / runtime! Most practitioners agree that compile times are irrelevant, what matters for benchmarking are the execution times. And it seems by now Scala on the JVM beats F# on .Net.

We begin with a very simple example. As above, we use the factorial function, in a recursive manner, to get us started:

In[24]:=

jcc_116.gif

jcc_117.gif

jcc_118.gif

Scala is primarily a functional programming language, but despite of  that it offers full access to the underlying virtual platform (Java or .Net, depending on your installation -- you can actually choose either Java or .Net, or both!).

In the following example we show a very simple Scala implementation of quicksort using the functional programming paradigm that we are already familiar with from Mathematica. Note how concise and compact the Scala code is:

In[25]:=

jcc_119.gif

In[26]:=

jcc_120.gif

Out[26]//Short=

jcc_121.gif

jcc_122.gif

jcc_123.gif

Keeping things in the spirit of previous examples, in the next one we show a recursive function that computes the square root of a given number (again, as above):

In[27]:=

jcc_124.gif

jcc_125.gif

jcc_126.gif

Check the answer:

jcc_127.gif

jcc_128.gif

Here we use a very simple functional expression (called first-order functions in Scala). _+_ adds two numbers

In[28]:=

jcc_129.gif

jcc_130.gif

jcc_131.gif

2*_ multiplies with 2.

In[29]:=

jcc_132.gif

jcc_133.gif

jcc_134.gif

With Scala you have full access to ALL classes/objects of the underlying platform (at this time: Java and .Net). In the following example we make use of access to the Java classes available to the Scala programmer (.Net class access would be similar). We want to see the current date formatted in French date format:

In[30]:=

jcc_135.gif

jcc_136.gif

jcc_137.gif

Note in the code above that we have used the Java libraries provided with the Java JDK, but the code is written entirely in Scala code syntax (but it uses Java classes).

Java varargs can be easily used in Scala as well:

In[31]:=

jcc_138.gif

jcc_139.gif

jcc_140.gif

In the following example we show parallel computation of all primes in a given range. Like above in the F# example, we want to use all cores available (8). However, in Scala, invoking the concurrency framework is even easier than in F#. All we need to do is insert “.par” on a collection (in this case: a Scala List) to make it a concurrent collection. The subsequent methods (in this case: filter(...)) is then used over multiple threads automatically. If we leave out the “.par” in the last line, we would get the single-threaded version. So we can actually do it with a mere five lines of Scala code, even less than what we needed in F#:

In[32]:=

jcc_141.gif

jcc_142.gif

jcc_143.gif

Here we use our concurrent prime computation method with the same parameters as in the F# example above. It is much faster (it executes on the same machine!).

jcc_144.gif

jcc_145.gif

jcc_146.gif

We need to make the problem bigger to get execution times that are closer to the F# version above:

jcc_147.gif

jcc_148.gif

jcc_149.gif

jcc_150.gif

JavaTools makes it easy to write Scala programs that use external third-party libraries. All you need to do is create a subdirectory called lib under the scalaprojects directory: That would be ToFileName[{$HomeDirectory,”scalaprojects”,”lib”}]. Then you simply copy all external .jar files into this new lib directory. In your Scala code you can then use import or use the full class name of the class(es) to be instantiated. In the following example we create a drum computer using the JFugue package from jfugue.org (Thanks to David Koelle).

In[33]:=

jcc_151.gif

When we call our function setrhythm[] we play our drum sequence:

In[21]:=

jcc_152.gif

This example also demonstrates full Java/Scala interoperability. The JFugue package was written in Java when Scala didn’t exist yet and is 100% Java code. But Scala and Java are completely byte-code compatible. For the JVM it doesn’t matter that the Rhythm and Player classes used above were implemented in Java but that we are using them with Scala code now.

But C is so much faster

Since the introduction of C code compilation in version 8 many people believe that they could simply compile their Mathematica codes to C and get the fastest possible code execution and wouldn't have to worry about anything. This is generally not true. The author of JavaTo
ols sees the following problems with automated Mathematica-to-C-code conversion:
◆ The Mathematica-to-C-code conversion requires an external C compiler installed. Without an external compiler this is not possible.
◆ It's not possible to install a compiler on all machines. There can be technical restrictions or company policies barring the installation of an external C compiler. Thus it can be a deployment problem.
◆ 64 bit compilation is not supported. Mathematica’s C compilation is limited to 32 bit arithmetic. That can be VERY restricting.
◆ C code is platform-dependent. This can be a deployment problem.
◆ SELinux may prevent the compilation and/or C code execution. Wolfram Research does not provide policy modules for SELinux.
Mathematica-to-C-code conversion uses LibraryLink, which is not a stable link. Unlike MathLink, a bug/crash in ANY of the libraries will automatically crash the WHOLE kernel, not just the affected library or link. This creates a dependency and stability problem. Even minor problems in an external library can take down the whole kernel, along with all other open links (e. g. database links or web services links). In other words, LibraryLink is not resilient.
◆ Some Mathematica codes don't fully compile to C code although the programmer thinks they do. For example, when an If-statement is used that doesn't have a then-clause, the Mathematica-to-C-code conversion includes a statement that calls back to the Mathematica kernel, which is totally unnecessary. This can only be found by inspecting the machine code statements with CompilePrint. A seemingly simple If-statement in Mathematica makes unnecessary calls back to the kernel that should not happen and can only by found with CompilePrint.

Java code exeution, managed from Mathematica, however, provides the following advantages:
◆ Java is a managed environment. Unlike C code, Java code executes in a virtual machine which provides many advantages over raw machine code execution, such as stability, user-defined runtime options, memory management, garbage-collection, error-handling, array bounds checking, etc. C has no garbage collecctor and no array bounds checking.
◆ Java allows the user to configure the virtual machine with runtime options, for example for memory usage, method-inlining, aggressive compilation, etc. There is no equivalent for that with C or C# code (the .Net runtime can NOT be configured by the user).
◆ Full 64 bit support, no 32 bit limitation.
◆ Although Java code executes in the virtual machine, a modern HotSpot VM automatically compiles the interpreted bytecode into machine code when it notices that a certain code branch is executed frequently (is "hot", hence the name HotSpot Virtual Machine). This is called "warm-up". Now the method executes with machine code speed. In addition, when parameters in the VM change over time (memory, other functions getting compiled to machine code, etc.) a HotSpot VM automatically recompiles the code to new machine code. This feature is called dynamic code (re)compilation. Unlike C or C# code, which is statically compiled (only once, for ever), a HotSpot VM recompiles the code occasionally as system and runtime parameters change. In fact, this can even happen WHILE a method executes, this is called OSR technology (On-Stack Replacement). This means due to dynamic code recompilation the machine code is dynamically adapted to the changing environment of the system. http://en.wikipedia.org/wiki/Dynamic_recompilation
◆ The slight speed disadvantage that Java still has compared to C code is getting slimmer and slimmer. As the Java VM matures, Java code automatically gets faster.  In general, Java is dynamically evolving, is mostly open-source, and includes features and innovation from the world-wide Java community.
◆ The entire Java technology platform is at the programmer's disposal when using JavaCode[]. This includes, for example, the concurrency framework, the security framework, the cryptography framework, Swing (see example above), and many others. Such platforms are not available through the Mathematica-to-C-code conversion mechanism. The author of JavaTools has written several advanced applications that harness the concurrency framework of Java to accelerate numeric computations.  These applications scale with the number of cores present on the machine on which JavaCode[] is executing according to Amdahl's Law. The corresponding parallel versions written for C are still a bit faster, but due to the stability and independence reasons mentioned above the author of JavaTools prefers to execute parallelized code with the Java concurrency framework, instead of parallel threads in C.

For a more detailed discussion of the advantages and limitations of the Mathematica compiler (including C compilation), the reader is referred to

http://mathematica.stackexchange.com/questions/1803/how-to-compile-effectively

Quoting in particular an incomplete list of limitations posted by Leonid Shifrin (thanks Leonid for your thorough top-level view):

◆ Can only accept regular arrays (tensors) of numerical or boolean types. This excludes ragged arrays and more general Mathematica expressions.
◆ In most cases, can only return a single tensor of some type
◆ Only machine-precision arithmetic
◆ From the user-defined functions, only pure functions are compilable, plus one can inline other compiled functions. Rules and “functions” defined with rules are inherently not compilable.
◆ No way to create functions with memory (a-la static variables in C)
◆ Only a small subset of built-in functions can be compiled to byte-code (or C)
◆ Possibilities for writing recursive compiled functions seem to be very limited, and most interesting cases seem to be ruled out
◆ No decent pass-by-reference semantics, which is a big deal (to me anyways)
◆ You can not really use indexed variables in Compile, although it may appear that you can.
◆ ...

The author of JavaTools strongly considers ragged arrays, functions with memory, recursion, pass-by-reference, index variables (sometimes called “associative arrays”, for example in perl) very important programming tools. The Mathematica compiler does not support them.

The author of JavaTools invites comments on this matter at info@lauschkeconsulting.net.

Spikey Created with Wolfram Mathematica 8.0