Comments (5)
Agreed. We won't be able to implement get-else
as a transform. We could either interpret the whole of [(get-else $ e :a v v-else) ?v]
as a special pattern or deviate from the Datomic API and offer something like [?e :a (or ?v false)]
. With the new binding system, we might even be able to do something like [?e :a ?v] (default ?v false)
, where the default
binding would work like a constant binding without any validation.
from clj-3df.
I like the latter two, with the second one perhaps giving us the most flexibility.
E.g., if we want to calculate a balance, but some users haven't paid / received anything yet so their respective queries currently don't evaluate:
(def balance
'[:find ?person ?balance
:where
(conj/paid ?person ?paid)
(conj/recv ?person ?recv)
[(subtract ?recv ?paid) ?balance]])
With third suggestion:
(def balance
'[:find ?person ?balance
:where
(conj/paid ?person ?paid)
(default ?paid 0)
(conj/recv ?person ?recv)
(default ?recv 0)
[(subtract ?recv ?paid) ?balance]])
Second suggestion looks weird if used on the rules / subqueries (it certainly doesn't look like we're binding 0
to ?paid
):
(def balance
'[:find ?person ?balance
:where
(conj/paid ?person (or ?paid 0))
(conj/recv ?person (or ?recv 0))
[(subtract ?recv ?paid) ?balance]])
...but using it on the subtract
clause makes sense:
(def balance
'[:find ?person ?balance
:where
(conj/paid ?person ?paid)
(conj/recv ?person ?recv)
[(subtract (or ?recv 0) (or ?paid 0)) ?balance]])
Also, we could perhaps even expand the (or ...)
syntax to binding attributes, like this:
(def balance
'[:find ?person ?balance
:where
(conj/paid (or ?person "alfredo") ?paid)
(conj/recv ?person ?recv)
[(subtract (or ?recv 0) (or ?paid 0)) ?balance]])
This would still leave the binding of ?person
for ?recv
, so it means something like "if ?person
hasn't paid anything, use ?paid
from Alfredo, but keep ?person
's receivables."
With suggestion 3 we would sacrifice that granularity and could only speak about ?person
in more general terms (at least without building a more complicated query):
(def balance
'[:find ?person ?balance
:where
(conj/paid ?person ?paid)
(default ?paid 0)
(conj/recv ?person ?recv)
(default ?recv 0)
(default ?person "alfredo")
[(subtract ?recv ?paid) ?balance]])
from clj-3df.
I prefer suggestion 3, because it is no new syntax, just a new type of binding. The "alfredo" use case seems highly confusing, because it breaks the unification intuition (?person
suddenly doesn't refer to the same entity in all cases).
And another (approximate?) way of expressing that could be:
(conj/paid ?person ?paid)
(conj/recv ?person ?recv)
(conj/paid "alfredo" ?paid-alfredo)
(default ?paid ?paid-alfredo)
Which on the front-end seems like an elegant solution ((default ?paid <constant>)
would simply de-sugar to (default ?paid ?gensym) (constant ?gensym <constant>)
). Not quite sure how the implementation as a PrefixExtender
would look like in that case...
from clj-3df.
Some more findings, mostly intended as memo.
Default can't be something associated with just a symbol. E.g. (default ?v fallback)
doesn't make sense, because as with negation, defaults need to be w.r.t to a set of entity ids.
I'll try and see how a (default ?e ?v fallback)
feels.
from clj-3df.
So comnik/declarative-dataflow@1a65b0f adds experimental support for something like this.
Indeed it is both simpler and more complex than expected.
More complex, because (for new-query-engine reasons) default bindings are not just dependent on entity ids for context, but also on the attribute that they are acting on.
Simpler, because now [?e :a ?v :else default]
actually becomes a pretty good expression of just that and the implementation fits in nicely with the new query engine (as far as I can tell).
My initial worries were unfounded, because when validating other bindings, this binding will already have a set of entity ids for context.
(Of course this means that we'll have to wait with frontend support, until the new query engine is the default.)
from clj-3df.
Related Issues (20)
- Multiple aggregations HOT 3
- FnExpr symbols and implicit clause order HOT 1
- Constant bindings HOT 1
- 3DF DB should be protocol for encoding queries
- Add support for transforms in the find-spec itself
- Add support for aggregations in clauses
- Add CloseInput support
- Support for pull query HOT 2
- Pagination HOT 1
- `min` and `max` don't work as expected HOT 1
- How to run clj-3df? HOT 7
- Update examples HOT 2
- Error handling HOT 1
- exec! is not batching commands HOT 1
- Cljs: clj_3df.compiler.trace_bindings is undefined HOT 2
- UUID serialization for entity id's HOT 1
- Roadmap? HOT 4
- retraction of an inexistent value of cardinality/one causes server panic HOT 1
- Datahike support? HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from clj-3df.