Fork me on GitHub
Jimmy Miller03:03:51

(m/rewrite {:items [{:a 10 :b 20 :c 55}
                    {:a 30 :b 40 :c 45}]}
  {:items [{:a !alpha :b !beta} ...]}
  {:items [{:alpha !alpha :b !beta} ...]})


As part of a larger transform, I’m trying to handle parameters that follow this pattern, i.e., they can either express simple operations to apply to a set, or they can express the desired value of the set:

;; owners current state: [3 4 5]
{:owners {:add [1 2] :remove [3 4]}} ;; => {:owner_ids [1 2 5]}
{:owners {:reset [1 2]}} ;; => {:owner_ids [1 2]}
Right now I’m doing the actual application of the add/remove operations in Clojure code in the RHS of a match:
  {:ctx {:db db}
   :attributes {:id 123
                :input {:owners {:add [1 2] :remove [3 4]}}}}
  {:ctx {:db ?db :as ?ctx}
   :attributes {:id ?id
                :input {:owners ?owner-ops}}}
  {:ctx ?ctx
   :attributes {:id ?id
                :input {:owner_ids (apply-ops
                                    (get-current-owners ?db ?id)
Is there a more idiomatic way to do this that expresses more of the transformation in Meander?

👍 2

That looks good to me. Pretty easy to follow.


In terms of idioms, I would say just try to balance what Meander and "vanilla" Clojure are good at. For example, it is totally possible to apply the owner operations you have here using m/rewrite but, apart from being a good exercise, it may confuse people on your team, etc.


Thanks @noprompt, I appreciate the sanity check.

👍 1

I have this rewrite where I’m using m/app to slightly post-process the output. In the case of !description I would like to keep the original value as well as the post-processed one, but mentioning it twice in the output means that 2 descriptions are consumed per :invoice/item. Is there a way to overcome this?


(defn xero-invoice->datom [invoice & {:keys [service/provider]}]
    (assoc invoice ::provider provider)
    {::provider ?provider
     [{:LineItems     [{:UnitAmount  !unit-amount
                        :LineAmount  !line-amount
                        :Description !description
                        :Quantity    !quantity}
       :CurrencyCode  ?currency
       :InvoiceNumber ?invoice-id
       :DateString    ?issue-date
       :Total         ?amount
       :DueDateString ?due-date
       :InvoiceID     ?xero-id
       :TotalTax      ?vat
       :Contact       {:Name ?xero-contact-name}}]}
    {:service/provider ?provider
     :service/consumer (m/app names->consumers ?xero-contact-name)
     :time/issue-date  (m/app instant/read-instant-timestamp ?issue-date)
     :time/due-date    (m/app instant/read-instant-timestamp ?due-date)
     :payment/amount   ?amount
     :payment/currency (m/app currency ?currency)
     :payment/vat      ?vat
     :xero/id          ?xero-id
     :invoice/id       ?invoice-id
     :invoice/items    [{:person/consultant (m/app desc->consultant !description)
                         :xero/description  !description
                         :service/quantity  !quantity
                         :service/unit      :hours
                         :payment/amount    !line-amount}