[ANN] Specter 0.9.2

525 views
Skip to first unread message

Nathan Marz

unread,
Jan 26, 2016, 3:51:25 PM1/26/16
to Clojure
I just released Specter 0.9.2:


Specter solves a near-universal problem encountered when writing Clojure/ClojureScript: the need to transform or query a data structure that's more sophisticated than a basic map or list. It is a library that captures the notion of "navigation" within a data structure and allows for writing elegant queries and transformations. Its performance is close to hand-optimized code so it can be used even in performance-critical code. Additionally, Specter is extensible to any data structure as it is based on a simple protocol.

There have been over 15 releases since I last posted about Specter on the group (almost a year ago), and there's been a ton of improvements since then:

- Precompilation feature enabling performance rivaling hand-optimized code
- Facilities for creating recursive navigators, including pre-walk and post-walk traversals (declarepath/providepath, stay-then-continue, continue-then-stay)
- ClojureScript support
- Conditional navigation (if-path, cond-path)
- Protocol paths: navigate based on the type of data encountered
- "Batteries included" set of navigators that captures majority of use cases dealing with combinations of maps, lists, vectors, and sets

Message has been deleted

Jean Baro

unread,
Jan 28, 2016, 7:11:37 PM1/28/16
to Clojure

Congratulations for the spectacular work and thanks for sharing this with the world.

Alan Thompson

unread,
Jan 29, 2016, 12:10:45 AM1/29/16
to clo...@googlegroups.com
Looks great, Nathan.  I also highly enjoyed your recent interview on the Cognitect podcast .   

One quick question:  In the first example below from the README (verified at the repl), it seems that the (srange ...) function sometimes behaves as a half-open interval [1,4) like the (range ...) function in Clojure).  However, in the 2nd example it seems to behave as a closed interval [2,4].  Is there an easy way of knowing which behavior applies in different situations?

Thanks, 
Alan


Here's how to increment all the odd numbers between indexes 1 (inclusive) and 4 (exclusive):

user> (transform [(srange 1 4) ALL odd?] inc [0 1 2 3 4 5 6 7])
[0 2 2 4 4 5 6 7]

Here's how to replace the subsequence from index 2 to 4 with [-1 -1 -1]:

user> (setval (srange 2 4) [-1 -1 -1] [0 1 2 3 4 5 6 7 8 9])
[0 1 -1 -1 -1 4 5 6 7 8 9]





On Thu, Jan 28, 2016 at 4:11 PM, Jean Baro <jfb...@gmail.com> wrote:

Congratulations for the spectacular work and thanks for sharing this with the world.

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nathan Marz

unread,
Jan 29, 2016, 1:50:00 AM1/29/16
to clo...@googlegroups.com
Both of those examples use half-open intervals :) The first selects the subsequence with indices 1,2,3, and the second selects the subsequence with indices 2,3. You can see in the second example that [2 3] in the overall sequence is replaced by [-1 -1 -1].

You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/XePZ-WSviso/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Twitter: @nathanmarz
http://nathanmarz.com

Alan Thompson

unread,
Jan 29, 2016, 1:27:22 PM1/29/16
to clo...@googlegroups.com
Oh!  I never even suspected that!  So you are replacing a length-2 subsequence with a length-3 subsequence.  Very flexible.

It might be useful to point out that feature in the docs.   :)

Alan

Nathan Marz

unread,
Jan 29, 2016, 2:19:09 PM1/29/16
to clo...@googlegroups.com
I updated the example with a larger replacement sequence to hopefully prevent that confusion in the future.

You can also use srange to eliminate subsequences, e.g.:

(setval (srange 4 7) nil [:a :b :c :d :e :f :g :h :i])
=> [:a :b :c :d :h :i]

And the navigator to prepend to a sequence is just selecting the empty subsequence at the beginning:

(def BEGINNING (srange 0 0))
(setval BEGINNING [:a :b] '(1 2 3))
=> (:a :b 1 2 3)

Alan Thompson

unread,
Jan 29, 2016, 6:30:29 PM1/29/16
to clo...@googlegroups.com
nice.

Jason Lewis

unread,
Jan 29, 2016, 8:08:17 PM1/29/16
to clo...@googlegroups.com
Wow, I hadn't seen this lib before, it really *is* the missing piece in a lot of ways. 

One question, are you considering migrating from cljx to cljc for cross-compiling? We've been trying to eliminate cljx dependencies in favor of cljc, and I'd be happy to help with the effort if it's on the roadmap.

cheers,
Jason

Nathan Marz

unread,
Jan 29, 2016, 8:37:51 PM1/29/16
to clo...@googlegroups.com
It used to use cljc but needed to switch to cljx so that it could be compatible with Clojure 1.6. It doesn't really affect users, it just adds some inconvenience to working on Specter itself. Once it looks like most people are on 1.7 or above, I'm all for switching it back to cljc. 

You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/XePZ-WSviso/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages