1 Deprecated and Removed Features 1.1 Fields that Start With a Dash Can No Longer Be Accessed Using Dot Syntax 2 New/Improved Features 2.1 Reader Literals 2.2 clojure.core/mapv 2.3 clojure.core/filterv 2.4 clojure.core/ex-info and clojure.core/ex-data 2.5 clojure.core/reduce-kv 2.6 clojure.core/contains? Improved 2.7 clojure.core/min and clojure.core/max prefer NaN 2.8 clojure.java.io/as-file and clojure.java.io/as-url Handle URL-Escaping Better 2.9 New Dot Syntax for Record and Type Field Access 2.10 Record Factory Methods Available Inside defrecord 2.11 assert-args Displays Namespace and Line Number on Errors 2.12 File and Line Number Added to Earmuff Dynamic Warning 2.13 require Can Take a :refer Option 2.14 *compiler-options* Var 2.15 Improved Reporting of Invalid Characters in Unicode String Literals 2.16 clojure.core/hash No Longer Relies on .hashCode 2.17 Java 7 Documentation 2.18 loadLibrary Loads Library Using System ClassLoader 2.19 Java int is boxed as java.lang.Integer 3 Performance Enhancements 4 Bug Fixes
Clojure 1.4 introduces a field accessor syntax for the dot special form that aligns Clojure field lookup syntax with ClojureScript's.
For example, in Clojure 1.3, one can declare a record with a field starting with dash and access it like this:
(defrecord Bar [-a]) ;=> user.Bar
(.-a (Bar. 10)) ;=> 10
In 1.4, the above code results in IllegalArgumentException No matching field found: a for class user.Bar
However, the field may still be accessed as a keyword:
(:-a (Bar. 10)) ;=> 10
Clojure 1.4 supports reader literals, which are data structures tagged by a symbol to denote how they will be read.
When Clojure starts, it searches for files named data_readers.clj
at the root of the classpath. Each such file must contain a Clojure
map of symbols, like this:
{foo/bar my.project.foo/bar
foo/baz my.project/baz}
The key in each pair is a tag that will be recognized by the Clojure reader. The value in the pair is the fully-qualified name of a Var which will be invoked by the reader to parse the form following the tag. For example, given the data_readers.clj file above, the Clojure reader would parse this form:
#foo/bar [1 2 3]
by invoking the Var #'my.project.foo/bar
on the vector [1 2 3]
. The
data reader function is invoked on the form AFTER it has been read
as a normal Clojure data structure by the reader.
Reader tags without namespace qualifiers are reserved for Clojure. Default
reader tags are defined in clojure.core/default-data-readers
but may be
overridden in data_readers.clj
or by rebinding *data-readers*
.
Clojure supports literals for instants in the form
#inst "yyyy-mm-ddThh:mm:ss.fff+hh:mm"
. These literals are parsed as java.util.Date
s
by default. They can be parsed as java.util.Calendar
s or java.util.Timestamp
s
by binding *data-readers*
to use clojure.instant/read-instant-calendar
or
clojure.instant/read-instant-timestamp
.
(def instant "#inst \"@2010-11-12T13:14:15.666\"")
; Instants are read as java.util.Date by default
(= java.util.Date (class (read-string instant)))
;=> true
; Instants can be read as java.util.Calendar or java.util.Timestamp
(binding [*data-readers* {'inst read-instant-calendar}]
(= java.util.Calendar (class (read-string instant))))
;=> true
(binding [*data-readers* {'inst read-instant-timestamp}]
(= java.util.Timestamp (class (read-string instant))))
;=> true
Clojure supports literals for UUIDs in the form #uuid "uuid-string"
. These
literals are parsed as java.util.UUID
s.
mapv
takes a function f
and one or more collections and returns a
vector consisting of the result of applying f
to the set of first items of
each collection, followed by applying f
to the set of second items in each
collection, until any one of the collections is exhausted. Any remaining
items in other collections are ignored. f
should accept a number of arguments
equal to the number of collections.
(= [1 2 3] (mapv + [1 2 3]))
;=> true
(= [2 3 4] (mapv + [1 2 3] (repeat 1)))
;=> true
filterv
takes a predicate pred
and a collection and returns a vector
of the items in the collection for which (pred item)
returns true. pred
must be free of side-effects.
(= [] (filterv even? [1 3 5]))
;=> true
(= [2 4] (filter even? [1 2 3 4 5]))
;=> true
ex-info
creates an instance of ExceptionInfo
. ExceptionInfo
is a
RuntimeException
subclass that takes a string msg
and a map of data.
(ex-info "Invalid use of robots" {:robots false})
;=> #<ExceptionInfo clojure.lang.ExceptionInfo: Invalid use of robots {:robots false}>
ex-data
is called with an exception and will retrieve that map of data
if the exception is an instance of ExceptionInfo
.
(ex-data (ex-info "Invalid use of robots" {:robots false}))
;=> {:robots false}
reduce-kv
reduces an associative collection. It takes a function f
,
an initial value init
and an associative collection coll
. f
should
be a function of 3 arguments. Returns the result of applying f
to init
,
the first key and the first value in coll
, then applying f
to that result
and the 2nd key and value, etc. If coll
contains no entries, returns init
and f is not called. Note that reduce-kv
is supported on vectors,
where the keys will be the ordinals.
(reduce-kv str "Hello " {:w \o :r \l :d \!})
;=> "Hello :rl:d!:wo"
(reduce-kv str "Hello " [\w \o \r \l \d \!])
;=> "Hello 0w1o2r3l4d5!"
contains?
now works with java.util.Set
.
min
and max
now give preference to returning NaN if either of their
arguments is NaN.
as-file
and as-url
now handle URL-escaping in both directions.
Clojure 1.4 introduces a field accessor syntax for the dot special form that aligns Clojure field lookup syntax with ClojureScript's.
In 1.4, to declare a record type and access its property x
, one can
write:
(defrecord Foo [x]) ;=> user.Foo
(.-x (Foo. 10)) ;=> 10
This addition makes it easier to write code that will run as expected in both Clojure and ClojureScript.
Prior to 1.4, you could not use the factory functions (->RecordClass
and map->RecordClass
) to construct a new record from inside a
defrecord
definition.
The following example did not work prior to 1.4, but is now
valid. This example makes use of ->Mean
which would have not yet
been available.
(defrecord Mean [last-winner]
Player
(choose [_] (if last-winner last-winner (random-choice)))
(update-strategy [_ me you] (->Mean (when (iwon? me you) me))))
assert-args
now uses &form to report the namespace and line number where
macro syntax errors occur.
When a variable is defined using earmuffs but is not declared dynamic, Clojure emits a warning. That warning now includes the file and line number.
require
can now take a :refer
option. :refer
takes a list of symbols
to refer from the namespace or :all
to bring in all public vars.
The dynamic var *compiler-options*
contains a map of options to send
to the Clojure compiler.
Supported options:
:elide-meta
: Have certain metadata elided during compilation. This should be set to a collection of keywords.:disable-locals-clearing
: Set to true to disable clearing. Useful for using a debugger.
The main function of the Clojure compiler sets the
*compiler-options*
from properties prefixed by clojure.compiler
,
e.g.
java -Dclojure.compiler.elide-meta='[:doc :file :line]'
When the reader finds an invalid character in a Unicode string literal, it now reports the character instead of its numerical representation.
hash
no longer directly uses .hashCode() to return the hash of a Clojure
data structure. It calls clojure.lang.Util.hasheq
, which has its own implementation
for Integer, Short, Byte, and Clojure collections. This ensures that the hash code
returned is consistent with =
.
*core-java-api*
will now return the URL for the Java 7 Javadoc when you are
running Java 7.
A static method, loadLibrary
, was added to clojure.lang.RT
to load a
library using the system ClassLoader instead of Clojure's class loader.
Java int
s are now boxed as java.lang.Integer
s. See
the discussion on clojure-dev
for more information.
(= char char)
is now optimizedequiv
is inlined in variadic =toString
cached on keywords and symbols
- CLJ-829 Transient hashmaps mishandle hash collisions
- CLJ-773 Macros that are expanded away still have their vars referenced in the emitted byte code
- CLJ-837 java.lang.VerifyError when compiling deftype or defrecord with argument name starting with double underscore characters
- CLJ-369 Check for invalid interface method names
- CLJ-845
Unexpected interaction between protocol extension and namespaced method keyword/symbols
- Ignoring namespace portion of symbols used to name methods in extend-type and extend-protocol
- CLJ-852 IllegalArgumentException thrown when defining a var whose value is calculated with a primitive fn
- CLJ-855 catch receives a RuntimeException rather than the expected checked exception
- CLJ-876 #^:dynamic vars declared in a nested form are not immediately dynamic
- CLJ-886 java.io/do-copy can garble multibyte characters
- CLJ-895
Collection.toArray implementations do not conform to Java API docs
- obey contract for toArray return type
- CLJ-898
Agent sends consume heap
- Only capture a shallow copy of the current Frame in binding-conveyor-fn, so that sends in agent actions don't build infinite Frame stacks
- CLJ-928 Instant literal for Date and Timestamp should print in UTC
- CLJ-931 Syntactically broken clojure.test/are tests succeed
- CLJ-933 Compiler warning on clojure.test-clojure.require-scratch