Thursday, December 10, 2009

Scala functions as data

Here is a short example showing functions being treated as data and then their execution. Note: this example contains global data and side-effects, not the proper way to write functional code. The point is to show the functions (i.e., a, b and c) being held in a list as data.

var x = 1

def a() {x = x * 2}
def b() {x = x * 3}
def c() {x = x * 5}

val fns = List[() => Unit](a, b, c)

println(x) // prints 1
fns.foreach{_()}
println(x) // prints 30

Calling fns.foreach cycles though the list of functions, executing each one.

Wednesday, July 8, 2009

Using Scala with groovy.sql.Sql

Short example of Scala using Groovy's Sql class. I'm new to Scala so I don't know if this is idiomatic. I used asInstanceOf to fully specify the type of the iterator.


import groovy.sql.Sql

val db = Sql.newInstance("jdbc:oracle:thin:@myhost:1521:mysid",
"myuser", "mypassword", "oracle.jdbc.driver.OracleDriver")

val sql = "select * from accounthistory where entrydate > sysdate - 100 and amount <> 0"

val iter = db.rows(sql).iterator().asInstanceOf[java.util.Iterator[java.util.Map[String,String]]]

while(iter.hasNext) {
val row = iter.next
printf("%13s\t%12s\n", row.get("ACCOUNTID"), row.get("AMOUNT"))
}

Tuesday, May 26, 2009

Clojure Classpath Made Easy

Java 6 has an improvement that makes it easy to add new jars to your Clojure classpath when starting the REPL. The -cp option now takes a wildcard, enabling you specify an entire directory of jars.

Here's what I do:

First, following the Groovy model, I create a .clojure subdirectory in my home directory.

Next, I copy clojure-1.0.0.jar and jline-0.9.94.jar to the .clojure directory.

Finally, I create a bash script named clj, making sure it is in my PATH:

