When round brackets are used, the first element in the list defines how the rest of the list is interpreted, for example:
(func a b c) — run a function with its parameters
(macro x y z) — expand a macro with its parameters
([p q r] …) — “bare” function body that starts with a vector of parameters, and executable forms follow.
Square brackets are used where elements are the same “kind”, and the first one is not special, e.g.:
(defn f [a b c] …) — a collection of same-kind parameters, the first parameter is not special
(let [a 1 b 2] …) — a collection of bindings, the first binding is not special
The only exception that comes to mind is grouping multiple matching elements in `case`, but it for ergonomics.
Once I got the logic, when which is used, I changed my mind, and ever since I’ve felt it’s beautiful.