## 1 New and Improved Features
### 1.1 Transducers
Transducers is a new way to decouple algorithmic transformations from their
application in different contexts. Transducers are functions that transform
reducing functions to build up a "recipe" for transformation.
Many existing sequence functions now have a new arity (one fewer argument
than before). This arity will return a transducer that represents the same
logic but is independent of lazy sequence processing. Functions included are:
* conj (conjs to [])
* map
* mapcat
* filter
* remove
* take
* take-while
* drop
* drop-while
* cycle
* take-nth
* replace
* partition-by
* partition-all
* keep
* keep-indexed
Additionally some new transducer functions have been added:
* cat - concatenates the contents of each input
* de-dupe - removes consecutive duplicated values
* random-sample - returns items from coll with random probability
And this function can be used to make completing transforms:
* completing
There are also several new or modified functions that can be used to apply
transducers in different ways:
* sequence - takes a transformation and a coll and produces a lazy seq
* transduce - reduce with a transformation (eager)
* eduction - returns a reducible/seqable/iterable seq of applications of the transducer to items in coll. Applications are re-performed with every reduce/seq/iterator.
* run! - run the transformation for side effects on the collection
There have been a number of internal changes to support transducers:
* volatiles - there are a new set of functions (volatile!, vswap!, vreset!, volatile?) to create and use volatile "boxes" to hold state in stateful transducers. Volatiles are faster than atoms but give up atomicity guarantees so should only be used with thread isolation.
* array iterators - added support for iterators over arrays
Some related issues addressed during development:
### 1.2 Keyword and Symbol Construction
1) The main bottleneck in construction of symbols (which also occurs inside keywords) was interning of the name and namespace strings. This interning has been removed, resulting in a performance increase.
2) Keywords are cached and keyword construction includes a cache check. A change was made to only clear the cache reference queue when there is a cache miss.
### 1.3 Warn on Boxed Math
One source of performance issues is the (unintended) use of arithmetic operations on boxed numbers. To make detecting the presence of boxed math easier, a warning will now be emitted about boxed math if \*unchecked-math* is set to :warn-on-boxed (any truthy value will enable unchecked-math, only this specific value enables the warning).
Example use:
user> (defn plus-2 [x] (+ x 2)) ;; no warning, but boxed
#'user/plus-2
user> (set! *unchecked-math* :warn-on-boxed)
true
user> (defn plus-2 [x] (+ x 2)) ;; now we see a warning
Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static java.lang.Number
clojure.lang.Numbers.unchecked_add(java.lang.Object,long).
#'user/plus-2
user> (defn plus-2 [^long x] (+ x 2)) ;; use a hint to avoid boxing
#'user/plus-2
### 1.4 update - like update-in for first level
`update` is a new function that is like update-in specifically for first-level keys:
(update m k f args...)
Example use:
user> (update {:a 1} :a inc)
{:a 2}
user> (update {:a 1} :a + 2)
{:a 3}
user> (update {} :a identity) ;; missing returns nil
{:a nil}
## 2 Enhancements
### 2.1 Error messages
Invalid defrecord results in exception attributed to consuming ns instead of defrecord ns
Report line,column, and source in defmacro errors
Give more specific hint if namespace with "-" not found to check file uses "_"
### 2.2 Documentation strings
Fix typo in gen-class doc-string
Fix typo in filterv example
Fix typo in defmulti docstring
Fix typo in deftype docstring
Fix typo in clojure.main usage
### 2.3 Performance
Improve performance of partial with more unrolling
clojure.core/set should use transients for better performance
Cache unknown multimethod value default dispatch
### 2.4 Other enhancements
Improve apropos to show some indication of namespace of symbols found
Hints don't work with #() form of function
Removes owner-thread check from transients - this check was preventing some valid usage of transients in core.async where a transient is created on one thread and then used again in another pooled thread (while still maintaining thread isolation).
Extracted IAtom interface implemented by Atom.
Don't initialize classes when importing them
Class name clash between top-level functions and defn'ed ones
## 3 Bug Fixes
Reduce broken on some primitive vectors
Equality bug on records created with nested calls to map->record
Unable to set compiler options via system properties except for AOT compilation
NPE when AOTing overrided clojure.core functions
reductions does not check for reduced value
Using def with metadata {:type :anything} throws ClassCastException during printing
Error when calling primitive functions with destructuring in the arg vector
Piping seque into seque can deadlock
<= is incorrect when args include Double/NaN
Make cached string value of Keyword and Symbol transient
clojure.core/bean should implement Iterable