Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify usage when passing bindings into a query #14

Open
RickMoynihan opened this issue Feb 20, 2019 · 3 comments
Open

Simplify usage when passing bindings into a query #14

RickMoynihan opened this issue Feb 20, 2019 · 3 comments

Comments

@RickMoynihan
Copy link
Member

Currently we do the following pattern:

(def some:predicate ,,,)

(defn my-query [binding-one binding-two db]
  ((match/construct {:binding binding-one :some-var ?val}
                                 [[binding-one some:predicate ?val]
                                   [binding-one binding-two "some constraint"]]) 
   db))

We do it quite a lot.

I'd quite like to simplify this somewhat. Perhaps with a defconstruct, defselect type syntax... though I'd also be open to just replacing the existing query macros, as it'd be good to support an anonymous usage too... and we can probably break compatibility right now, as updating the call sites probably isn't too hard at this stage.

(def myquery (newconstruct {:grafter.rdf/uri subject
                                                 ?p ?o}
                                                [[subject ?p ?o]]))

(myquery {'subject :some/value} database)

I haven't thought of all the pros and cons to the above syntax, and I intend it mainly to be illustrative.

So I'd quite like to explore some proposals here, on how this might work.

We do something similar in another macro we have (we don't have that many honest) https://github.com/Swirrl/grafter.db/blob/1329fd597d41680b0fbcf0e497888b32ea840b8f/test/grafter/db/triplestore/query_test.clj#L21 here. This was extracted into a new repo by @scottlowe from something I wrote initially in zib, the extracted version should have a few improvements, which are yet to be backported into zib. @danmidwood and @scottlowe will I'm sure be more than happy to explain how the binding syntax there works. It's essentially an explicit variant with a few more bells and whistles on a lower level variation here https://github.com/Swirrl/grafter/blob/a061ca1524149e02ca16d1737344a770b7284278/src/grafter/rdf/sparql.clj#L120 that in turn builds on some stuff in sesame/rdf4j.

You'll note the grafter.db approach requires us to be explicit about the bindings we expect to be provided to us. So that might also be beneficial here, depending on whether we can disambiguate some:predicate from an unbound local (I'm pretty sure we probably can -- though it's probably not best to assume the:in the symbol means anything. I think only?*` should be special).

I'll be in the office tomorrow to talk about it. It should be a pretty fun task, though it's not particularly critical for anything... So the definition of done could just end up being we thought it was a bad idea, or we have a proposal and design for how it would work but no implementation, or maybe an experimental implementation.

@RickMoynihan RickMoynihan changed the title Simplify usage when passing passing bindings into a query Simplify usage when passing bindings into a query Feb 20, 2019
@RickMoynihan
Copy link
Member Author

I think if we wanted to infer the bindings we'd need to use &env and compare to those mentioned in the query body. Other options might be to use ^:metadata hints about what bindings you want to be ^:required.

@andrewmcveigh
Copy link
Contributor

andrewmcveigh commented Feb 20, 2019

How often do you find you close over the db in a function? E.G.,

(fn [arg] ((construct {:arg arg} [[arg what:evs "thing]]) db))

where db is bound further up the scope? (not by the immediate function)

@RickMoynihan
Copy link
Member Author

Yeah that is probably the more common case, hence why I think the def variant is less important than the anonymous one, looking at a branch I have locally on zib, there are maybe 9 instances of us closing over db whilst doing other things in the function too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants