Showing posts with label clojure. Show all posts
Showing posts with label clojure. Show all posts

23 May 2013

A Short Survey on the State of Functional Reactive Programming in ClojureScript

In the Object-Oriented world of JavaScript, architectures like MVP, MVC, and their brethren are well established. But when I started using ClojureScript to build rich user interfaces on the web, I was naturally interested in finding ways to architect my site that are friendly to a functional programming language like Clojure. This led me to functional reactive programming, or FRP.

FRP, probably the best-known user interface paradigm for functional programming, models UIs as dataflows, where changes (user actions or data source changes) propagate through the system using purely functional operations and eventually end up as visual changes back in the UI. In short, FRP is similar to how changes to a cell in a spreadsheet propagate to other dependent cells.

Though the ClojureScript ecosystem is still fairly immature (or perhaps because it is), there are many libraries which support the FRP style of programming. If you are looking for an alternative to faking object-oriented styles of programming in ClojureScript, jump in and give one or more a try!

(By the way, if you want my personal recommendation, I have had a lot of luck with the simplicity and power of widje.)

Native ClojureScript libraries

acute (wrapper around AngularJS)
rx-cljs (wrapper around RxJS)
Yolk (wrapper around Bacon.js)
Clang (wrapper around AngularJS)

Using JavaScript libraries directly

30 November 2011

Non-Locking Concurrency Control

At work this week I have been working on implementing a concurrency control strategy on a system. During the discussions, software transactional memory (STM) came up, as we want to develop a solution that does not involve locking, and since my primary experience with it is Clojure's built-in STM, I brought that up.

The world seems to be helping out today with a link on Hacker News to an old discussion involving Clojure's creator Rich Hickey: Clojure: STMs vs Locks. Good food for thought.

It is great to see that my Clojure knowledge is proving to be surprisingly useful at work. Those years of being a closeted functional programming nerd are paying off!

I also re-watched Rich Hickey's talk "Are We There Yet?" and reread "Equal Rights for Functional Objects" by Henry G. Baker, which are both great resources for really thinking about state in a functional manner.

20 November 2011

My Clojure Environment Setup

Mostly for my own personal future reference, here is how I setup my Clojure environment.


Emacs
  1. Install Emacs 24 (links to the binaries available here).
  2. Install the Emacs Starter Kit or the Emacs Prelude.
Leiningen
Based on instructions from Leiningen (github.com).
  1. Get the Leiningen batch script from https://raw.github.com/technomancy/leiningen/master/bin/lein.bat and edit it to fetch version 1.6.1.1 instead of 2.0.0-SNAPSHOT.
  2. Put lein.bat in a folder. Add that folder to your PATH.
  3. Download wget.exe and curl.exe and add them to your PATH.
  4. Run:
    lein self.install
Setting Up Emacs for Clojure
  1. Setup clojure-mode
  2. Setup swank-clojure
    1. Follow installation instructions from swank-clojure (github.com).
References

03 February 2009

Creating a Clojure GUI Application with SWT

In my explorations of Clojure, I have been developing a desktop GUI application that uses SWT, the graphics toolkit that Eclipse uses. Once you get going, SWT is fairly intuitive to program in with Clojure, but you might need a little help to get started. Here is an example of a barebones app in SWT:
(ns swttest
(:import (org.eclipse.swt.widgets Display Shell)
(org.eclipse.swt.layout GridLayout)
(org.eclipse.swt.events ShellAdapter)))

(defn create-shell [display shell]
(let [layout (GridLayout.)]
(doto shell
(.setText "SWT Test")
(.setLayout layout)
(.addShellListener
(proxy [ShellAdapter] []
(shellClosed [evt]
(System/exit 0)))))))

(defn swt-loop [display shell]
(loop []
(if (.isDisposed shell)
(.dispose display)
(do
(if (not (.readAndDispatch display))
(.sleep display))
(recur)))))

(defn begin []
(let [display (Display.)
shell (Shell. display)]
(create-shell display shell)
(.setSize shell 700 700)
(.open shell)
(swt-loop display shell)))

(begin)
On Mac, you will need to add the "-XstartOnFirstThread" command line option or your application will crash soon after launching.

Update:
I originally left out the line "(create-shell display shell)". The code above is now corrected.

See also: