Fork me on GitHub
#clojure
<
2022-07-21
>
Ovidiu Stoica09:07:21

Idiomatic clojure question about conditionally adding elements to a new array. Is it better to do this:

(cond-> []
  conditionA (conj :a)
  conditionB (conj :b))
or
(remove nil? 
    [(when conditionA :a)
     (when conditionB :b)])
or is there a better solution? The current case is for declaratively making an xml node with children Like so
(xml-node :name 
      [(xml-node :kid1)
       (xml-node :kid2)])
But some nodes should only be included on conditions

jumar10:07:53

This also depends on what those conditions are. Without knowing more, I would probably pick cond-> - that looks more clear to me. Btw. there's also #idioms channel

3
Ovidiu Stoica10:07:42

Did not know about the idioms channel, Ty! Indeed the conditions can be 1-2 lines and now writing, I see that it would be cumbersome to say true to all the ones that go in by default without a check. Ty

Max16:07:32

I recently used this approach:

;; From Medley
(assoc-some
  :key1 (some-> val1 not-empty)
  ...)

;; Compare to
(cond->
  (seq val1) (assoc :key1 val1)
  ...)
My case was a little special though: • The value and key names were long, making repeating them in cond-> uncomfortable • All of my conditions could easily be expressed as a fn in clojure.core that returns the value or nil (e.g. not-empty) • In some cases, I needed to run transformations on the values before assoc’ing them, which was easy to do like (some-> val not-empty another-fn) In some cases I also needed to do a nested assoc, so I ended up writing an assoc-some-in helper fn to replace Medley’s assoc-some

Max16:07:14

It also occurs to me that your XML thing looks remarkably similar to Hiccup. You might be able to use hiccup directly, but if you can’t, their approach was to just automatically remove nil from all of the vectors.

👍 1
Diego20:07:44

What’s the proper way of caching .m2 files in github actions? I have this, but it’s not working:

- name: Maven cache
        uses: actions/[email protected]
        with:
          path: /root/.m2/repository
          key: ${{ runner.os }}-maven-${{ hashFiles('shadow-cljs.edn') }}
          restore-keys: |
            ${{ runner.os }}-maven-

Sameer Thajudin20:07:57

This stumped me. Invoke an array with an integer and it returns the element in the position that the integer defines. ([1 2 3] 2) returns 3. The docs don’t seem to mention it. What is the idea behind this?

dpsutton20:07:56

Lots of clojure datastructures implement clojure.lang.IFn and they tend to do what makes sense™.

👍 1
dpsutton21:07:01

maps look up the item provided ({:a 1} :a) -> 1 (#{:a} :a) -> :a as it checks membership and returns the value if its in the set

👍 1
seancorfield21:07:40

It's also worth noting that vectors are associative on their indices:

user=> (ancestors (type [1 2 3]))
#{clojure.lang.ILookup java.lang.Iterable clojure.lang.IEditableCollection clojure.lang.Associative ...
user=> (get [1 2 3] 1)
2
user=> (get [1 2 3] 99)
nil

👍 1