Edward
Edward

Reputation: 4651

What is the Clojure-way of "do additional stuff when ..."

I have a function "my-func", that processes the map x it gets as a parameter and returns a map. The processing is quite long so here I transferred it to the function block-with-several-function-calls-on-x If the incoming map contains :special-key, an additional key-value-pair should be added to the outgoing map.

(defn my-func [x]
  (if (contains? x :special-key)
    (assoc (block-with-several-function-calls-on-x x)
           :extra-key true)
    (block-with-several-function-calls-on-x x)))

I'd really like to keep the code of block-with-several-function-calls-on-x within my-func. I other programming languages, I'd simply save the output of that part within a variable and (if necessary) add the additional part afterwards and than return the value. I was told that using let is not "Clojuresque".

So is transferring the code to a function (as I did above) the only way? or is the a do-additonal-stuff-to-output-of-second-block-function:

(defn my-func [x]
  (do-additional-stuff-to-output-of-second-block
    (when (contains? x :special-key)
      (assoc :extra-key true))
    (block-with-several-function-calls-on-x x)))

Upvotes: 4

Views: 87

Answers (3)

xsc
xsc

Reputation: 6073

cond-> and cond->> are conditional versions of -> and ->> and might fit your need:

(defn my-func
  [x]
  (cond-> (block-with-several-function-calls-on-x x)
    (contains? x :special-key) (assoc :extra-key true)
    (contains? x :other-key)   (dissoc :we-dont-need-this)))

Although, with only one condition this might not be the epitome of readability.

Upvotes: 3

Thumbnail
Thumbnail

Reputation: 13483

Despite the advice you've had, I'd use let:

(defn my-func [x]
  (let [ans (block-with-several-function-calls-on-x x)]
    (if (contains? x :special-key)
      (assoc ans :extra-key true)
      ans)))

Notes:

  • The only value you mention is boolean. If all your values are boolean, use a set, not a map.
  • If not, I doubt that you have false (false or nil) values. In their absence, you can replace (contains? x :special-key) with (x :special-key) or (:special-key x).

Upvotes: 1

juan.facorro
juan.facorro

Reputation: 9930

The following option might be more idiomatic and concise than your current one. It avoids repeating the call to the block-with-several-function-calls-on-x function and uses when to convey the meaning of the lack of an alternative in the conditional.

(defn block-with-several-function-calls-on-x [x]
  x)

(defn my-func [x] 
  (into (block-with-several-function-calls-on-x x)
        (when (contains? x :special-key)
          {:extra-key true})))

(my-func {:bla 1 :special-key 2})
;= {:bla 1, :special-key 2, :extra-key true}
(my-func {:bla 1})
;= {:bla 1}

Upvotes: 0

Related Questions