How to make shorthand more readable in Clojure?

A reducecall has its argument f. Visually speaking, this is often the largest part of the form. eg.

(reduce
 (fn [[longest current] x]
   (let [tail (last current)
         next-seq (if (or (not tail) (> x tail))
                    (conj current x)
                    [x])
         new-longest (if (> (count next-seq) (count longest))
                       next-seq
                       longest)]
     [new-longest next-seq]))
 [[][]]
 col))

The problem is that the argument of the argument val(in this case [[][]]) is colgiven below, and it is a long way for your eyes to match the parameters f.

This would look more readable to me if it were in that order:

(reduceb val col
  (fn [x y]
    ...))

Should I implement this macro, or am I not mistaken at all?

+4
source share
6 answers

I need this order for the form:

  • reduce
  • val, col
  • f

I was able to understand that this technically satisfies my requirements:

> (apply reduce
    (->>
     [0 [1 2 3 4]]
     (cons
      (fn [acc x]
        (+ acc x)))))
10

But this is not the easiest thing to read.

:

> (defn reduce< [val col f]
    (reduce f val col))
nil

> (reduce< 0 [1 2 3 4]
    (fn [acc x]
      (+ acc x)))
10

(< " " ). reduce<, , f , f, f ( ). , f , val col, , reduce . , , f reduce, fn .

, , .

0

, , , . ; , :

(-> (fn [x y]
      ...)
    (reduce init coll))

, , , , , :

(reduce (fn [x y]
          ...)
        init, coll)

, , . , . , .

(defn decreasing-subsequences [xs]
  (lazy-seq
    (cond (empty? xs) []
          (not (next xs)) (list xs)
          :else (let [[x & [y :as more]] xs
                      remainder (decreasing-subsequences more)]
                  (if (> y x) 
                    (cons [x] remainder)
                    (cons (cons x (first remainder)) (rest remainder)))))))

reduce :

(apply max-key count (decreasing-subsequences xs))

, , , , , ; , ( , ), , , , . , > in (> y x) , . , , , , .

, , , . , , .

+5

reduce ( ) . :

(def in [3 2 1 0 -1 2 7 6 7 6 5 4 3 2])
(defn descending-sequences [xs]
  (->> xs
       (partition 2 1)
       (map (juxt (fn [[x y]] (> x y)) identity))
       (partition-by first)
       (filter ffirst)
       (map #(let [xs' (mapcat second %)]
               (take-nth 2 (cons (first xs') xs'))))
       (sort-by (comp - count))))

(descending-sequences in)
;;=> ((7 6 5 4 3 2) (3 2 1 0 -1) (7 6))

(partition 2 1) , partition-by . , , .

, < >:

;;=> ((-1 2 7) (6 7))

, , , first . sort-by :

(apply max-key count)

:

(defn greatest-continuous [op xs]
  (let [op-pair? (fn [[x y]] (op x y))
        take-every-second #(take-nth 2 (cons (first %) %))
        make-canonical #(take-every-second (apply concat %))]
    (->> xs
         (partition 2 1)
         (partition-by op-pair?)
         (filter (comp op-pair? first))
         (map make-canonical)
         (apply max-key count))))
+1

... .

2 . , Plumatic Plumbing defnk style:

(fnk-reduce { :fn    (fn [state val] ... <new state value>)
              :init  []
              :coll  some-collection } )

arg, .

, fn . , , reduce:

(let [glommer (fn [state value] (into state value)) ]
   (reduce glommer #{} some-coll))

, ,

(defn glommer [state value] (into state value)) 
(reduce glommer #{} some-coll))

, , , . , .:)

0

-, /.

clojure transducers, , " ", "" . , , .

(def longest-decreasing
   (fn [rf]
     (let [longest (volatile! [])
           current (volatile! [])
           tail (volatile! nil)]
       (fn
         ([] (rf))
         ([result] (transduce identity rf result))
         ([result x] (do (if (or (nil? @tail) (< x @tail))
                           (if (> (count (vswap! current conj (vreset! tail x)))
                                  (count @longest))
                             (vreset! longest @current))
                           (vreset! current [(vreset! tail x)]))
                         @longest)))))))

, , , :

(def coll [2 1 10 9 8 40])
(transduce  longest-decreasing conj  coll) ;; => [10 9 8]
(transduce  longest-decreasing +     coll) ;; => 27
(reductions (longest-decreasing conj) [] coll) ;; => ([] [2] [2 1] [2 1] [2 1] [10 9 8] [10 9 8])

, , , ( , 1 ?)

0

, iterate reduce. , iteratee, iterate :

(defn step-state-hof [op]
  (fn [{:keys [unprocessed current answer]}]
    (let [[x y & more] unprocessed]
      (let [next-current (if (op x y)
                          (conj current y)
                          [y])
            next-answer (if (> (count next-current) (count answer))
                         next-current
                         answer)]
        {:unprocessed (cons y more)
         :current     next-current
         :answer      next-answer}))))

current , , answer, answer. , op , current.

iterate , , :

(def in [3 2 1 0 -1 2 7 6 7 6 5 4 3 2])
(->> (iterate (step-state-hof >) {:unprocessed (rest in)
                                  :current     (vec (take 1 in))})
     (drop (- (count in) 2))
     first
     :answer)
;;=> [7 6 5 4 3 2]

Often you should use a short circuit drop-whileor take-whileonly when the answer is received. We could do so that, however, a short circuit is not required here, since we know in advance that the inner function step-state-hofshould be called (- (count in) 1)once. This is less than an account because it processes two elements at the same time. Note what firstcauses the final call.

0
source

Source: https://habr.com/ru/post/1675222/


All Articles