I think it may be one of those things you have to see in order to understand.
I think it may be one of those things you have to see in order to understand.
For example:
(let [result {:a 1}
result (assoc result :b 2)]
...)
He mentions that C and C++ allow const variables, but Clojure doesn't support that.clj-kondo has a :shadowed-var rule, but it will only find cases where you shadow a top-level var (not the case in my example).
I think in practice this is the ideal middle ground of convenience (putting version numbers at the end of variables being annoying), but retaining mostly sane semantics and reuse of prior intermediate results.
The `assoc` on the second binding is returning a new object; you're just shadowing the previous binding name.
This is different than mutation, because if you were to introduce an intermediate binding here, or break this into two `let`s, you could be holding references to both objects {:a 1} and {:a 1 :b 2} at any time in a consistent way - including in a future/promise dereferenced later.