Clojure’s growing popular mind share

Popular interest in Clojure has rapidly increased over the last few years since 2008, almost to the level of Java (the language) today, which has dropped off significantly. (At least according to Google web trends.)
In contrast, popular interest in Common Lisp seems to have dropped off steadily since 2004.

Clojure vs. Java vs. Common Lisp

I used “java language” instead of “java” because it is ambiguous enough to mean the language, framework, JVM, the island or the coffee.

My earlier outlook on Clojure’s prospects circa 2009.

Purely Functional Data Structures & Algorithms : Selection Sort

*Updated @ 2012-08-31 02:08:58 due to internet pedantry*

Previously, previously.

According to Wikipedia :

In computer science, a Selection sort is a sorting algorithm, specifically an in-place comparison sort. It has O(n2) time complexity, making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort is noted for its simplicity, and also has performance advantages over more complicated algorithms in certain situations, particularly where auxiliary memory is limited.

(A functional implementation of selection sort is however, not an in-place sort.)
Behold the abomination which is the imperative implementation (from the Wikipedia link) :

int i,j;
int iMin;

for (j = 0; j < n-1; j++) {
    iMin = j;
    for ( i = j+1; i < n; i++) {
        if (a[i] < a[iMin]) {
            iMin = i;
        }
    }

    if ( iMin != j ) {
        swap(a[j], a[iMin]);
    }
}

Now, the functional equivalent in Haskell :

selectionSort :: [Int] -> [Int] -> [Int]
selectionSort sorted [] = reverse sorted
selectionSort sorted unsorted = selectionSort (min:sorted) (delete min unsorted)
                     where min = minimum unsorted

Or in Shen :

(define selection-sort-aux
  { (list number) --> (list number) --> (list number) }
  Sorted []       -> (reverse Sorted)
  Sorted Unsorted -> (let Min (minimum Unsorted)
        (selection-sort-aux (cons Min Sorted) (remove-first Min Unsorted))))

Yes. These functional snippets use their respective implementations of the list type (which is not an efficient persistent data type in either Haskell or Shen for accesses or updates). Replacing the List type with Data.Sequence(a persistent data type with efficient constant access and update) for the Haskell snippet is trivial. I’ll leave that as an exercise to the reader. Shen is too new to support these efficient persistent types at the moment but implementations will appear in the future and changing the snippet would also be trivial. A Clojure implementation using it’s already built in efficient persistent types would also be trivial.

The complete code can be found here.

Purely Functional Data Structures & Algorithms : Union-Find

It’s been a while since I last posted in this series. Today we look at the disjoint-set data structure, specifically disjoint-set forests and the complementary algorithm : union-find.

In computing, a disjoint-set data structure is a data structure that keeps track of a set of elements partitioned into a number of disjoint (nonoverlapping) subsets. A union-find algorithm is an algorithm that performs two useful operations on such a data structure:

  • Find: Determine which subset a particular element is in. This can be used for determining if two elements are in the same subset.
  • Union: Join two subsets into a single subset.
My inspiration comes from Sedgewick and Wayne’s class over at Coursera : Algorithms, Part I. So check the class out if you are unfamiliar with this and interested in the details.
I’m always curious how data structures and algorithms translate from their imperative counterparts(usually in Java) which are the norm for most classes on the subject and in most textbooks.
I think that this is a very unexplored part of the field of study in comparison with the usual approach to algorithms and data structures. So here we go with another example.
As before, we are using Shen as our implementation language.
First we define our disjoint-set type.
\**\
\* Disjoint set data type (weighted and using path compression) demonstrating  *\
\* 5(m + n) worst-case find time *\
\**\
(datatype disjoint-set
 Count : number ; Ids : (vector number) ; Sizes : (vector number);
 =================================================================
 [Count Ids Sizes] : disjoint-set;)
Then we add a few utilities for creating new instances, retrieving the disjoint subsets count and finding the root of an object.
\* Create a new disjoint-set type *\
(define new
 { number --> disjoint-set }
 N -> [N (range 1 N) (vector-init 1 N)])
