I'm confused why you don't see this as obvious. (There are several possible ways to represent mappings. I picked one that was close to something that you're happy with.)
Clojure uses {} for maps, #{} for sets, and [] for vectors, and vectors are used in function definitions, let statements, etc. This slight decrease in regularity makes a lot of functionality more visible. For example:
SBCL:
(defun f (x y) (let ((z (gethash x :a))) (+ z y))
Clojure
(defn f [x y] (let [z (get x :a)] (+ x y)))
Having syntax for maps is a huge win. Like ML's pattern matching, it's one of those things that changes your coding style entirely for the better, in a way that you wouldn't predict just by looking at the feature.
The only think I miss from CL when I work in Clojure is keyword arguments to functions. There, the Clojure way is a bit worse:
(defun f (x &key y z) (list x y z))
(f 2 :z 3) => (2 nil 3)
(defn f [x {y :y z :z}] (list x y z))
(f 2 {:z 3}) => (2 nil 3)
> (defun f (x y) (let ((z (gethash x :a))) (+ z y))
vs
> (defn f [x y] (let [z (get x :a)] (+ x y)))
The CL defn of f is a function that is called with two arguments. That function is called like "(f a b)" If the Clojure definition is comparable, that is, the call looks like "(f a b)", why are []s used in the definition and the let?
> This slight decrease in regularity makes a lot of functionality more visible.
What functionality? x,y aren't part of a vector and neither is z. (x,y may come from a vector in the caller, but I'll assume that the defn works if they don't, so
that shouldn't matter.)
{ ("x" ( { ("y" "a") ("z" 23) ("q" ( 54 32 45 )) } )) ("r" 43) }