Live data from Hacker News

Specter – Clojure API for immutable programming (2017)

nathanmarz.com

11–20 of 44 posts

Re: Specter – Clojure API for immutable programming (2017)

#11

Specter is fantastic. It makes transformations on deeply nested data structures easy. Want to transform all the "datetimes" from JSON data into actual datetimes (or vice versa)? It takes about five minutes if you have to look everything up. Works with ClojureScript too. Some production code: (defn transform-tagged-values [x] (sp/transform (sp/walker tr/tagged-value?) tagged-value->cljs x)) Give it a predicate for whi…

It really does remove multiple layers of complexity that usually stand between your mental model of what your transformation function should do and the code that actually implements it. With Specter if I can clearly articulate the transformation I want to do on a data structure, then I can almost always translate that one-to-one into the code that does the transformation.

When I started using it in one of my existing projects I was able to completely eliminate a few needlessly long and complex functions that were littered with comments and calls to helper functions. In their place are functions that are about 5 lines of code that barely even need a docstring because it's readily apparent what they do just by looking at the source.

Re: Specter – Clojure API for immutable programming (2017)

#12
Specter is always on my clojure toolbox. Not only it makes transforming arbitrarily nested data painless, it also is usually more efficient than the average hand-rolled code!

A great example of why macros in Lisp are powerful, and how they empower you as a user even if you never write one.

Re: Specter – Clojure API for immutable programming (2017)

#14
post #10
post #2

I invented instar ( https://github.com/boxed/Instar ) which is quite similar to specter (imo a little bit nicer) because I also thought the built in API was weirdly clunky in these respects.

What's the performance vis-a-vis Specter?

I have never run a benchmark and the specter guy really cares about it so instar is probably way worse :)

I was more trying to show that the API could be better and hoping this would put pressure on core devs to do it properly.

Re: Specter – Clojure API for immutable programming (2017)

#15
post #8

Like SQL for nested maps in Clojureland. Neat. The DSL [ALL :a even?] does feel a tiny bit un-clojurey to me as well, maybe making it look like [:all :a even?] would make it clearer.

In instar it's [* :a even?] which I think is prettier... being the author of instar :)

Re: Specter – Clojure API for immutable programming (2017)

#16
post #8

Like SQL for nested maps in Clojureland. Neat. The DSL [ALL :a even?] does feel a tiny bit un-clojurey to me as well, maybe making it look like [:all :a even?] would make it clearer.

Well there’s a reason it’s like that — ALL is actually a value, not just a sentinel or keyword. It’s found at com.rpl.specter/ALL.

Keywords don’t form a DSL in Specter, they just do keyword navigation into maps, the same way ‘0’ navigates into the first element of a list.

This touches upon a really nice element of Specter, which is its pattern for reuse. Here’s a very real but deliberately simple example of using it:

  (def chat-threads
    {[“sova” “tekacs”]
     [{:text [“hey” “you there?”]}
      {:text [“line 1” “line 2”]}]})
  
  (def ALL-TEXT
    [sr/ALL :text sr/ALL])
  
  (defn text-for [chat]
    (sr/select [chat ALL-TEXT]))

  (def ALL-CHAT-TEXT
    [sr/MAP-VALS ALL-TEXT])
  
  (text-for [“sova” “tekacs”]) ;=> [...]
Here the navigator into a list, then the :text field and then the list is bottled simply by putting several navigators in a vector.

Then, it can be used alongside other navigators in a first class fashion — [chat ALL-TEXT] is just a nested vector. :)

Re: Specter – Clojure API for immutable programming (2017)

#19
Specter is really handy for manipulating data structures, and have been happily using it.

I wonder, is it possible to select some subset of a map? Say you have these paths:

(def paths [[:some :path] [:another :deeper :path] [:yet :another :one] [:yet :another :one :deeper]])

And select from a map these paths. You could do it with get-in, but maybe Specter can do it faster? I couldn't find a way to do it with Specter...

Re: Specter – Clojure API for immutable programming (2017)

#20
post #6

Specter is tremendously useful and rarely lets on a case where it can’t perform a transformation. For ensuring that you’re getting the most efficient form of a transformation [0] it’s incredible —- and it is somewhat data-oriented, allowing easy saving and reuse of navigators. Meander [1] is also wonderful. Its unification-based approach makes for nice expressions of intent. Its strategy-based approach to rewriting […

So specter is lens and meander is syb/generics. Nice
Post reply on HN