On 21/11/2019 18:30, ajs6f wrote:
Some off-the-cuff ideas…
I'd like to catch up to Java. :grin: Here are three examples (very much off the
top of my head, so there may some obvious reasons that we wouldn't want to do
these) to give the flavor of what I mean, assuming we are talking about a
really new API. I don't think anything is too unworldly, depending on our
timescale.
• I'd like to see the introduction of Optional on a much larger scale to replace
returning "value-or-null" in a new API. Modern JVMs in-line Optional to
null-checks, so there is no real performance issue, and Optional (for my money) is no
longer confusing and new, it's elegant and clear and concise.
(all naming of operations not serious proposals)
The decision I see here is not Optional vs null but follows from
validated vs non-validating data.
Both styles matter.
With validated data (e.g. SHACL or knowing there are upstream processes
with quality output) such checks are unnecessary and clutter the code.
There for this case an alternative - exceptions.
If the data is potentially invalid, a test at each step is good to have
a decent error message.
There are 3 "policies" -- we have 2 at the moment get/getRequired at the
moment.
getOneOf -> the thing (one of, if several) or expection = getRequired
getExactlyOne -> the thing (exactly one) or (runtime) expection
getMaybe -> the thing or Optional.
(there is list* for "all" in both old and new)
I confess that if we have 2, I'd like getExactlyOne, getMaybe, not
getOneOf. getRequired with "one of several" doesn't gel with me but I'm
not a heavy API user.
Some style/pattern to make navigating the Model API with different choices:
XYZ.start(model, resource)
.onError(()->{})
.get(property1)
.get(property2)
.exactlyOne()
.toInteger() -> a Java Integer
now whether that is a builder of an access engine exec'ed at the end or
a stream-like (inc Optional) execution is a choice on implementation
Or ...
So as not to make the move for applications all-or-nothing, we can have
the existing API, mostly as is, with improvements and this new API
growing along side. newAPI can learn from feedback and change.
• The Streams API has already come up. IMHO it's a no-brainer to introduce it
alongside iterators in selected appropriate places in the SPI and a new API.
Ideally we would even feature a few good examples of pushing computation back
up the line.
• The Flow API (reactive streams) seems interesting in the context of SPARQL
1.2 protocol-related discussions:
https://github.com/w3c/sparql-12/issues?utf8=%E2%9C%93=is%3Aissue+is%3Aopen+protocol
For example, if ideas like https://github.com/w3c/sparql-12/issues/7 or /84 go
forward, we could potentially redesign RDFConnection and its underpinnings to
use Flows. This is pretty speculative, of course, but there are other areas
that might be interesting for this. I suspect that we could use it to do some
level of decoupling of SPARQL execution (flows passing to each other), but that
is well above my ability to speculate usefully on, knowing as shamefully little
as I do about the actual paths through ARQ, and anyway, that's not API-related.
Other stuff:
I would like to look at the fairly large number of methods on classes like Resource and
Model and see if we can corral and regularize them a bit. I'm not against functionality,
of course, but we've built up those APIs via the "coral reef" model
(accumulation) and so we have little oddities like:
Statement getProperty(Resource s, Property p, String lang)
and
Property getProperty(String nameSpace, String localName)
but
Statement getRequiredProperty(Resource s, Property p)
with no
Property getRequiredProperty(String s, String p)
That's not such a horrible state of existence, but I find that the dozens and
dozens of methods on some of our core types often get a bit hard to sort
through, especially with little quirks like that.
We might also want to consider nomenclature. Model, for example, isn't really a great
term to use any more for what most APIs would call a Graph. Of course, we've used
"Graph" elsewhere. In any event, something to think about. Next.0 is the time
to make changes like that, if we're going to make them.
Do they? A lot of APIs work at what we call Graph anyway.
I think we can make Graph itself a little more friendly without losing
the import aspect that it is simple to implement.
That is not to say that Graph++ is the new application API. It is
forsubsystems, library code/algorithms and rest of Jena that might work
directly on Graph.
An important different between Model and Graph is that Resources carry
the model they relate to (and can be used in other Models when the model
is named in the method call).
One (arguable) misnaming ATM is "Node" which should be "RDF Term" (which
only came into building at SPARQL 1.0 because there wasn't a name in RDF
at the time).
But.
"Term"