#!/bin/bash
java -cp $HOME/.clojure/*: jline.ConsoleRunner clojure.lang.Repl $1

Be sure to terminate the wildcard with a path separator or it won't work. Whenever you need a new jar in your classpath (e.g., a database driver like Oracle's ojdbc14.jar), simply drop the jar in your .clojure directory and your next invocation of the clj script will pick up the new jar.

Friday, March 13, 2009

Quadrature of the Parabola

Archimedes was the first person in recorded history to use the summation of an infinite series. He used it to determine the area of a parabola. The purpose of this blog entry is to study a little math history, aided by Clojure.

For simplicity, consider the area enclosed by the line y = 1 and the parabola y = x ^ 2. Archimedes concluded that the bounded area is 4/3 times the area of an inscribed triangle (imagine a triangle from 0,0 to 1,1 to -1,1). In his proof, Archimedes showed that the infinite series 1/1 + 1/4 + 1/16 + 1/64... converged to 4/3. We can express this as the summation from 1 to infinity of the function 1 / (4 ^ (n - 1)).

To express this in Clojure, we first need to define a power function. We could use Math/pow from Java but Greeks didn't have a double. So we will define a simple power function that operates with rationals, with the power argument restricted to being a whole number.

(defn power [i n] (apply * (replicate n i)))

Note that (power 4 0) does the right thing because (apply * nil) returns 1.

Next, we define a function to express one term in the series:

(defn one-term [n] (/ 1 (power 4 (dec n))))

We also need a general summation function:

(defn summation [from to f] (apply + (map f (range from (inc to)))))

Test it with:

(summation 1 10 (fn [x] x)) => 55.

One of the benefits of a lambda calculus based language, such as Clojure, is that we can pass an unapplied function (e.g., one-term) as data in the third argument to summation.

Finally, we define a function called area-parabola:

(defn area-parabola [base height] (* (/ (* base height) 2) (summation 1 100 one-term)))

I use 100 as the upper range because it is good enough and my computer doesn't do infinity well. The answer comes back as a rational number with a very large numerator and denominator due to Clojure repeatedly finding the least common denominator during each iteration. Cast the result as a double in order to see it in decimal notation. Our original problem defined by the line y = 1 and the parabola y = x ^ 2, inscribes a triangle with a base of 2 and a height of 1, (i.e., an area of 1). Therefore, the answer is:

(double (area-parabola 2 1)) => 1.3333333333, which is approximately 4/3.

What was the mechanism that Archimedes used to conclude that the answer was 4/3? He did not divide some large numerator by a large denominator, nor did he add up smaller and smaller decimals. He proved it geometrically. I tried to go through an 1897 translation of his proof but I didn't make it. I cheated and took a look at Proposition 24 at the end where he concludes that the answer can't be greater than 4/3 or less than 4/3.

In 1906, a hidden document authored by Archimedes was found in a monastery in Constantinople. Entitled "The Method", some argue that it describes the essence of what would be called integral calculus, over 1800 years later.

Friday, February 27, 2009

Conway's Game of Life

John Conway developed the Game of Life in 1970 as an example of cellular automata. The following Clojure code uses Swing to implement the game.




(import '(javax.swing JFrame JPanel JButton)
'(java.awt BorderLayout Dimension Color)
'(java.awt.event ActionListener))

(def cells (ref {}))

(def running (ref false))

(defn init-cells []
(dosync
(dorun
(for [x (range 32) y (range 48)]
(ref-set cells
(assoc (deref cells) [x y] (= 0 (rand-int 5))))))))

(defn determine-new-state [x y]
(let [count
(+ (if (cells [(- x 1) (- y 1)]) 1 0)
(if (cells [x (- y 1)]) 1 0)
(if (cells [(+ x 1) (- y 1)]) 1 0)
(if (cells [(- x 1) y]) 1 0)
(if (cells [(+ x 1) y]) 1 0)
(if (cells [(+ x 1) (+ y 1)]) 1 0)
(if (cells [x (+ y 1)]) 1 0)
(if (cells [(- x 1) (+ y 1)]) 1 0))]

(or (and (cells [x y]) (> count 1) (< count 4))
(and (not (cells [x y])) (= count 3)))))

(defn calc-state []
(let [new-cells (ref {})]
(dosync
(dorun
(for [x (range 32) y (range 48)]
(ref-set new-cells
(assoc (deref new-cells) [x y] (determine-new-state x y)))))

(ref-set cells (deref new-cells)))))

(defn paint-cells [graphics]
(dorun (map #(let [x (first (first %))
y (second (first %))
state (second %)]

(doto graphics
(. setColor (if state Color/RED Color/WHITE))
(. fillRect (* 10 x) (* 10 y) 10 10)))

(deref cells))))

(defn toggle-thread [panel button]
(if (deref running)

(do (dosync (ref-set running false))
(. button (setText "Start")))

(do (dosync (ref-set running true))
(. button (setText "Stop"))
(. (Thread.
#(loop []
(calc-state)
(. panel repaint)
(Thread/sleep 100)
(if (deref running) (recur))))
start))))

(defn main[]

(init-cells)

(let [f (JFrame.)
b (JButton. "Start")
panel (proxy [JPanel] [] (paint [graphics] (paint-cells graphics)))]

(doto f
(. setLayout (BorderLayout.))
(. setLocation 100 100)
(. setPreferredSize (Dimension. 320 540))
(. add b BorderLayout/SOUTH)
(. add panel BorderLayout/CENTER)
(. setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(. pack)
(. setVisible true))

(. b addActionListener
(proxy [ActionListener] []
(actionPerformed [evt] (toggle-thread panel b))))))

(main)


ref, deref, and ref-set maintain the state of the cells and whether or not the system has started or stopped. Approximately twenty percent of the cells are initialized as alive by the statement (= 0 (rand-int 5)).

Friday, February 13, 2009

Trivial Clojure and Spring Example

This is trivial example that shows how to use Clojure with Spring.

First, define and compile Hello.java, which has a getGreeting method.

public class Hello {
public String getGreeting() {
return "Hello, Alonzo Church";
}
}

Second, write a Spring hello.xml context, which defines a hello bean based on the Hello class.

<beans default-lazy-init="true"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="hello" class="Hello"/>
</beans>

Finally, create a clj file that uses the Spring context to get the bean and invoke its getGreeting method.

(import '(org.springframework.beans.factory.xml XmlBeanFactory)
'(org.springframework.core.io FileSystemResource))

(let [factory (XmlBeanFactory. (FileSystemResource. "hello.xml"))
hello (. factory (getBean "hello"))]
(println (. hello getGreeting)))

To run it, include clojure.jar, spring.jar, and commons-logging.jar in your classpath.

Monday, January 5, 2009

Short Fibonacci Function

I think this is one of the shortest Fibonacci sequences I've ever seen. It's interesting to see the sequence defined as a recursive definition. It was written in Clojure by Christophe Grand:

(def fib-seq
(lazy-cat [0 1] (map + fib-seq (rest fib-seq))))

Be sure to specify how many numbers you want or it will run forever:

(take 10 fib-seq)