Sunday, September 04, 2011

SPARQL JSON

After commenting the other day that Fuseki was ignoring my request for a JSON response, I was asked to submit a bug report. It's easy to cast unsubstantiated stones in a blog, but a bug report is a different story, so I went back to confirm everything. In the process, I looked at the SPARQL 1.1 Query Results JSON Format spec (I can't find a public copy of it, so no link, sorry. UPDATE: Found it.) and was chagrined to discover that it has its own MIME type of "application/sparql-results+json". I had been using the JSON type of "application/json", and this indeed does not work, but the corrected type does. I don't think it's a good idea to ignore "application/json" so I'll report that, but strictly speaking it's correct (at least, I think so. As Andy said to me in a back channel, I don't really know what the + is supposed to mean in the subtype). So Fuseki got it right. Sorry.

When I finally get around to implementing this for Mulgara I'll try to handle both. Which reminds me... I'd better get some more SPARQL 1.1 implemented. My day job at Revelytix needs me to do some Mulgara work for a short while, so that may help get the ball rolling for me.

separate

I commented the other day that I wanted a Clojure function that takes a predicate and a seq, and returns two seqs: one that matches the predicate and the other that doesn't match. I was thinking I'd build it with a loop construct, to avoid recursing through the seq twice.

The next day, Gary (at work) suggested the separate function from Clojure Contrib. I know there's some good stuff in contrib, but unfortunately I've never taken the time to fully audit it.

The implementation of this function is obvious:
(defn separate [f s]
[(filter f s) (filter (complement f) s)])
I was disappointed to learn that this function iterates twice, but Gary pointed out that there had been a discussion on exactly this point, and the counter argument is that this is the only way to build the results lazily. That's a reasonable point, and it is usually one of the top considerations for Clojure implementations. I don't actually have cause for complaint anyway, since the seqs I'm using are always small (being built out of query structures).

This code was also a good reminder that (complement x) offers a concise replacement for the alternative code:
  #(not x %)
By extension, it's a reminder to brush up on my idiomatic Clojure. I should finish the book The Joy of Clojure (which is a thoroughly enjoyable read, by the way).

4 comments:

Anonymous said...

You might take a look at group-by. It should return a map with keys of 'true' and 'false'.

Anonymous said...

As #1 said, take a look at group-by, it's only one pass:
http://stackoverflow.com/questions/5664833/clojure-partition-by-filter

Paula said...

I like anything in core, so thanks.

For some of my uses, this works just fine. e.g. instead of a "let" binding like:
[positives negatives] (separate pred the-seq)]
I can pull it apart with:
{positives true negatives false} (group-by pred the-seq)
Which is minimal work.

One hassle is another usage that I have, where I pull matching values to the front of a seq with:
(apply concat (separate pred the-seq)))
This seems elegant. I can think of several ways to do the same thing with group-by, but I can't think of any way to do it without a "let" binding. So it works, but I'm less comfortable. OTOH, there may be a non-let way to do this (without duplicating the function call). Does anyone see it?

Shopgijii said...

Paul you need to call me i need you to sign a paper waiving all your parental rights, i need this so my sister can be the legal parent.