Будет ли это рассматриваться как идиоматический ClojureScript?

Я экспериментирую/изучаю ClojureScript. После интерфейса фрагмента кода с отличным d3.js lib для отображения некоторых кругов. Найдите, что это бит многословный, не прибегая к макросам, есть ли способ его оптимизировать/минимизировать?

(def rdata (atom (array 3 10 12 16 19)))

(defn update []
(let [em (.selectAll (.select js/d3 "svg") "circle")
     data (.data em @rdata d3/String)
     enter (.append (.enter data) "circle")
     yscale (.linear (. js/d3 -scale))
     xscale (.linear (. js/d3 -scale))
     rscale (.linear (. js/d3 -scale))
     ]
(-> yscale 
  (.domain (array 0 20))
  (.range (array 100 200)))
(-> xscale
  (.domain (array 0 20))
  (.range (array 100 800)))
(-> rscale
  (.domain (array 0 20))
  (.range (array 50 100)))
(-> enter
  (.attr "cx" xscale)
  (.attr "cy" yscale)
  (.attr "r" rscale)
  (.style "fill" "steelblue")
  (.style "stroke" "black")
  (.style "stroke-width" "2")
  )
)
(.info js/console "rdata: " @rdata)
)

Спасибо

Ответ 1

Чтобы инициализировать весы, вы можете написать (.linear (.-scale js/d3)), что немного более кратким. Кроме того, в этом фрагменте кода нет причин использовать Atom для данных. Если вы хотите обновить визуализацию, вы можете передавать новые данные в качестве аргумента в update вместо того, чтобы мутировать атом и вызывать обновление no-arg fn.

Матрица с потоком, идиоматическая для цепочки, так что вы там хорошо.

И снова вы не можете получить больше идиоматичности, чем использовать прямую библиотеку Clojure; C2, a Clojure (Script) реализация D3. (Конечно, в качестве основного автора я немного склонен к этому.)

Если вам нужно самому использовать D3, вы также можете отключить источник устаревшей cljs-d3 обертки.

Макросы - это один из способов получить более сжатый интерфейс (например, расширение литералов на несколько вызовов (.attr "key" value)), но семантика макроса цепочки позволяет вводить любые fn в цепочку, что сильно отличается от JavaScript дело. Например, вы можете написать простой fn, который принимает выбор d3 и карту атрибутов и использует doseq для вызова (.attr d3 k v) для каждого ключа/значения карты.

Собственно, там 40 минутных разговоров на этом точном предмете (с использованием D3 в качестве примера) из Clojure Conj в прошлом году.