I'm working on the following function:
(defn process-request [request]
(if (not (db/empty?))
{:person (db/get-person!) :violations (:violations (process-violations request))}
{:person {} :violations ["no-person"]}))
I need the process-violations function to only be called if the db is not empty. That's why it's in the if block.
However, I also need it to be called before the db/get-person! function. Otherwise, the value will be outdated.
So I wonder:
No, maps are not ordered. For small literal maps it will probably work, but you should not rely on it, and for larger maps it indeed does fail:
user=> {0 (println 0) 1 (println 1) 2 (println 2) 3 (println 3) 4 (println 4) 5 (println 5) 6 (println 6) 7 (println 7) 8 (println 8) 9 (println 9)}
0
7
1
4
6
3
2
9
5
8
{0 nil, 7 nil, 1 nil, 4 nil, 6 nil, 3 nil, 2 nil, 9 nil, 5 nil, 8 nil}
But it is always easy to force ordering by using let bindings, which are evalauted, in order, before the let body.
(let [person (db/get-person!)]
{:person person :violations ...})
The reader will read the map in the code into a map, about which you should make no ordering assumptions, so do not rely on the evaluation order of those values. (In reality, it's an array map, and it probably is evaluated in the same order as defined lexically, but you should not rely on that.)
(defn process-request [request]
(if (not (db/empty?))
(let [violations (:violations (process-violations request))
person (db/get-person!)]
{:person person :violations violations})
{:person {} :violations ["no-person"]}))
would be safer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With