Fork me on GitHub
#specter
<
2018-08-08
>
souenzzo14:08:40

I need to add a item( :NEW ) before a pred ( map? ) just on first match. exaple: [:foo :bar {} {}] into [:foo :bar :NEW {} {}] I'm using mapcat and a atom to say if it's the first match. There is a simpler way to do that?

souenzzo15:08:47

There is BEFORE-ELEM but can't understand how to compose it.

nathanmarz15:08:04

@souenzzo you can do something like:

(defn index-matching [p]
  (fn [s]
    (select-first [INDEXED-VALS (selected? LAST (pred p)) FIRST] s)
    ))

(setval
  [(srange-dynamic (index-matching map?) (end-fn [_ i] i))
   BEFORE-ELEM]
  :NEW
  [:foo :bar {} {}]
  )

👍 4
nathanmarz15:08:41

probably want to modify it a little to handle the case where nothing matches the predicate

jsa-aerial19:08:41

suppose, you have a transform ALL function which makes substitutions that may themselves need to have substitutions and so reapply the transform on result until no more substitutions involved. Is the obvious soln such as (->> x (iterate xform) (drop-while (comp not test)) first) still the 'right' way to do this with specter? Or is there an even more idiomatic way?

nathanmarz19:08:25

@jsa-aerial you could always do something like:

(def iterated-path
  (recursive-path [test] p
    (stay-then-continue
      (pred test)
      p
      )))
(transform (iterated-path #(< % 10)) inc 1)
;; => 10

jsa-aerial20:08:47

@nathanmarz that looks very interesting - let me take a hack with that. Thanks!

jsa-aerial20:08:24

Hmmmm, actually the test needs the last two values. Basically let x1 and x2 be the last two values, iterate until (= x1 x2).

nathanmarz20:08:54

@jsa-aerial

(def FIXED-POINT-PATH
  (recursive-path [] p
    [(collect-one STAY)
     (multi-path
       [DISPENSE STAY]
       [(collect-one STAY)
        (if-path (collected? [a b] (= a b))
          STOP
          [DISPENSE p]
          )])
     ]))

(defn f [a] (min (inc a) 10))
(transform [:a FIXED-POINT-PATH] f {:a 1 :b 2})
;; => {:a 10 :b 2}

nathanmarz20:08:18

that's an interesting one

nathanmarz20:08:37

actually can shorten the definition like this:

(def FIXED-POINT-PATH
  (recursive-path [] p
    [(collect-one STAY)
     (multi-path
       [DISPENSE STAY]
       [(collect-one STAY)
        (if-path (collected? [a b] (not= a b))
          [DISPENSE p]
          )])
     ]))

nathanmarz20:08:36

I'd probably just write that in regular clojure though

jsa-aerial20:08:00

I think it will be instructive to study these two - even though for the particular case in question the solution actually looks simpler in straight clojure