Skip to content

Commit e706f98

Browse files
authored
Merge pull request #269 from bbatsov/add-collections-section-examples
Add examples and rationale to the Data Structures section
2 parents adae12c + d41cdf4 commit e706f98

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

README.adoc

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,11 +1947,24 @@ ____
19471947
=== Avoid Lists [[avoid-lists]]
19481948

19491949
Avoid the use of lists for generic data storage (unless a list is
1950-
exactly what you need).
1950+
exactly what you need). Vectors provide O(1) indexed access, efficient
1951+
`conj` at the end, and work better with the rest of the standard
1952+
library.
1953+
1954+
[source,clojure]
1955+
----
1956+
;; good
1957+
[1 2 3]
1958+
1959+
;; bad - a list used as a mere container
1960+
'(1 2 3)
1961+
----
19511962

19521963
=== Keywords For Hash Keys [[keywords-for-hash-keys]]
19531964

1954-
Prefer the use of keywords for hash keys.
1965+
Prefer the use of keywords for hash keys. Keywords are interned (fast
1966+
equality checks), can be used as functions to look themselves up in a
1967+
map, and stand out visually from values.
19551968

19561969
[source,clojure]
19571970
----
@@ -1984,6 +1997,18 @@ when the values are compile-time constants.
19841997
=== Avoid Index Based Collection Access [[avoid-index-based-coll-access]]
19851998

19861999
Avoid accessing collection members by index whenever possible.
2000+
Destructuring and sequence functions convey intent more clearly and
2001+
don't break when the collection order changes.
2002+
2003+
[source,clojure]
2004+
----
2005+
;; good - destructuring makes the meaning clear
2006+
(let [[x y] point]
2007+
(process x y))
2008+
2009+
;; bad - fragile and says nothing about what's at index 0 and 1
2010+
(process (nth point 0) (nth point 1))
2011+
----
19872012

19882013
=== Keywords as Functions for Map Values Retrieval [[keywords-as-fn-to-get-map-values]]
19892014

@@ -2028,16 +2053,51 @@ Leverage the fact that keywords can be used as functions of a collection.
20282053
=== Avoid Transient Collections [[avoid-transient-colls]]
20292054

20302055
Avoid the use of transient collections, except for
2031-
performance-critical portions of the code.
2056+
performance-critical portions of the code. Transients add complexity
2057+
(they must not be shared across threads and require a different set of
2058+
mutation functions) while persistent collections are already quite fast
2059+
for most use cases.
2060+
2061+
[source,clojure]
2062+
----
2063+
;; good - persistent collections are fine for everyday code
2064+
(reduce conj [] (range 1000))
2065+
2066+
;; ok in a hot path where benchmarks justify it
2067+
(persistent! (reduce conj! (transient []) (range 1000)))
2068+
----
20322069

20332070
=== Avoid Java Collections [[avoid-java-colls]]
20342071

2035-
Avoid the use of Java collections.
2072+
Avoid the use of Java collections. Java collections are mutable and do
2073+
not implement Clojure's sequence abstractions, making them incompatible
2074+
with the standard library.
2075+
2076+
[source,clojure]
2077+
----
2078+
;; good
2079+
{:name "Bruce" :age 30}
2080+
2081+
;; bad
2082+
(doto (java.util.HashMap.)
2083+
(.put :name "Bruce")
2084+
(.put :age 30))
2085+
----
20362086

20372087
=== Avoid Java Arrays [[avoid-java-arrays]]
20382088

20392089
Avoid the use of Java arrays, except for interop scenarios and
2040-
performance-critical code dealing heavily with primitive types.
2090+
performance-critical code dealing heavily with primitive types. Arrays
2091+
are mutable, have no literal syntax, and don't print readably.
2092+
2093+
[source,clojure]
2094+
----
2095+
;; good
2096+
[1 2 3]
2097+
2098+
;; bad - unless required for interop or primitive performance
2099+
(int-array [1 2 3])
2100+
----
20412101

20422102
== Types & Records
20432103

0 commit comments

Comments
 (0)