\* Return the number of disjoint sets *\
(define count
 { disjoint-set --> number }
 [Count Ids Sizes] -> Count)
\* Return id of root object *\
(define find-root
 { disjoint-set --> number --> number }
 [Count Ids Sizes] P -> (let Parent 
                         \* Path Compression *\
                         (<-vector Ids (<-vector Ids P))
                         (if (= P Parent)
                             P
                             (find-root [Count Ids Sizes] Parent)))
Next we define functions to check if two objects are connected along with the quick-union function that will actually connect two objects.
\* Are objects P and Q in the set ? *\
(define connected
 { disjoint-set --> number --> number --> boolean }
 UF P Q -> (= (find-root UF P) (find-root UF Q)))
\* Replace sets containing P and Q with their union *\
(define quick-union
 { disjoint-set --> number --> number --> disjoint-set }
 [Count Ids Sizes] P Q 
 -> (let UF [Count Ids Sizes]
         I (find-root UF P)
         J (find-root UF Q)
         SizeI (<-vector Sizes I)
         SizeJ (<-vector Sizes J)
         SizeSum (+ SizeI SizeJ)
         CIds (vector-copy Ids)
         CSizes (vector-copy Sizes)
      (if (= I J)
          [Count CIds CSizes]
          \* Always make smaller root point to larger one *\
          (do (if (< SizeI SizeJ)
                  (do (vector-> CIds I J) (vector-> CSizes J SizeSum))
                  (do (vector-> CIds J I) (vector-> CSizes I SizeSum)))
              [(- Count 1) CIds CSizes]))))
After running our test we get the following output.
(50+) (test 10)
creating union find with 10 objects ...
DONE
[10 <1 2 3 4 5 6 7 8 9 10> <1 1 1 1 1 1 1 1 1 1>]
All objects are disconnected :
1 and 9 connected ? false
4 and 6 connected ? false
3 and 1 connected ? false
7 and 8 connected ? false
... creating unions ... 
DONE
[1 <4 8 7 7 8 8 8 8 8 8> <1 1 1 2 1 1 4 10 1 1>]
All objects should be connected as there is only 1 group :
1 and 9 connected ? true
4 and 6 connected ? true
3 and 1 connected ? true
7 and 8 connected ? true

run time: 0.0 secs
1 : number
All the code can be found here.

Welcome to John McCarthy’s new website.

From the website: John was a legendary computer scientist at Stanford University who developed time-sharing, invented LISP, and founded the field of Artificial Intelligence.* In March 2011 John launched Project JMC with the objective to make his work more approachable and accessible. The Project JMC team is continuing to help realize his objective. In this site you will find all John’s work, including his social commentary, and acknowledgements of his outstanding contributions and impact. Additional comments, suggestions, stories, photographs and videos on John and his work are very welcome. Please send them to the Project JMC team. His old website is here.

Quick Sort in Shen

A Shen type-checked implementation of Quick Sort is even more elegant/terse compared with the CL version posted previously.
Pattern-matching and currying make this possible.

(tc +)

(define filter
  {(A --> boolean) --> (list A) --> (list A)}
  _  []      -> []
  T? [A | B] -> (append [A] (filter T? B)) where (T? A)
  T? [_ | B] -> (filter T? B))

(define quick-sort-generic
  {(list A) --> (A --> A --> boolean) --> (A --> A --> boolean) --> (list A)}
  [] _ _ -> []
  [A | B] L? R? -> (append (quick-sort-generic (filter (R? A) B) L? R?)
			   [A]
			   (quick-sort-generic (filter (L? A) B) L? R?)))

\* descending with duplicates *\
* (quick-sort-generic [3 1 2 7 9 6 6 3 0] >= <)
* [9 7 6 6 3 3 2 1 0] : (list number)

The complete code can be found here. Based on this numeric version.

Quick Sort in Common Lisp

After watching some of Tim Roughgarden’s videos on sorting algorithms, I thought I’d post an implementation of quick sort in Common Lisp as an example of a sorting algorithm implemented in CL. It’s a simple enough example(at < 20 LOC) that demonstrates one non-imperative approach to algorithm implementation. The complete code can be found here.

(defun quick-sort-generic2 (sequence cfun &optional result-type)
  (if (<= (length sequence) 1)
      (copy-seq sequence)
      (flet ((partition (fun array)
           (list (remove-if-not fun array) (remove-if fun array))))
    (let* ((result-type (or result-type 'vector))
           (pivot-ind (random (length sequence)))
           (pivot-val (elt sequence pivot-ind))
           (rem-seq
        (remove pivot-val sequence :start pivot-ind :end (+ 1 pivot-ind)))
           (part (partition (lambda (x) 
                  (apply cfun (list x pivot-val))) rem-seq)))
      (concatenate result-type
               (quick-sort-generic2 (car part) cfun result-type) 
               (list pivot-val)
               (quick-sort-generic2 (cadr part) cfun result-type))))))

* (test-sort)

started quick-sort (generic, array) ...
Evaluation took:
  0.089 seconds of real time
  0.081912 seconds of total run time (0.081587 user, 0.000325 system)
  92.13% CPU
  142,664,472 processor cycles
  8,375,024 bytes consed
  
quick-sorted 10000 items (first 10 shown) : 
#(9998 9998 9998 9997 9997 9996 9995 9994 9993 9992) 

started quick-sort (generic, list) ...
Evaluation took:
  0.062 seconds of real time
  0.058722 seconds of total run time (0.058417 user, 0.000305 system)
  95.16% CPU
  99,419,648 processor cycles
  9,371,456 bytes consed
  
quick-sorted 10000 items (first 10 shown) : 
(9999 9998 9997 9997 9996 9996 9994 9993 9993 9992) 

Happy Pi Day in Shen

Here’s a port of the previous Qi II code to Shen.
Run with Hakan Raberg’s 0.1.4 version of shen.clj (Shen implemented in Clojure !).

*
  Accurately calculates N digits of Pi using Machin's formula
  with fixed point arithmetic and variable guards digits. 

  Depends on the maths library -->
    http://www.shenlanguage.org/library.html
*

(tc +)

(define arccot-
  {number --> number --> number --> number --> number --> number} 
  X N XPOWER    0 _ -> 0
  X N XPOWER TERM 1 -> (+ (arccot- X (+ N 2) (floor (/ XPOWER X)) 
                                     (floor (/ XPOWER N)) 0) 
                          (floor (/ XPOWER N)))
  X N XPOWER TERM 0 -> (- (arccot- X (+ N 2) (floor (/ XPOWER X))
                                      (floor (/ XPOWER N)) 1) 
                          (floor (/ XPOWER N))))

(define arccot
  {number --> number --> number}
  X UNITY -> (let XPOWER (floor (/ UNITY X))
                  (arccot- (* X X) 1 XPOWER (floor XPOWER) 1)))

(define machin-pi
  {number --> number} 
  DIGITS -> (let GUARD (+ 10 (ceiling (log' DIGITS 10)))
                 UNITY (expt 10 (+ DIGITS GUARD))
                 (floor (/ (* 4 (- (* 4 (arccot 5 UNITY))
                                   (arccot 239 UNITY)))
                           (expt 10 GUARD)))))




(1+) (time (machin-pi 100))

run time: 2.56899999999996 secs
31415926535...4350265344N : number

Clojure/Conj 2011

Sold out attendance marked this being the second premiere conference for Clojure. What I realized is just how great the people are in this community. No, seriously. There’s far less ego than with many other communities. This is a great sign for the future of Clojure. Particularly because Rich is such a great guy. He even gave a public apology for something or other that he said(on a mailing list) which he felt was not in the spirit of the Clojure community.

As for the conference, some of the more mathematically inclined talks were especially exciting and encouraging because they highlight how Clojure is facilitating rigorous and ground-breaking work in the sciences :

Arnoldo Jose Muller-Molina : Hacking the Human Genome using Clojure and Similarity Search

“The Genome inside each cell works like a massively parallel computer. Some proteins called Transcription Factors (TF) attach into specific regions called “promoters”. This attachment starts a complex process that can have different outcomes. One of the possible outcomes is the creation of another TF that will in turn attach to some promoter(s) creating a cascade of events. TFs are like functions that have side effects, call other TFs and also can call themselves recursively. In this talk, I will describe a machine learning technique that attempts to reverse engineer the Genome. To achieve this tricky task, you need versatile tools. First of all, Clojure plays an instrumental role in the development of visualizations and data processing pipelines. Clojure makes it really easy to filter, visualize, and synthesize many gigabytes of data. In addition, similarity search is used extensively to find patterns in a huge set of possibilities. I hope to convince you here that similarity search is the next “NoSQL” and that Clojure is an ideal tool for data science projects.”

Chas Emerick : Modeling the world probabilistically using Bayesian networks in Clojure

“Some of the most challenging problems that programs can face include classification, prediction, and making decisions in the face of messy or incomplete observations, data, or understanding. Bayesian networks provide a basis for implementing solutions to many of these sorts of problems, and Clojure offers excellent raw materials for building them. This talk will briefly introduce the concepts of Bayesian probability and networks, demonstrate the usage of an open source generalized Bayesian network modeling library, and discuss its implementation – highlighting the Clojure facilities that made it possible.”

Christophe Grand : From Linear to Incremental

“In this talk I expose some of some of the insights I gathered while turning an inherently linear process (parsing) into a sublinear (bestcase logarithmic) process. This is a tale of datastructures (featuring 2-3 and fingertrees), inversion of control, twisted memoization strategies, profiling and optimizing.”

Ambrose Bonnaire-Sergeant : Introduction to Logic Programming with Clojure

“A well written logic program is a gold mine. Logic programming represents a problem as a set of declarative logical axioms, or facts, which a logic engine uses to construct a proof. With a set of facts, the programmer can offload the work of collecting results to a logic engine in exciting ways. Beyond these wonderful properties, writing a logic program is tremendous fun! We will use Clojure’s logic engine core.logic to introduce these concepts and jump into the fascinating world of logical programming.”

For the Artistically inclined there was

Sam Aaron’s Programming Music with Overtone :

“Can programming languages help us to free our creative potential? Formalised descriptions of data, events and process have been used to great effect within industrial settings but could they also be useful in artistic contexts? This presentation introduces Overtone – a Clojure front-end to the state-of-the-art realtime sound synthesis engine SuperCollider – currently being established as a music platform for both research and performance. Overtone facilitates a truly exciting high-level exploration of musical ideas such as the design and structure of sound, the coordination of multiple concurrent performers and even new forms of musical notation. Through live coding, monome button bashing and loud music performances such as synthesized dubstep, we’ll dive into the architecture of the system and explore some of the deeper computational questions that working in a musical context forces you to answer. Ultimately we will see how Clojure can manage so much more than the representation of business logic or the construction of web apps. We will cover a lot of ground – so hold onto your ears!”
(See this earlier post to get a better idea.)

There were many more great talks too. The full list is here.

Overtone

Overtone is an open source audio environment being created to explore musical ideas from synthesis and sampling to instrument building, live-coding and collaborative jamming.


In this video Sam Aaron gives a fast-paced introduction to a number of key live programming techniques such as triggering instruments, scheduling future events and synth design. Finally, the viewer is shown how a simple musical sequence may be composed and then converted into an intricate Reich phase. The main body of the video was recorded in one take and features an Emacs buffer (using the Live Coding Config (is.gd/​live_coding_emacs) for editing text and communicating with Overtone (is.gd/​overtone), an expressive Clojure front-end to SuperCollider. Clojure is a state-of-the-art functional lisp emphasising immutability and concurrency (clojure.org).