Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.

Functions 61 First, we'll examine functions in some detail. Lisp was born in the context of math- ematics, and functions are elemental to it. Clojure uses functions as building blocks, and mastering functions is fundamental to learning Clojure. We'll then look at how namespaces help organize large programs. These are similar to Java packages; they're a simple way to keep code organized by dividing it into logical modules. The next section will address vars, which represent the notion of globally visible entities in Clojure. Understanding them is critical to using Clojure effectively. You'll also learn how they're special, thanks to their dynamic scoping rules (as opposed to the more familiar lexical scoping rules). This chapter will explore vars and their use in some detail. Next will be a section on destructuring, something that's rather uncom- mon in most languages. Destructuring is a neat way of accessing interesting data ele- ments from inside a larger data structure. Finally, we'll conclude this chapter with a section on metadata, which is a unique way to associate orthogonal data with ordinary Clojure objects. Without any further ado, let's review how Clojure creates and uses functions. 3.1 Functions As discussed in chapter 1, Lisp was born in the context of mathematics and is a func- tional language. A functional language, among other things, treats functions as first- class elements. This means the following things: Functions can be created dynamically (at runtime). Functions can be accepted as arguments by other functions. Functions can be returned from functions as return values. Functions can be stored as elements inside other data structures (for exam- ple, lists). It's worth mentioning again that Clojure functions are objects, and because they fol- low all the rules mentioned, they can be used in some interesting ways. This section will give you an overview of what functions are and how they work, and you'll see several code examples that illustrate various concepts. We'll begin by defining simple functions, with both a fixed and a variable number of parameters. We'll then show how to use the do construct to allow side effects. After that, we'll examine anonymous functions and a few shortcuts for using them, followed by using recursion as a means of looping. We'll end the section with a discussion on higher-order functions and closures. To get started, let's examine the means that Clojure provides to define your own functions. 3.1.1 Defining functions Functions are defined using the defn macro. The structure of the defn macro is the following: (defn function-name doc-string? attr-map? [parameter-list] conditions-map? (expressions))