redplanetlabs / specter

Clojure(Script)'s missing piece
Apache License 2.0
2.51k stars 102 forks source link

Question about the idiomatic nature of the API regarding navigators and predicates #286

Closed dmg46664 closed 4 years ago

dmg46664 commented 4 years ago

Hi,

If you use the navigator ALL with a predicate then you get you might get the following

(def temp [{:a 0}{:a 1 :b 2} {:a 1 :b 3}{:a 2 :b 4}])
(s/select [s/ALL #(= (get % :a) 1)] temp) ;=> [{:a 1, :b 2} {:a 1, :b 3}]

However if you use FIRST and LAST with the same predicate Specter returns no results.

(s/select [s/FIRST #(= (get % :a) 1)] temp) ;=>[]
(s/select [s/LAST #(= (get % :a) 1)] temp) ;=> []

It's a weird one because I read the API as one might in English: Return ALL items THAT match the predicate, as this is usually how predicate filters are implemented in my experience.

However I'd guess from the results that predicates are implemented: Return ALL items, THEN filter by predicate, which in the case of FIRST & LAST will return empty.

Thoughts on what is preferable? If THEN is preferable (or here to stay) then how might one do the THAT version of the query given first and last? Is the right way to perform the ALL filter and then seek the first and last item?

P.S If any of my clojure can be improved please let me know as I'm still learning 😄

nathanmarz commented 4 years ago

It's best to think of navigation as a path, not as a relational-like statement. Each step takes you to a different place.