1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
|
<!-- -*- mode: markdown ; mode: visual-line ; coding: utf-8 -*- -->
# Changes to Clojure in Version 1.4
## CONTENTS
<pre>
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
</pre>
## 1 Deprecated and Removed Features
### 1.1 Record and Type Fields that Start With a Dash Can No Longer Be Accessed Using Dot Syntax
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
## 2 New and Improved Features
### 2.1 Reader Literals
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*`.
#### 2.1.1 Instant Literals
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
#### 2.1.2 UUID Literals
Clojure supports literals for UUIDs in the form `#uuid "uuid-string"`. These
literals are parsed as `java.util.UUID`s.
### 2.2 clojure.core/mapv
`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
### 2.3 clojure.core/filterv
`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
### 2.4 clojure.core/ex-info and clojure.core/ex-data
`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}
### 2.5 clojure.core/reduce-kv
`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!"
### 2.6 clojure.core/contains? Improved
`contains?` now works with `java.util.Set`.
### 2.7 clojure.core/min and clojure.core/max prefer NaN
`min` and `max` now give preference to returning NaN if either of their
arguments is NaN.
### 2.8 clojure.java.io/as-file and clojure.java.io/as-url Handle URL-Escaping Better
`as-file` and `as-url` now handle URL-escaping in both directions.
### 2.9 New Dot Syntax for Record and Type Field Access
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.
### 2.10 Record Factory Methods Available Inside defrecord
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))))
### 2.11 assert-args Displays Namespace and Line Number on Errors
`assert-args` now uses &form to report the namespace and line number where
macro syntax errors occur.
### 2.12 File and Line Number Added to Earmuff Dynamic Warning
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.
### 2.13 require Can Take a :refer Option
`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.
### 2.14 \*compiler-options\* Var
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]'
### 2.15 Improved Reporting of Invalid Characters in Unicode String Literals
When the reader finds an invalid character in a Unicode string literal, it
now reports the character instead of its numerical representation.
### 2.16 clojure.core/hash No Longer Relies on .hashCode
`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 `=`.
### 2.17 Java 7 Documentation
`*core-java-api*` will now return the URL for the Java 7 Javadoc when you are
running Java 7.
### 2.18 loadLibrary Loads Library Using System ClassLoader
A static method, `loadLibrary`, was added to `clojure.lang.RT` to load a
library using the system ClassLoader instead of Clojure's class loader.
### 2.19 Java int is Boxed As java.lang.Integer
Java `int`s are now boxed as `java.lang.Integer`s. See
[the discussion on clojure-dev](https://groups.google.com/forum/#!msg/clojure/7-hARL5c1lI/ntnnOweEGfUJ)
for more information.
## 3 Performance Enhancements
* `(= char char)` is now optimized
* `equiv` is inlined in variadic =
* `toString` cached on keywords and symbols
## 4 Bug Fixes
* [CLJ-829](http://dev.clojure.org/jira/browse/CLJ-829)
Transient hashmaps mishandle hash collisions
* [CLJ-773](http://dev.clojure.org/jira/browse/CLJ-773)
Macros that are expanded away still have their vars referenced in the emitted byte code
* [CLJ-837](http://dev.clojure.org/jira/browse/CLJ-837)
java.lang.VerifyError when compiling deftype or defrecord with argument name starting with double underscore characters
* [CLJ-369](http://dev.clojure.org/jira/browse/CLJ-369)
Check for invalid interface method names
* [CLJ-845](http://dev.clojure.org/jira/browse/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](http://dev.clojure.org/jira/browse/CLJ-852)
IllegalArgumentException thrown when defining a var whose value is calculated with a primitive fn
* [CLJ-855](http://dev.clojure.org/jira/browse/CLJ-855)
catch receives a RuntimeException rather than the expected checked exception
* [CLJ-876](http://dev.clojure.org/jira/browse/CLJ-876)
#^:dynamic vars declared in a nested form are not immediately dynamic
* [CLJ-886](http://dev.clojure.org/jira/browse/CLJ-886)
java.io/do-copy can garble multibyte characters
* [CLJ-895](http://dev.clojure.org/jira/browse/CLJ-895)
Collection.toArray implementations do not conform to Java API docs
* obey contract for toArray return type
* [CLJ-898](http://dev.clojure.org/jira/browse/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](http://dev.clojure.org/jira/browse/CLJ-928)
Instant literal for Date and Timestamp should print in UTC
* [CLJ-931](http://dev.clojure.org/jira/browse/CLJ-933)
Syntactically broken clojure.test/are tests succeed
* [CLJ-933](http://dev.clojure.org/jira/browse/CLJ-933)
Compiler warning on clojure.test-clojure.require-scratch
|