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