Consider this snippet of C code:

struct foo {
int x;
}

Do you care how the structure definition is represented in your
compiler? is it a list, a vector or a custom data-structure? You don't
know, and it doens not matter to you. Besides, it is totally different
from what you manipulate at runtime (for type definitions, not
much). Consider the second snippet:

for(int i = 0; i < n; ++i) {
// something
}

Should the internal representation for the block delimited by braces
be necessary the same as the one used to represent the fields in the
previous structure? I mean, do the brace characters always map to the
same internal data-structure? Probably not. In C, the concrete syntax
has generally nothing to do with the abstract syntax. This is not the
case in Lisp, because each syntax is used to parse a specific type of
data.

In Clojure, you write #{...} and the reader (LispReader.java) sees the
sharpsign followed by brace and builds a set containing the values
inside the braces. That set is contained inside the AST, and acts as a
literal value. That value is shared among all invocations of your
code, meaning that if you call the enclosing function at different
places, the same literal object is shared. Since this data is
immutable, this is not really a problem because when you add more
elements at runtime, the original literal is not modified. OTOH, you
can still invoke EvalReader, #=(), which evaluates code at
read-time. I believe that you can put mutable data-structures into the
AST and obtain funny results by mutating it during execution.

How is it different from Common Lisp? Not much.

Common Lisp is less restrictive because the readtable can be
customized. Also, the standard data-structures are mutable (however,
the behavior is undefined if you try to mutate literal data; some
compilers warn you about that). I don't think I ever needed to have
hash-table as a literal, it seems practically useless because if you
want a hash-table in your source code, odds are that it contains few
elements. If so, an association list is simpler (and more efficient).

If you really really need a complex data-structure in your source
code, you are more likely to use LOAD-TIME-VALUE anyway, because it
works better with a compiler: not all data-structures are (nor should
be) automatically serialisable in the object file (they could containt
transient data, for example). In other words, your original code has
little to do with the machine code that is produced and eventually
loaded (possibly in another environment). LOAD-TIME-VALUE is a way to
execute code at load-time to produce such data-structures in your
code: I have a parser which pre-computes some regexes, and this is not
something that has an equivalent in Clojure, as far as I know.

So my first point is: you can have literals of any type in your source
code in Common Lisp (like in Clojure). All of them have dedicated
syntax, like vectors of arbitrary dimensions #2A((1 2)(3 4)), bit
vectors #*1111, complex numbers #C(0 1), pathnames #P"/tmp/foo", and
of course strings. Likewise, you have a generic syntax for
structures. Suppose you define a structure FOO with a single slot X,
then #S(foo :x 10) is a literal of that type.

However, not all data-structures have such syntax: maybe it was not
deemed necessary to represent literal hash-tables in source code, or
maybe it did not make it to the standard, I don't know. I personally
don't miss it and I am happy to use auto-complete the few times I need
a hash-table. However, if you want you can customize your Lisp easily;
for example, load the FSET library and provide a custom syntax over
immutable data-structures. If you look at Maxima, it has a lot of
custom syntax. And I am not talking about macros, but about changing
the readtable which reads Lisp objects from a stream. An example of
this is RUTILS[0], which provides the #h(equal "k1" v1 "k2" v2) syntax
for hash-table. But note that this notation is only used to produce a list,
namely the code required to produce a hash-table at runtime and
populate it.

Which brings me to my second point: there is a big difference with
Clojure in that Common Lisp doesn't use different types to provide
syntactic sugar. For example, in Clojure [] is for vectors, {} is for
maps and #{} is for sets. That literally means that when you have a
binding, you allocate a vector. When you destructure a map with
map-notation, you use internally a map. So the language is mixing two
concepts: syntactic sugar and actual internal representation. I find
this rather hackish but I can live with it because it probably has
little incidence. I think it adds complexity to the compiler which has
to walk different kinds of code. Besides, the usage of such syntax is
not regular: sometimes vectors are for unevaluated data, sometimes for
bindings or destructuring, so you still need context to know what you are
doing. Those are minor points, and I understand that Clojure can look more convenient to use. However Common Lisp being a little more wordy is not a problem for me.

[0] http://lisp-univ-etc.blogspot.fr/2016/05/improving-lisp-ux-o...