First, a disclaimer: I'm not deeply familiar with the uniform access principal so you may want to take this with a grain of salt. That said, I would argue that Clojure does observe a uniform access principle: function calls.
The key quote on Wikipedia seems to be that "all services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation", and that's exactly the case with function calls in Clojure. In fact, everything in Clojure (and other Lisps) is a function call except for special forms and macros - and macros actually are functions, with the distinction that they operate on source code. You can even specify function call behavior for your own types by implementing
(deftype Invokable  clojure.lang.IFn (invoke [this] :was-invoked)) (def invokable (Invokable.)) (invokable) ;=> :was-invoked
You may have in mind the use of keywords as functions, which are most specifically associated with hash-maps, but you can actually implement that behavior for different types as well. Here's a silly example where keyword access reads a file (with the same name as the keyword) from your home directory, or returns a default value if such a file doesn't exist:
(ns weird.example (:require [clojure.java.io :as io])) (deftype WeirdKlass  clojure.lang.ILookup (valAt [this k not-found] (let [home (System/getProperty "user.home") file (io/file home (name k))] (if (.isFile file) (slurp file) not-found))) (valAt [this k] (.valAt this k nil))) (def klass (WeirdKlass.)) ;; assuming you have a file at $HOME/testfile (:testfile klass) ;=> "test content!" (:blah klass) ;=> nil (:blah klass :not-found) ;=> :not-found