= Using Libs
Rich Hickey
2015-01-01
:type: reference
:toc: macro
:icons: font
:navlinktext: Libs
:prevpagehref: namespaces
:prevpagetitle: Namespaces
:nextpagehref: vars
:nextpagetitle: Vars and Environments

ifdef::env-github,env-browser[:outfilesuffix: .adoc]

toc::[]

Clojure provides for code loading and dependency tracking via its "lib" facility. A lib is a named unit of Clojure source code contained in a Java resource within classpath. A lib will typically provide the complete set of definitions that make up one Clojure namespace.

== Lib Conventions

Clojure defines conventions for naming and structuring libs:

* A lib name is a symbol that will typically contain two or more parts separated by periods.
* A lib's container is a Java resource whose classpath-relative path is derived from the lib name:
** The path is a string
** Periods in the lib name are replaced by slashes in the path
** Hyphens in the lib name are replaced by underscores in the path
** The path may end with ".class", ".clj", or ".cljc" (see <<libs#order,Lib load order>> below)
* A lib begins with an "ns" form that
** creates the Clojure namespace that shares its name, and
** declares its dependencies on Java classes, Clojure's core facilities, and/or other libs,

Clojure ensures that if the call to "ns" completes without throwing an exception, the declared dependencies have been satisfied and the capabilities they provide are available.

== Example Lib

A simple lib:

[source,clojure]
----
(ns com.my-company.clojure.examples.my-utils
  (:import java.util.Date)
  (:use [clojure.string :only (join)])
  (:require [clojure.java.io :as jio]))
----

* The `ns` form names the lib's namespace and declares its dependencies. Based on its name, this lib is typically defined in a source file at the classpath-relative path: com/my_company/clojure/examples/my_utils.clj (note the translations from period to slash and hyphen to underscore).
* The `:import` clause declares this lib's use of `java.util.Date` and makes it available to code in this lib using its unqualified name.
* The `:use` clause declares a dependency on the `clojure.string` lib for its `join` function only. +join+ may be used in this lib's code using its unqualified name.
* The `:require` clause declares a dependency on the `clojure.java.io` lib and enables using its members using the shorter namespace alias `jio`.

== Prefix Lists

It's common for a lib to depend on several other libs whose full names share a common prefix. In calls to `require` and `use` (and in `:require` and `:use` clauses within an +ns+ form), the common prefix can be extracted and provided once using a prefix list. For example, these two forms are equivalent:

[source,clojure]
----
(require 'clojure.contrib.def 'clojure.contrib.except 'clojure.contrib.sql)
(require '(clojure.contrib def except sql))
----

''''

== Related functions

Creating a namespace: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/ns[ns]

Ensuring a lib is loaded: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/require[require] https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/use[use]

Listing loaded libs: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/loaded-libs[loaded-libs]

[[order]]
== Lib load order

Libs may exist in either compiled (`.class`) or source (`.clj` or `.cljc`) form. In some cases, one or even all of these might exist on the classpath. The lib is loaded from one of them based on the following rules:

* A `.class` file is always preferred over a source file, unless the source file's timestamp is newer than the `.class` file, in which case the source file is preferred.
* A `.clj` (platform-specific file) is always preferred over a `.cljc` (common across platforms).

The second rule allows a library author to ship both a portable common definition of a lib while also shipping platform-specific libs that override the portable version to do something that leverages the host platform.
