The no-op value type is somewhat ambiguous.
My current interpretation is:
A. In an array - the element is skipped
[[]
[#][i][2]
[i][1]
[N]
[N]
[i][2]
Note that the container count doesn't include the no-op elements.
B. In an object - the key is discarded
[{]
[#][i][2]
[i][3][foo][i][1]
[N]
[i][3][bar][i][2]
Should the following also be allowed? The merits of it are somewhat questionable, as there is no point in including the key if the value is going to cause it to be removed.
[{]
[#][i][2]
[i][3][foo][i][1]
[i][3][bar][N]
C. Top level N - Error or symbol/sentinel value
In languages where it is available: Symbol('noop') (JavaScript, Dart).
Otherwise throw a dedicated error: 'N' can only occur in arrays/objects (distinct from an unexpected byte error!), and ignore if processing a stream.
Importantly, do not skip N before/after a value is found: bjdata.decode("NTN") != bjdata.decode("T").
D. In an un-delimited sequence of BJData objects / an implicit stream of values - the entry is ignored:
Sequence of BJData values in a file or streamed over network - implicitly wrapped in [ and ] so effectively the same as A.
Another way to interpret it is at the tokenizer level, where it could appear anywhere a token is expected i.e. only excluding strongly-typed contexts where it is impossible to differentiate between the value 0x4E and N:
Surrounding a value:
[N][S][i][3][foo][N][EOF]
When waiting for a length:
When waiting for a count:
[[]
[$][U]
[N]
[#][N][i][1]
[5]
Within an array:
[[]
[#][i][2]
[i][1]
[N]
[N]
[i][2]
nlohmann/json exhibits some of these behaviors.
Don't think the latter interpretation is ever what was intended, but we would certainly benefit from being more explicit.
To summarize:
- Can
N appear in arrays? ✅ This is the main purpose
- Can
N appear in objects before keys? ✅ Also potentially useful
- Can
N appear in objects after keys? ❌ Seems redundant
- Can
N appear at top-level? ❌ It is not meaningful in that context. Throw error/special value, and handle in streams.
- Can
N appear in special contexts (between [/$/#, S/i, etc)? ❌ Seems redundant
- Does
N contribute towards container count? ❌ We might know we have to produce 10 values, but have to send keep-alives in between them because processing is slow. Could also ban N in counted containers.
- Are leading/trailing
N ignored when looking for a value? ❌
If we can agree on the expected behavior I can make a PR with the appropriate spec changes.
The
no-opvalue type is somewhat ambiguous.My current interpretation is:
A. In an array - the element is skipped
Note that the container count doesn't include the
no-opelements.B. In an object - the key is discarded
{"foo": 1, "bar": 2}Should the following also be allowed? The merits of it are somewhat questionable, as there is no point in including the key if the value is going to cause it to be removed.
{"foo": 1}C. Top level
N- Error or symbol/sentinel valueIn languages where it is available:
Symbol('noop')(JavaScript, Dart).Otherwise throw a dedicated error:
'N' can only occur in arrays/objects(distinct from anunexpected byteerror!), and ignore if processing a stream.Importantly, do not skip
Nbefore/after a value is found:bjdata.decode("NTN") != bjdata.decode("T").D. In an un-delimited sequence of BJData objects / an implicit stream of values - the entry is ignored:
Sequence of BJData values in a file or streamed over network - implicitly wrapped in
[and]so effectively the same as A.Another way to interpret it is at the tokenizer level, where it could appear anywhere a token is expected i.e. only excluding strongly-typed contexts where it is impossible to differentiate between the value
0x4EandN:Surrounding a value:
When waiting for a length:
"foo"When waiting for a count:
[5]Within an array:
nlohmann/json exhibits some of these behaviors.
Don't think the latter interpretation is ever what was intended, but we would certainly benefit from being more explicit.
To summarize:
Nappear in arrays? ✅ This is the main purposeNappear in objects before keys? ✅ Also potentially usefulNappear in objects after keys? ❌ Seems redundantNappear at top-level? ❌ It is not meaningful in that context. Throw error/special value, and handle in streams.Nappear in special contexts (between[/$/#,S/i, etc)? ❌ Seems redundantNcontribute towards container count? ❌ We might know we have to produce 10 values, but have to send keep-alives in between them because processing is slow. Could also banNin counted containers.Nignored when looking for a value? ❌If we can agree on the expected behavior I can make a PR with the appropriate spec changes.