Hey! 🙂 I am trying to match a DataScript entity with a map and it does not. The reason is clear: (map? (d/entity db 1)) => false
; entities are not maps, but are map like: (associative? (d/entity db 1)) => true
entities support a get interface which is sufficient to treat them like maps. One solution is to reify the entities into maps, but I’d rather not. Sadly entities are not seqable?
(don’t ask me why not, seems silly). So maybe there is a missing concept here m/associative
Any thoughts on the everything is a pattern webdev take? I extracted it to a more condensed macros and I think It’s pretty amazballs lol
(p/defview github-project-contributors-table
;; Justice pattern that queries for entities
#:github.project{:name _}
;; A pattern to match the entities
(#:github.project{:name !project-name
:contributors (#:github.user{:login !user-login
:name !user-name}
..!n)}
...)
;; Hiccup pattern of the view
[:table {:style {:border "1px solid"}}
[:thead
[:tr
[:th "Project"] [:th "Contributors"]]]
[:tbody
.
[:tr
[:td !project-name] [:td [:ul
.
[:li !user-name " (" !user-login ")"]
..!n]]]
...]
[:tfoot
[:tr
[:td.numeric "Total: " ~(count !project-name)] [:td.numeric "Total: " ~(count !user-login)]]]])
entities and patterns! seems way more obvious than what I’d normally do with for loops into vectors from maps or random stuff destructured here and thereThats pretty cool @timothypratley 🙂
We might want to allow associative as an option passed via meta on the form.
That would be nice, and I do like that… but FWIW I’d still have to annotate every map in the pattern which would be tedious (though no different from writing m/associative
so maybe more visually pleasing 🙂
https://github.com/timothypratley/pattern-query-view/blob/master/src/pattern_query_view/core.cljs
^^ FWIW I think this turned out pretty nice
The only things I’m not satisfied with are:
• The associative thing
• I think combining the Justice query pattern with the meander match pattern would improve it
• The listener mechanics aren’t perfect
• I’m not sure Reagent is necessary, watching the @watch
is a bit of a hack
But I think the underlying philosophy comes through: There is a global DB You can query the DB with a pattern that looks like an entity You construct views with Meander patterns.
Just showing that it works:
Oh I could easily make a macro that annotated all maps as associative, and the idea is that this would all be presented as a simplified macro;; so the metadata approach wouldn’t be tedious and it makes sense that that would be a consumer concern (not a meander concern).
FWIW I think m/associative
is better than metadata though 🙂
It seems more analogous to m/sequable
and I can still do some magic macroing to translate maps to m/assocative
forms mechanically.
Sadly I’m not sure how to implement it; it doesn’t seem as straightforward as m/seqable
which just tests and seq
… in this case something deeper needs to happen.
Worth considering the role that records play here too… presumably they are covered by associative, though you could get more specific an only match by type there too :thinking_face:
i.e. coming from the other direction, maybe my match pattern should contain ->Entity
records o_O that feels inconvenient, but is more explicit about what to match against.
My suggestion was applied to the macro form e.g. match, find, search, etc.
^{::m/associative-maps true}
or something this affect. Of course, an operator is good too. 😄