Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the order of function calls inside a Clojure map guarantee runtime order processing?

Tags:

clojure

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:

  • How would I do that?
  • And anyway, is the order of values in a map enough to guarantee that a function will always be called before another?
like image 248
brenobarreto Avatar asked Jul 24 '26 15:07

brenobarreto


2 Answers

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 ...})
like image 167
amalloy Avatar answered Jul 26 '26 06:07

amalloy


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.

like image 31
Alex Miller Avatar answered Jul 26 '26 06:07

Alex Miller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!