An tude, according to Wikipedia, is an instrumental musical composition, usually short and of considerable difficulty, usually designed to provide practice material for perfecting a particular musical skill.
What Are tudes for ClojureScript?
In this book, you will find descriptions of programs that you can compose (write) in ClojureScript. The programs will usually be short, and each one has been designed to provide practice material for a particular ClojureScript programming area. Unlike musical tudes, these programs have not been designed to be of considerable difficulty, though they may ask you to stretch a bit beyond the immediate material and examples that you find in most ClojureScript books or online references.
These tudes are not intended to introduce you to individual ClojureScript concepts. That ground is covered quite nicely by ClojureScript Koans, 4Clojure, and ClojureScript Unraveled. Instead, these tudes take the form of small projects that do something that is (somewhat) useful. They are much along the lines of the programming katas given in chapter 10 of Living Clojure by Carin Meier (OReilly). If Koans, 4Clojure, and ClojureScript Unraveled ask you to write programs at the level of chemical elements, in this book, you are constructing simple molecules.
This book is open source, so if youd like to contribute, make a correction, or otherwise participate in the project, check out https://github.com/oreillymedia/etudes_for_clojurescript for details. If we accept your work, well add you to the contributors chapter.
Acknowledgments
Thanks to OReilly Media, Inc.s Simon St. Laurent and Meghan Blanchette, who encouraged me to write this book. Thanks also to all the people on the #clojurescript
IRC channel who patiently answered my questions, and to Mike Fikes for his technical review. Any errors remaining in this document are mine, not theirs.
Chapter 1. Functions and Variables
This chapter starts with a couple of warm-up exercises so that you can get comfortable with your ClojureScript development environment. First, a quick review of how to define functions. Here is the generic model for a function:
(defn
function-name [
parameters]
function-body)
Here is a function that takes an acceleration and an amount of time as its parameters and returns the distance traveled:
(defn distance [accel time] (/ (* accel time time) 2.0)
You can also put a documentation string between the function name and parameter list:
(defn distance "Calculate distance traveled by an object moving with a given acceleration for a given amount of time." [accel time] (/ (* accel time time) 2.0)
tude 1-1: Defining a Function in the REPL
Create a project named formulas (see , and create a project to work with. In the REPL, type the preceding distance
function and test it.
tude 1-2: Defining Functions in a Source File
Defining functions in the REPL is fine for a quick test, but it is not something you want to do on an application-level scale. Instead, you want to define the functions in a source file. In the formulas project, open the src/formulas/core.cljs file and create functions for these formulas:
- Distance equals one-half acceleration multplied by time squared:
- Kinetic energy equals one-half the mass times velocity squared:
- Centripetal acceleration is velocity squared over the radius:
Here is some sample output. (in-ns 'formulas.core)
switches you to that namespace so that you can type the function name without having to specify the module that it is in. If you update the source, (require 'formulas.core :reload)
will recompile the code:
cljs.user=> (in-ns 'formulas.core)nilformulas.core=> (require 'formulas.core :reload)nilformulas.core=> (distance 9.8 5)122.5formulas.core=> (kinetic-energy 35 4)280formulas.core=> (centripetal 30 2)450
See a suggested solution: .
tude 1-3: Using def
The def
special form lets you bind a symbol to a value. The symbol is globally available to all functions in the namespace where it is defined. Add a function named gravitational-force
that calculates the gravitational force between two masses whose centers of mass are at a distance r from each other to your code:
, where the gravitational constant
Use a def
for the gravitational constant.
Here is the calculation for two masses of 100 kg that are 5 m apart:
formulas.core=> (gravitational-force 100 100 5)2.67136e-8
Redefining and def
ClojureScripts def
creates an ordinary JavaScript variable. Note that it is possible to rebind a symbol to a value with code like this:
(
def
x
5
)
(
def
x
6
)
(
def
x
(
+
1
x
))
However, this is somewhat frowned upon. Global, shared, mutable (changeable) variables can be problematic, as described in this answer to a question on StackExchange. You will find that ClojureScripts functional programming model makes the need for such global variables much less frequent. As a beginning programmer, when you create a variable with