Any book on clojure and website too will go over them. They are fundamental to using clojure.
I don't know enough about haskell to say what it does or doesn't have in relation to clojure. However, it's not simply the data structures, but how the language is built to interact with them from a programmers perspective.
From a user interface to the language point of view, I find the ways of interacting with maps to be very nice.
In particular the dual purpose of "keywords" to serve both as a good index/key in said hash maps, but also as callable look up function for the same key in a hash map leads to simplified code.
This, coupled with the extremely high usage of those maps in typical clojure code, makes a big difference.
To expand on that a little, "keywords" are symbols that begin with a colon, which I believe is the same as common lisp. :for :example :this :is :a :sentence :of :keywords. They are commonly used as the key in a map. Which has a literal syntax like (def map1 {:a 1 :b 2 :c "taco"}). To pull a value out, you can evaluate (:c map1) which will return "taco".
They are hash maps based on work by Philip Bagwell, and I think a lot of languages have versions of this now. At least scheme and Common Lisp do. But I don't believe they have the nice literal syntax and interaction syntax.
Many Lisp traditionalists are bothered by the use of curly braces for maps and square brackets for vectors, however I'm a fan. Without this bit of syntax, you have to add verbosity to the language to differentiate defining a map from doing a lookup, etc.
For resources, Clojure for the Brave and True is pretty popular. Also the online community is quite friendly, although I have noticed some trends toward "the one true way" of doing things that puts me off a little.
>Many Lisp traditionalists are bothered by the use of curly braces for maps and square brackets for vectors
I have definitely seen this. I'm not sure that I understand this sentiment. The only thing that Clojure is missing is the "system" feel that Common Lisp provides, with things like character macros, symbol macros, etc.
That being said, I definitely appreciate how thought through Clojure is, especially when compared to CL. Several things are missing/don't feel well thought out in CL (notion of a `calleable` type is gone, `nth` isn't defined on vectors or strings (but you can still `length` them!) nor is `first` and `rest`) That provides a great deal of friction.
Common Lisp had a lot thought put into it, but the design goals were different. One of the design goals was to support efficient compilation given various constraining dimensions: the need for speedy compilers vs. the need for delivery of applications on standard hardware. Thus a Lisp compiler should be able to generate fast code, even by using whole-program compilation. Thus the language has to take care of a wide range of possible implementations, not just one on a particular virtual machine.
Clojure OTOH has a relatively straight-forward compiler written in Java, only targetting the JVM in a standard way. The Java/JVM infrastructure for code generation (JIT), low-level optimizations (JIT), memory management, application building and delivery could be reused. With all its features and limitations (for example no TCO, fixed JVM instruction set, ...).
Common Lisp also not only provides some generic operators, but also lots of non-generic operators. One reason for that is the will for backwards compatibility (which was another goal in the Common Lisp design) and the idea that something like Common Lisp is also a low-level languages or provides at least a layer of low-level stuff, functions you would use to implement higher-level stuff.
Common Lisp is the next step in the evolution of Lisp I to Lisp 1.5 to Maclisp to Zetalisp. Thus it contains much of the core Lisp functions, stuff you can read about it the Lisp manuals from 1958 and 1960. People did not want to throw their code away, they wanted a modernized Maclisp. Thus one could port a 100kloc Lisp program from Maclisp or Zetalisp to Common Lisp without too much effort. The main operations were there.
Clojure OTOH has almost no backwards compatibility to earlier Lisp dialects. Programs can not be ported from Lisp to Clojure in a useful way. They have to be rewritten. But that was okay, since the main target were not Lisp developers, but people who wanted a language with Lisp influence in the Java/JVM eco-system (or possibly other eco-systems too).
Thus Common Lisp looks to you like it has less thought put in, where people actually struggled to be backwards compatible and modernize the language at the same time.
So Common Lisp has lots of non-generic functions, a layer of generic non-extensible functions (like the sequence layer) and a mechanism for extensible generic functions (CLOS). Something like CLOS is implemented on-top of the non-generic Lisp, with a few parts using implementation specific mechanims. One does not need to use the primitives of a different host language, because Common Lisp is already capable of hosting with its primitives.
You can do this using the metaobject protocol and defining a class with a metaclass of FUNCALLABLE-STANDARD-CLASS, for example, given:
(defclass c ()
((x :initarg :x :accessor x))
(:metaclass funcallable-standard-class))
(defmethod initialize-instance :after ((c c) &key)
(with-slots (x) c
(set-funcallable-instance-function
c
#'(lambda ()
(format t "~&I'm #~a" x)))))
Then (funcall (make-instance 'c :x 3)) will print "I'm #3".
> `nth` isn't defined on vectors or strings (but you can still `length` them!)
ELT in Common Lisp is generic over sequence types. NTH is specific to lists. If you want to write a function that is generic over sequences, use ELT. If you know that you have a list or an array, and you're writing something performance sensitive, you can avoid type dispatch overhead by using NTH or AREF instead of ELT.
> nor is `first` and `rest`
You can avoid that friction a lot of the time by writing in terms of MAP, REDUCE, REMOVE-IF-NOT, and so on, as well as LENGTH and ELT, which are all generic over sequences, or doing (iter (for x in-sequence sequence) ...) or whatever.
But if you really want to use FIRST and REST to walk through a vector, you can do (coerce vector 'list) first to convert it. Coercing a list to list will just return that list, so that version would work for either, too. I admit, there's no real reason I know of (aside from lack of demand) that there isn't a predefined function like:
> Many Lisp traditionalists are bothered by the use of curly braces for maps and square brackets for vectors, however I'm a fan. Without this bit of syntax, you have to add verbosity to the language to differentiate defining a map from doing a lookup, etc.
I agree with you, in the sense that they are useful, however the complain of "Lisp traditionalists" will be that in any case, if you need them, you can add them to Common Lisp by using reader macros. So in CL the curly braces and brackets are "free" to be used (i.e. define what they should do) in any way you want; on Clojure they are already taken, so it feels a bit uncomfortable.
I don't know enough about haskell to say what it does or doesn't have in relation to clojure. However, it's not simply the data structures, but how the language is built to interact with them from a programmers perspective.
From a user interface to the language point of view, I find the ways of interacting with maps to be very nice.
In particular the dual purpose of "keywords" to serve both as a good index/key in said hash maps, but also as callable look up function for the same key in a hash map leads to simplified code.
This, coupled with the extremely high usage of those maps in typical clojure code, makes a big difference.
To expand on that a little, "keywords" are symbols that begin with a colon, which I believe is the same as common lisp. :for :example :this :is :a :sentence :of :keywords. They are commonly used as the key in a map. Which has a literal syntax like (def map1 {:a 1 :b 2 :c "taco"}). To pull a value out, you can evaluate (:c map1) which will return "taco".
They are hash maps based on work by Philip Bagwell, and I think a lot of languages have versions of this now. At least scheme and Common Lisp do. But I don't believe they have the nice literal syntax and interaction syntax.
Many Lisp traditionalists are bothered by the use of curly braces for maps and square brackets for vectors, however I'm a fan. Without this bit of syntax, you have to add verbosity to the language to differentiate defining a map from doing a lookup, etc.
For resources, Clojure for the Brave and True is pretty popular. Also the online community is quite friendly, although I have noticed some trends toward "the one true way" of doing things that puts me off a little.