Open earthlyreason opened 5 years ago
Hi @gavinpc-mindgrub thank you for the feedback!
This spec only provides javascript specific interface definitions for software applications which support RDF 1.1. For example interfaces available after parsing data from any of RDF1.1 serializations.
The use of these distinct identifiers also allows consumers of data from unknown sources to make determinations about their nature and capabilities—again, the whole point of the semantic web as I understand it.
Any data published on The Web should use one of official RDF1.1 serializations
Could you please describe a scenario where you would use RDFJS interface definitions themselves as part of published data? I could think of situations where a statement uses doap:implements
but having a canonical IRI which denotes the spec (possibly in https://w3id.org/ namespace) should suffice.
Thanks for the prompt reply, @elf-pavlik!
Yes, I think we are on the same page. I admit that the scenario I implied, which you described correctly as "using RDFJS interfaces themselves as published data," anticipates a level of JS interop that goes beyond any immediately obvious use cases. I appreciate your humoring the notion with what is, again, an incisive response about a canonical IRI with the potential for associated implementation claims.
Such usage of annotated values inside the runtime would indeed be distinct from "published data" in that, e.g. values need not always be portable. The RDFJS proposal appears to be suited for such usage, and as such would be a good exemplar of the technique, which is as you say quite simple for a provider.
For background, the question arises out of exploratory research into an aggressive use of RDF particularly inside JavaScript runtimes to support functionally self-descriptive components, where the ultimate aim is to bootstrap the kind of fully dynamic userland environment that is not feasible with today's artifacts. For example (and again, thank you for bearing with me), whereas we currently import modules via direct references to known locations, we often don't really care about the identity or location of the module so much as the qualities of the things provided. With the right vocabularies, it's possible to imagine a registry of annotated modules that allows you to query for functions as you might do for data. Such a registry could well be importing entries without a priori knowledge about what they are.
Here is a very hand-wavy example of how you might provide a function for creating part of a graph layout. The function requires a topological sort but doesn't care where it gets it. It returns a description of an X-force such as can be used to arrange nodes horizontally by rank.
dynamic_require(
[
/* Here you can query for providers by their qualities. */
["?", "doaf:implements", "https://w3id.org/example/TopologicalSort"]
],
topoSort => {
const FORCEX = "https://github.com/d3/d3-force#forceX";
const PROTO = { "@type": FORCEX };
return Object.assign(
(directedGraph, root) => {
const ranks = new Map();
for (const { node, rank } in topoSort(directedGraph, root))
ranks.set(node, rank);
return Object.create(PROTO, { x: node => ranks.get(node) });
},
{
/* Here you can annotate the provided function */
"interop:Parameters": [
{ implements: "https://xlinux.nist.gov/dads/HTML/directedGraph.html" }
],
"interop:Returns": { type: FORCEX }
}
);
}
);
Like I said, it's exploratory research. It is as much about potential applications of RDFJS as it is about the protocol itself. If you're aware of any prior efforts of this kind, I'd greatly appreciate a reference.
Thank you for clarifying @gavinpc-mindgrub
Speaking for myself, I would not see an issue with using a namespace like https://w3id.org/rdfjs#
if any implementation would find it helpful. At the same time it might bring up some issue with possibly conflated semantics, for example: http://rdf.js.org/#namednode-interface
NamedNode
as WebIDL interface"NamedNode"
as string constantGiven both would map to the same IRI https://w3id.org/rdfjs#NamedNode
, one can not any more make distinction between them.
Also equals()
requires comparing those string constants, one could try to have something like JSON-LD @vocab
for DataFactory but I think this might end up pretty tricky.
Last but not least, in the spirit of "Just do it" I don't see problem if someone would register https://w3id.org/rdfjs#
and start it as unofficial namespace. Then at some point maybe group would reach consensus to reference it in spec in some way. Again just speaking for myself here.
Please consider using a version to be able to distinct between different versions in the future.
Ref: #112
etc. ?
I guess if interface didn't change between versions it use <https://w3id.org/rdfjs/v1#NamedNode> owl:sameAs <https://w3id.org/rdfjs/v2#NamedNode> .
https://w3id.org/rdfjs/v1# https://w3id.org/rdfjs/v2# etc. ?
More like
This way we have a clear semantic versioning instead of just the major release number.
If we use such rapidly moving target namespaces, it would make no sense without heavy use of owl:sameAs
in applications described by @gavinpc-mindgrub and of course maintainer of those namespaces would need to add all those owl:sameAs
statements for all the interfaces which haven't changed between previous and next releases.
Many thanks for the thoughtful replies.
I agree with @elf-pavlik that a number that increments only for breaking changes—which should be rare—would be optimal.
On defensive API design, I found this presentation eye-opening. Rich takes the essential ideas from RDF into Clojure, and they are just as good in JavaScript. A key insight is the connection between open formats (such as RDF graphs), and backward compatibility. If consumers are "liberal in what they accept," i.e. ignoring unrecognized values, then software and protocols can safely grow by accretion. Certain kinds of changes, such as adding optional parameters and adding optional keys (to arguments or return values), need not be considered breaking changes.
I have just come across the rdf.js specification. Please forgive me if I have overlooked a previous discussion of this point.
It does not appear that this specification is itself based on an RDF vocabulary, such as could serve to disambiguate the very names defined therein.
I would expect an effort like this to start by identifying a namespace and then defining the associated terms, followed by their semantics.
Why? Because the whole point of RDF is to support the "composition with impunity" of data from unforeseen, heterogeneous sources.
For example, although it does not use RDF, the
@@transducer
protocol defined here by several library authors makes an effort to avoid name collisions with other protocols that may be implemented by a given object. So does the fantasy-land specification, another interop-oriented initiative.However, this is not just about avoiding name collisions. The use of these distinct identifiers also allows consumers of data from unknown sources to make determinations about their nature and capabilities—again, the whole point of the semantic web as I understand it. How does a conformant implementation declare itself as such? A simple
@context
on the prototype would suffice, if the bespoke namespace had been defined.Again, apologies if I have failed to find a relevant decision documented somewhere. I'll be happy to elaborate if any part of my question is unclear.
Thanks!