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](http://clojure.org/special_forms) and [macros](http://clojure.org/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 `clojure.lang.IFn`: (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 because I couldn't come up with anything better that involved IO and wasn't too long: (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