05.08.2014 Views

here - Stefan-Marr.de

here - Stefan-Marr.de

here - Stefan-Marr.de

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

2. Context and Motivation<br />

Clojure Agents The Clojure programming language offers a variation inspired<br />

by the active objects pattern called agents. 10 An agent represents a<br />

resource with a single atomically mutable state cell. However, the state is<br />

modified only by the agent itself. The agent receives update functions asynchronously.<br />

An update function takes the old state and produces a new state.<br />

The execution is done in a <strong>de</strong>dicated thread, so that at most one update function<br />

can be active for a given agent at any time. Other threads will always<br />

read a consistent state of the agent at any time, since the state of the agent is<br />

a single cell and read atomically.<br />

Specific to agents is the integration with the Clojure language and the<br />

encouraged usage patterns. Clojure aims to be “predominantly a functional<br />

programming language” 11 that relies on immutable, persistent data structures.<br />

T<strong>here</strong>fore, it encourages the use of immutable data structures as the state<br />

of the agent. With these properties in mind, agents provi<strong>de</strong> a more restrictive<br />

mo<strong>de</strong>l than common active objects, and if these properties would be enforced,<br />

it could be classified as a mechanism for communicating isolates. However, Clojure<br />

does not enforce the use of immutable data structures as state of the<br />

agent, but allows for instance the use of unsafe Java objects.<br />

The <strong>de</strong>scribed set of intentions and the missing guarantees qualify agents<br />

as an example for later chapters. Thus, it is <strong>de</strong>scribed <strong>here</strong> in more <strong>de</strong>tail.<br />

1 ( <strong>de</strong>f cnt ( agent 0))<br />

2 ( println @cnt ) ; prints 0<br />

3<br />

4 ( send cnt + 1)<br />

5 ( println @cnt ) ; might print 0 or 1, because of data race<br />

6<br />

7 ( let [ next-id ( promise )]<br />

8 ( send cnt (fn [ old-state ]<br />

9 ( let [ result (+ old-state 1)]<br />

10 ( <strong>de</strong>liver next-id result ) ; return resulting id to sen<strong>de</strong>r<br />

11 result )))<br />

12 @next-id ) ; reliably read of the update function ’s result<br />

Listing 2.1: Clojure Agent example<br />

Lst. 2.1 gives a simple example of how to implement a counter agent in Clojure,<br />

and how to interact with it. First, line 1 <strong>de</strong>fines a simple counter agent<br />

named cnt with an initial value of 0. Printing the value by accessing it directly<br />

10 http://clojure.org/agents<br />

11 Clojure, Rich Hickey, access date: 20 July 2012 http://clojure.org/<br />

28

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!