null values
When is null an ok value? What does it signify.
Might also need to distinguish between "no value" and "the value is null", given the whole "open world assumption" of the RDF universe (where all we know is what's explicitly said, like "the value is null"; what's unsaid, like "no value", must be treated as explicitly unknown).
So, we have constraints from JSON-LD on the use of nulls:
https://www.w3.org/TR/json-ld11/#null
I think the place where we've gotten stuck in the past is using a null value in id property, which is called out in the ActivityPub section on object identifiers, but causes errors in JSON-LD processing.
For example,
https://json-ld.org/playground/#startTab=tab-expanded&json-ld=%7B%22%40context%22%3A%22https%3A%2F%2Fwww.w3.org%2Fns%2Factivitystreams%22%2C%22type%22%3A%22Note%22%2C%22content%22%3A%22Hello%2C%20World!%22%2C%22id%22%3Anull%7D
The other value of an explicit null property is making it clear that the property actually has no value, and not that it has been omitted from the object representation. For example, if I wanted to show that a Note has no author, I could write it this way:
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://social.example/note/1",
"type": "Note",
"attributedTo": null,
"content": "Hello, World!"
}
Whether that really means "this doesn't exist" or "this is undefined" is interesting.
There is a lot of text about null in the Serialization section:
When serialized, absent properties are represented by either (a) setting the property value to null, or (b) by omitting the property declaration altogether at the option of the publisher. These representations are semantically equivalent. If a property has an array value, the absence of any items in that array MUST be represented by omitting the property entirely or by setting the value to null. The appropriate interpretation of an omitted or explicitly null value is that no value has been assigned as opposed to the view that the given value is empty or nil.
Another option brought up by @trwnh is defining an AS2-specific "known to be nonexistent" value, like "rdf:Nil".
rdf:nil (https://www.w3.org/1999/02/22-rdf-syntax-ns#nil) is defined as the "there is no value, you have reached the end" vocabulary term.
nil : The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it.
I would say that at minimum, we could provide guidance in the primer:
- Producers SHOULD NOT produce
null. - Consumers SHOULD ignore any
nullthey encounter.
For "no more items", we can hold off on a specific recommendation, but rdf:nil is equivalent to () in Turtle syntax. The expanded JSON-LD equivalent would be like so:
{
"https://property.example/": [{"@id": "https://www.w3.org/1999/02/22-rdf-syntax-ns#nil"}]
}
Although you could maybe also use an empty array:
{
"@context": {
"set": {
"@id": "https://set-property.example/",
"@type": "@id"
},
"list": {
"@id": "https://list-property.example/",
"@type": "@id",
"@container": "@list"
}
},
"set": [],
"list": []
}
Without any @context, this compacts to the following:
{
"https://list-property.example/": {
"@list": []
},
"https://set-property.example/": []
}
Per https://github.com/json-ld/json-ld.org/issues/220#issuecomment-13740838 it seems like the empty array should be fine, although it will generally not survive a round-trip to RDF and back to JSON-LD: https://www.w3.org/TR/json-ld11-api/#data-round-tripping
The empty set is dropped in the RDF data model.
The empty list is serialized as rdf:nil: https://www.w3.org/TR/json-ld11-api/#list-to-rdf-conversion
Also, naive/buggy converters might coerce rdf:nil to an object instead of a @list:
{
"https://list-property.example/": {
"@list": []
}
}
_:b0 <https://list-property.example/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
{
"https://list-property.example/": {
"@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"
}
}
Note that this is a bug in the converter, as the RDF-to-JSONLD algorithm has you generate a @list instead. (See https://www.w3.org/TR/json-ld11-api/#serialize-rdf-as-json-ld-algorithm section 8.4.2, algorithm step 6.4 for more details.)
{
"https://list-property.example/": {
"@list": []
}
}