Dear Clojurians,

I am very happy to announce Clojuratica version 2.

Clojuratica now offers the **syntactic** integration of Clojure and
Mathematica.

What does this mean? It means you can write Clojure code that looks like
this:

=> (FactorInteger 12345)
[[3 1] [5 1] [823 1]]

You guessed it. FactorInteger is a Mathematica function. And that's a
Clojure REPL.

Symbolic math in Clojure? Syntax-unquoting to feed in Clojure data
structures? Absolutely.

=> (Sqrt (* 9 a))
(* 3 (Power a 1/2))

=> (let [x [[2 1] [1 2]]]
     (CholeskyDecomposition ~x))
[[(Power 2 1/2) (Power 2 -1/2)] [0 (Power 3/2 1/2)]]

Note that the Clojure "matrix" (vector of vectors) is converted on the fly
to a Mathematica matrix, and vice versa. Automatic conversions take place
for all Clojure and Mathematica data structures.

There's more. Mathematica functions are now Clojure functions. The following
is a Mathematica function written in Clojure that finds the n shortest genes
in the human genome. (Mathematica has some cool functions like GenomeData to
try out.)

=> (Function [n]
     (Take
       (Sort
         (Map
              (Function [gene] [(GenomeData gene "SequenceLength") gene])
           (GenomeData)))
       n))
#<parse$parse_fn__1230$fn__
1234 clojuratica.base.parse$parse_fn__1230$fn__1...@19fa0b5>

What's that ugly return value? It's a first-class Clojure function. We
evaluated a Mathematica function in Clojure and got back a Clojure function
which, when we call it, hands off the computation to Mathematica and returns
the result:

=> (*1 4)
[[11 "IGHD727"] [16 "IGHD411"] [16 "IGHD417"] [16 "IGHD44"]]

All the power of Mathematica is now seamlessly available in Clojure. If you
like, you can think of Mathematica as a particularly mature Clojure library
for linear algebra, matrix decomposition, symbolic mathematics,
optimization, differential equations, symbolic and numerical integration,
Fourier analysis, 2D and 3D visualization, image and photo manipulation,
exploratory data analysis, probability and statistics, graph theory, number
theory, geodesy, and access to the Wolfram Research internet data feeds on
finance, chemistry, geometry, meteorology, astronomy, protein structure,
and, as we've seen, the human genome.

Let's take a step back and see how it all works.

Observe: Clojure and Mathematica are remarkably similar languages despite
their different areas of strength.

Constant-lookup arrays:

Clj vectors:  [1 2 3]
Mma lists:    {1, 2, 3}

Matrices as nested arrays:

Clj:  [[1 0] [0 1]]
Mma:  {{1, 0}, {0, 1}}

Function calls *always* use prefix notation:

Clj:  (func arg1 arg2 arg3)
Mma:  Func[arg1, arg2, arg3]

In Mathematica, common functions do have syntactic sugar, but it always is
just syntactic sugar:

Clj:  none
Mma:  1 + 1   is just   Plus[1, 1]
      !foo && (bar > baz)   is just   And[Not[foo], Greater[bar, baz]]

Homoiconicity:

Clj:  (nth '(func arg1 arg2) 1)   ==>   arg1
Mma:  Part[Func[arg1, arg2], 1]   ==>   arg1

The similarities suggest the core idea: Mathematica expressions can be
written as Clojure expressions without any loss of information, and vice
versa. There is perfect correspondence. Happily, Mathematica functions are
PascalCase by convention. This allows the interning of Mathematica functions
right into your Clojure namespace without conflict.

Mma:  FactorInteger[1091]
Clj:  (FactorInteger 1091)

Mma:  Function[{x}, x + 1]
Clj:  (Function [x] (Plus x 1))

The heart of Clojuratica is simple. Convert Clojure expressions to
Mathematica expressions, evaluate them in Mathematica, and parse the result
back into Clojure expressions.

As you will see in the tutorial on the Clojuratica web page <
http://clojuratica.weebly.com>, you are not forced to intern Mathematica
functions directly into your namespace. You may, but you do not have to. The
generic way to call Mathematica code is using the math macro (which you
yourself define, so it need not be called "math"):

=> (let [x "World"]
     (math (StringJoin "Hello, " ~x "! This is some Mathematica code's
output.")))
"Hello, World! This is some Mathematica code's output."

=> (def hello
     (math
       (Function [x]
         (StringJoin "Hello, " x "! This is a Mathematica function's
output."))))
#'user/hello

=> (hello "World")
"Hello, World! This is a Mathematica function's output."

There are other features, too:

    * A concurrency framework for multithreaded, parallel computation.
Mathematica is not designed for threads or concurrency. It has excellent
support for parallel computation, but parallel evaultions are initiated from
a single-threaded master kernel which blocks until all parallel evaluations
return. By contrast, Clojuratica includes a concurrency framework that lets
multiple Clojure threads execute Mathematica expressions without blocking
others. The computations will be farmed out to as many Mathematica kernels
as are parallelized on the local machine or across a cluster or grid. The
computations will return asynchronously, and some threads will go about
their business while others continue to wait. I have worked to make the
system as high-performance as possible.

    * Hashmap conversion. Mathematica has no map data structure, so I
include a basic one with Clojuratica, along with a few other helpful
Mathematica funcions and features (e.g. Let, with is akin to With but allows
later bindings to see earlier bindings, just like Clojure's let).

Version 2 of Clojuratica is a complete rewrite of version 1. It should be
considered alpha software for the time being. I would appreciate suggestions
and bug reports.

I plan to make the integration work in the opposite direction when I have
time. It might be a while! The Clojure-in-Mathematica integration that was
available in version 1 has been removed for now.

I encourage you to read the tutorial on the web page <
http://clojuratica.weebly.com>. You can download the software there as well.

I hope you enjoy it!

Garth Sheldon-Coulson

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to