Many classes of applications remain safely ignorant of the details and subtleties of mathematics, regardless of the language or runtime being used. In such cases, it is often I/O overhead, database queries, and other factors that define an application’s bottlenecks.
However, there are domains where numeric performance and/or correctness are critical, and the set of such cases seems to be growing: large-scale data processing, visualization, statistical analysis, and similar classes of applications all often require a degree of mathematical rigor not found elsewhere. Clojure gives you ways to choose how to optimize your application’s usage of numerics to meet these demands along two different axes. Without sacrificing concision, expressiveness, or runtime dynamism, you can opt to:
Use primitive numerics to obtain maximum performance within the available range of those primitives.
Use boxed numerics to reliably perform arbitrary-precision operations.
In this chapter, we’ll do a deep dive into how Clojure models numbers and implements operations over them.
Our first step must be to understand the raw materials at hand, Clojure’s numeric representations, shown in Table 11-1. A good place to start would be to compare Clojure’s numerics and those in Ruby and Python (those familiar with Java should be immediately comfortable, insofar as Clojure reuses Java’s numeric representations).