← Back to context

Comment by barrell

2 days ago

This is not the best example, it's just the most recent example (what I was doing last night) that can fit in one screen:

  (defn report [date]
    (let [[d w m q y] (-> (comp tier* recall* (partial c/shift date :day)) 
                          (map [1 7 30 90 365]))]
      (reduce (fn [memo {:keys [card code]}]
                (cond-> memo 
                  true (update code (fnil update [0 0 0 0 0 0 0 0 0 0]) (q card) inc)
                  (<= 4 (d card)) (update-in [code 6] inc)
                  (<= 4 (w card)) (update-in [code 7] inc)
                  (<= 4 (m card)) (update-in [code 8] inc)
                  (<= 4 (y card)) (update-in [code 9] inc)))
              {} 
              (k/index :intels)))))

The elixir code I was able to condense down into:

  def report(facets, intels, day) do
    [d, w, m, q, y] = for x <- [1, 7, 30, 90, 365], do: Date.shift(day, day: x)

    Enum.reduce(intels, %{}, fn intel, acc ->
      facet = Map.get(facets, intel.uuid, :zero)

      [q0, q1, q2, q3, q4, q5, d4, w4, m4, y4] =
        acc[intel.code] || [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

      quarterly_tier = tier(facet, q)

      Map.put(acc, intel.code, [
        if(quarterly_tier == 0, do: q0 + 1, else: q0),
        if(quarterly_tier == 1, do: q1 + 1, else: q1),
        if(quarterly_tier == 2, do: q2 + 1, else: q2),
        if(quarterly_tier == 3, do: q3 + 1, else: q3),
        if(quarterly_tier == 4, do: q4 + 1, else: q4),
        if(quarterly_tier == 5, do: q5 + 1, else: q5),
        if(tier(facet, d) >= 4, do: d4 + 1, else: d4),
        if(tier(facet, w) >= 4, do: w4 + 1, else: w4),
        if(tier(facet, m) >= 4, do: m4 + 1, else: m4),
        if(tier(facet, y) >= 4, do: y4 + 1, else: y4),
      ])
    end)
  end

It was much longer prior to writing this comment (I originally used multiple arity helper functions), but it was only fair I tried my best to get the elixir version as concise as possible before sharing. Still 2x the lines of effective code, substantially more verbose imho, and required dedicated (minor) golfing to get it this far.

Replacing this report function (12 lines) + one other function (6 lines) + execution code (18 lines) is now spread across 3 modules in Elixir, each over 100 lines. It's not entirely apples to oranges, but trying to provide as much context as possible.

This is all just to say that the high effort in reading it is normally a result of information density, not complexity or syntax. There are real advantages to being able to see your entire problem space on a single page.