- •Contents
- •Foreword
- •Acknowledgments
- •Preface
- •Who This Book Is For
- •What Is in This Book
- •How to Read This Book
- •Notation Conventions
- •Web Resources and Feedback
- •Downloading Sample Code
- •Getting Started
- •Why Clojure?
- •Clojure Coding Quick Start
- •Exploring Clojure Libraries
- •Introducing Lancet
- •Wrapping Up
- •Exploring Clojure
- •Forms
- •Reader Macros
- •Functions
- •Vars, Bindings, and Namespaces
- •Flow Control
- •Metadata
- •Wrapping Up
- •Working with Java
- •Calling Java
- •Optimizing for Performance
- •Creating and Compiling Java Classes in Clojure
- •Exception Handling
- •Adding Ant Projects and Tasks to Lancet
- •Wrapping Up
- •Unifying Data with Sequences
- •Everything Is a Sequence
- •Using the Sequence Library
- •Clojure Makes Java Seq-able
- •Adding Properties to Lancet Tasks
- •Wrapping Up
- •Functional Programming
- •Functional Programming Concepts
- •How to Be Lazy
- •Lazier Than Lazy
- •Recursion Revisited
- •Wrapping Up
- •Concurrency
- •The Problem with Locks
- •Refs and Software Transactional Memory
- •Use Atoms for Uncoordinated, Synchronous Updates
- •Use Agents for Asynchronous Updates
- •Managing Per-Thread State with Vars
- •A Clojure Snake
- •Making Lancet Targets Run Only Once
- •Wrapping Up
- •Macros
- •When to Use Macros
- •Writing a Control Flow Macro
- •Making Macros Simpler
- •Taxonomy of Macros
- •Making a Lancet DSL
- •Wrapping Up
- •Multimethods
- •Living Without Multimethods
- •Moving Beyond Simple Dispatch
- •Creating Ad Hoc Taxonomies
- •When Should I Use Multimethods?
- •Adding Type Coercions to Lancet
- •Wrapping Up
- •Clojure in the Wild
- •Automating Tests
- •Data Access
- •Web Development
- •Farewell
- •Editor Support
- •Bibliography
- •Index
- •Symbols
INTRODUCING LANCET |
42 |
You can download a PDF version of the online documentation from the Clojure Google Group’s file archive;8 the filename is manual.pdf.
Now you have written a bit of Clojure code and can load and explore Clojure libraries. It is time to introduce the main sample application for the book: Lancet.
1.4 Introducing Lancet
Lancet is a more involved project that we will build together throughout the book. Lancet is a dependency-based build system. In a dependencybased system, you describe the dependencies between various targets (objectives). Then you can request performance of a particular target, and the system will determine what other targets also need to run, and in what order. Popular dependency-based build systems include Make,9 Ant,10 SCons,11 and Rake.12
Lancet can function stand-alone, or it can invoke tasks from Ant. In fact, Lancet was inspired by a review of Ant’s build syntax. Here is a simple Ant build script:
Download lancet/step_0/build.xml
<project name="example" default="compile">
<property name="src" location="src"/> <property name="build" location="classes"/>
<target name="init"> <tstamp/>
<mkdir dir="${build}"/> </target>
<target name="compile" depends="init" description="Compile Java sources." > <javac srcdir="${src}"
destdir="${build}" />
</target>
</project>
8.http://groups.google.com/group/clojure/files
9.http://en.wikipedia.org/wiki/Make_(software)
10.http://ant.apache.org
11.http://www.scons.org
12.http://rake.rubyforge.org/
Prepared exclusively for WG Custom Motorcycles
Report erratum
this copy is (P1.0 printing, May 2009)
INTRODUCING LANCET |
43 |
Ant’s design can be summarized as follows:
•A build is composed of one or more distinct targets, such as init and compile.
•Targets are related by dependencies. In the previous sample, compile depends on init.
•By tracking dependency relationships, Ant can run only the targets that are needed and run each target only once per build.
•You can provide and override configuration settings by setting arbitrary properties, such as src and build in the example.
•The actual work of targets is performed by tasks, such as tstamp, mkdir, and javac.
•Ant build scripts are usually written in XML, as shown earlier, but the underlying implementation is typically Java.
At first glance, Lancet syntax looks like Ant syntax but Lispy instead of XMLish:
Download lancet/step_0/build.clj
(use 'lancet) (use 'lancet.ant)
(def src "src" )
(def build "classes" )
(deftarget init (tstamp)
(mkdir {:dir build}))
(deftarget compile
"Compile Java sources"
(init)
(javac {:srcdir src :destdir build}))
The surface similarity belies some important differences:
•Lancet is pure Clojure code. Lancet uses no XML and does not have to convert between XML and Java.
•Because Lancet is Clojure code, the need for properties disappears. You can simply use Clojure vars such as src and build.
•Likewise, there is no need for tasks. Tasks are just functions.
•Targets such as init and compile are also just functions, with the special property that they run only once. deftarget defines a function with run-once semantics.
Prepared exclusively for WG Custom Motorcycles
Report erratum
this copy is (P1.0 printing, May 2009)
WRAPPING UP |
44 |
•Explicit dependencies are unnecessary. They fall out naturally when one target calls another, because compile calls init in the earlier example.
Lancet also provides direct access to Ant’s most important feature: its large, tested library of tasks. Lancet can call Ant tasks such as tstamp, mkdir, and javac directly as Clojure functions.
Most of the abstractions in Ant exist not to build projects but to manage the impedance mismatch between XML and Java. Lancet avoids all that ceremony and distills the essence of a dependency-based system: functions that run only once, when needed.
At the end of most chapters, you will build a little bit of Lancet. By the end of the book, you will have a usable Clojure build system.
1.5 Wrapping Up
You have just gotten the whirlwind tour of Clojure. You have seen Clojure’s expressive syntax, learned about Clojure’s approach to Lisp, and seen how easy it is to call Java code from Clojure.
You have Clojure running in your own environment, and you have written short programs at the REPL to demonstrate functional programming and software transactional memory. You have seen what Lancet will look like, once you know how to build it. Now it is time to explore the entire language.
Prepared exclusively for WG Custom Motorcycles
Report erratum
this copy is (P1.0 printing, May 2009)