JSON Pointer: Slashes

716 views
Skip to first unread message

Paul C. Bryan

unread,
Jun 23, 2011, 5:33:21 PM6/23/11
to json-...@googlegroups.com
I've been discussing the use of the slash delimiter in JSON Pointer with Kris...

I wrote:
Just wondering if the initial slash in the JSON Pointer is necessary. Presumably, the absence of any fragment value (after the #) would/should be equivalent to the root...

Kris responded:
No, I don't think it is necessary, I believe that omitting the slash should indicate the root. A fragment of "#/" should indicate the empty string property value of the root. For example:
{
  "": "foo"
}
# -> root object
#/ -> "foo"

Right, I totally forgot that we need to support "empty" property names. Let's imagine a more complicated structure to push some pathological cases:


{
    "": {
        "": {
            "foo": "bar"
        }
    },
    "baz": "qux"
}

Let's say I want to address property "foo"; the JSON Pointer value "//foo" seems like the most intuitive. To address the "baz" property, would simply be to name "baz" as the JSON Pointer (no preceding slash). At this point, slash truly is just a delimiter between property tokens. Used in fragment, these pointers would look like: "#//foo" and "#baz". This makes sense to me, but wanted to run it by the rest of the group.

Thoughts?

Paul

Paul C. Bryan

unread,
Jun 23, 2011, 6:25:19 PM6/23/11
to json-...@googlegroups.com
I should also have stated that implication of all of this is that a trailing slash is allowed—in fact it's necessary to identify a leaf node with an empty name.

Paul
--
You received this message because you are subscribed to the Google Groups "JSON Schema" group.
To post to this group, send email to json-...@googlegroups.com.
To unsubscribe from this group, send email to json-schema...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/json-schema?hl=en.

Dean Landolt

unread,
Jun 23, 2011, 6:38:57 PM6/23/11
to json-...@googlegroups.com
On Thu, Jun 23, 2011 at 6:25 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
I should also have stated that implication of all of this is that a trailing slash is allowed—in fact it's necessary to identify a leaf node with an empty name.

I likey. I'd wondered the same thing but figured it was related to differentiating between . and / resolution protocols somehow. But that's what a hyperschema's for, of course -- so good catch. I hadn't even considered the "" issue -- interesting...

But what do you mean by "a trailing slash is allowed—in fact it's necessary to identify a leaf node with an empty name"? A trailing slash should only be included when you're pointing to an empty property, right?

Paul C. Bryan

unread,
Jun 23, 2011, 7:24:44 PM6/23/11
to json-...@googlegroups.com
Well, it would be required when pointing to an empty property, but not necessarily only. And all of this is an issue because we want to distinguish between root node and empty child node—which presents us with ambiguity.

We're saying that "" and "/" are different; the former is a pointer to root node, the latter a pointer to an empty named child node of root. In the latter case, on which side of this slash is the empty-named child being identified?

As far as I can tell, there are two possible options:

a) on the left-hand-side, which means that the slash is trailing, optional, but required when empty child, or
b) on the right-hand-side, which means that initial slash is either required, or optional but required when empty child.

I prefer option a). I'm open to others' preferences in this matter, or reasons why one option would be superior to the other.

Paul

Dean Landolt

unread,
Jun 24, 2011, 8:13:17 AM6/24/11
to json-...@googlegroups.com
I'm having trouble groking this. This is how it is in my head...

{
  "foo": "bar",
  "bar": {
    "baz": 1,
    "quux": [2,3]
  },
  "/": "escaped",
  "": {
    "": "a",
    "b": "c"
  }
}

#  ->  the root object
#foo  ->  "bar"
#bar  ->  { "baz": 1, "quux": [2,3] }
#bar/baz  ->  1
#bar/quux  ->  [ 2, 3 ]
#bar/quux/1  ->  3
#bar/  ->  undefined (because #bar lacks a "" key)
#bar/quux/  ->  undefined (because #bar/quux lacks a "" key)
#%2f  ->  escaped
#/  ->  { "": "a", "b": "c" }
#//  ->  a
#/b  ->  c


Does this make sense?

ISTM slashes should mean what we say they mean. The various ambiguities introduces between fs path wrangling are a nightmare -- we have no need for ambiguities -- we can just be explicit and avoid them completely.

Kris Zyp

unread,
Jun 24, 2011, 9:20:06 AM6/24/11
to json-...@googlegroups.com, Dean Landolt
I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one). This also avoids rules about when the slash is optional and when it is required. It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions). Is that worth it?
Thanks,
Kris


On 6/24/2011 6:13 AM, Dean Landolt wrote:
On Thu, Jun 23, 2011 at 7:24 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Thu, 2011-06-23 at 18:38 -0400, Dean Landolt wrote:

On Thu, Jun 23, 2011 at 6:25 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
I should also have stated that implication of all of this is that a trailing slash is allowed�in fact it's necessary to identify a leaf node with an empty name.
I likey. I'd wondered the same thing but figured it was related to differentiating between . and / resolution protocols somehow. But that's what a hyperschema's for, of course -- so good catch. I hadn't even considered the "" issue -- interesting...
But what do you mean by "a trailing slash is allowed�in fact it's necessary�to identify a leaf node with an empty name"? A trailing slash should only be included when�you're pointing to an empty property, right?

Well, it would be required when pointing to an empty property, but not necessarily only. And all of this is an issue because we want to distinguish between root node and empty child node�which presents us with ambiguity.


We're saying that "" and "/" are different; the former is a pointer to root node, the latter a pointer to an empty named child node of root. In the latter case, on which side of this slash is the empty-named child being identified?

As far as I can tell, there are two possible options:

a) on the left-hand-side, which means that the slash is trailing, optional, but required when empty child, or
b) on the right-hand-side, which means that initial slash is either required, or optional but required when empty child.

I prefer option a). I'm open to others' preferences in this matter, or reasons why one option would be superior to the other.

I'm having trouble groking this. This is how it is in my head...

{
� "foo": "bar",
� "bar": {
� � "baz": 1,
� � "quux": [2,3]
� },
� "/": "escaped",
� "": {
� � "": "a",
� � "b": "c"
� }
}

# �-> �the root object
#foo �-> �"bar"
#bar �-> �{ "baz": 1, "quux": [2,3] }
#bar/baz �-> �1
#bar/quux �-> �[ 2, 3 ]
#bar/quux/1 �-> �3
#bar/ �-> �undefined�(because #bar lacks a "" key)
#bar/quux/ �-> �undefined�(because #bar/quux lacks a "" key)
#%2f �-> �escaped
#/ �-> �{ "": "a", "b": "c" }
#// �-> �a
#/b �-> �c


Does this make sense?

ISTM slashes should mean what we say they mean. The various ambiguities introduces between fs path wrangling are a nightmare -- we have no need for ambiguities -- we can just be explicit and avoid them completely.

Dean Landolt

unread,
Jun 24, 2011, 9:37:21 AM6/24/11
to json-...@googlegroups.com
I fail at email. Forwarding to the group...


On Fri, Jun 24, 2011 at 9:20 AM, Kris Zyp <kri...@gmail.com> wrote:
I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one).

That's what I suspected. But really, isn't this what the hyperschema's for? Is it your intention that all future fragment resolution strategies be identified by their first char? If so, should that be in the spec? If not, we're back to needing the hyperschema for disambiguation, right?
 
This also avoids rules about when the slash is optional and when it is required.

Yeah, I agree that's way too complex. Did you see my alternative proposal?
 
It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions).
Is that worth it?

Perhaps not. But only for the sake of schemaless disambiguation, if anything.

Kris Zyp

unread,
Jun 24, 2011, 9:53:38 AM6/24/11
to json-...@googlegroups.com, Dean Landolt
Note that even if the spec is strict, implementations can certainly accept optional slashes. In order to allow for that and ensure compatibility, what I would suggest stating that all path segments SHOULD be preceded by a slash in a pointer fragment. However, if a fragment is being resolved, and the recipient knows the fragment follows the JSON pointer spec/slash delimited, and the first character of a non-empty string is not a slash, the first characters should be treated a path segment (as if it had been prepended with a slash). In other words, leading slashes SHOULD be used by authors, optional leading slashes SHOULD be accepted by parsers. This is compatible, clear, unambiguous, still allows for reduced slashes by implementations for more contained environments.

A little more inline...


On 6/24/2011 7:37 AM, Dean Landolt wrote:
I fail at email. Forwarding to the group...


On Fri, Jun 24, 2011 at 9:20 AM, Kris Zyp <kri...@gmail.com> wrote:
I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one).

That's what I suspected. But really, isn't this what the hyperschema's for?

Yes, but I would presume that JSON Pointers are broadly applicable enough that they are going to be used in some situations where the recipient hasn't seen the hyperschema.


Is it your intention that all future fragment resolution strategies be identified by their first char? If so, should that be in the spec?
If not, we're back to needing the hyperschema for disambiguation, right?
 
This also avoids rules about when the slash is optional and when it is required.

Yeah, I agree that's way too complex. Did you see my alternative proposal?

No, which email is that in?

 
It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions).
Is that worth it?

Perhaps not. But only for the sake of schemaless disambiguation, if anything.

Dean Landolt

unread,
Jun 24, 2011, 10:06:45 AM6/24/11
to Kris Zyp, json-...@googlegroups.com
On Fri, Jun 24, 2011 at 9:53 AM, Kris Zyp <kri...@gmail.com> wrote:
Note that even if the spec is strict, implementations can certainly accept optional slashes. In order to allow for that and ensure compatibility, what I would suggest stating that all path segments SHOULD be preceded by a slash in a pointer fragment. However, if a fragment is being resolved, and the recipient knows the fragment follows the JSON pointer spec/slash delimited, and the first character of a non-empty string is not a slash, the first characters should be treated a path segment (as if it had been prepended with a slash). In other words, leading slashes SHOULD be used by authors, optional leading slashes SHOULD be accepted by parsers. This is compatible, clear, unambiguous, still allows for reduced slashes by implementations for more contained environments.


That oughtta work. There's still a bit of a question when you have an oddball object that has an empty key vs. an object that doesn't -- you'd get different, strange behavior that could lead to some perplexing bugs.
 


A little more inline...


On 6/24/2011 7:37 AM, Dean Landolt wrote:
I fail at email. Forwarding to the group...


On Fri, Jun 24, 2011 at 9:20 AM, Kris Zyp <kri...@gmail.com> wrote:
I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one).

That's what I suspected. But really, isn't this what the hyperschema's for?

Yes, but I would presume that JSON Pointers are broadly applicable enough that they are going to be used in some situations where the recipient hasn't seen the hyperschema.

Sure, but JSON Pointer probably shouldn't be concerned with JSON Schema considerations like alternate resolution strategies -- as far as it's concerned it's the resolution strategy. So if you have a JSON Pointer value and an object you know what to do. In that context JSON Pointer need not be disambiguated -- it already has been. It's only when have hypermedia concerns where you'd need to disambiguate, right?
 


Is it your intention that all future fragment resolution strategies be identified by their first char? If so, should that be in the spec?
If not, we're back to needing the hyperschema for disambiguation, right?
 
This also avoids rules about when the slash is optional and when it is required.

Yeah, I agree that's way too complex. Did you see my alternative proposal?

No, which email is that in?

From a little earlier today in this same thread. Copying below:

I'm having trouble groking this. This is how it is in my head...
{
  "foo": "bar",
  "bar": {
    "baz": 1,
    "quux": [2,3]
  },
  "/": "escaped",
  "": {
    "": "a",
    "b": "c"
  }
}
#  ->  the root object
#foo  ->  "bar"
#bar  ->  { "baz": 1, "quux": [2,3] }
#bar/baz  ->  1
#bar/quux  ->  [ 2, 3 ]
#bar/quux/1  ->  3
#bar/  ->  undefined (because #bar lacks a "" key)
#bar/quux/  ->  undefined (because #bar/quux lacks a "" key)
#%2f  ->  escaped
#/  ->  { "": "a", "b": "c" }
#//  ->  a
#/b  ->  c

Paul C. Bryan

unread,
Jun 24, 2011, 11:34:36 AM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 08:13 -0400, Dean Landolt wrote:
I'm having trouble groking this. This is how it is in my head...


{
  "foo": "bar",
  "bar": {
    "baz": 1,
    "quux": [2,3]
  },
  "/": "escaped",
  "": {
    "": "a",
    "b": "c"
  }
}


#  ->  the root object
#foo  ->  "bar"
#bar  ->  { "baz": 1, "quux": [2,3] }
#bar/baz  ->  1
#bar/quux  ->  [ 2, 3 ]
#bar/quux/1  ->  3
#bar/  ->  undefined (because #bar lacks a "" key)
#bar/quux/  ->  undefined (because #bar/quux lacks a "" key)
#%2f  ->  escaped
#/  ->  { "": "a", "b": "c" }
#//  ->  a
#/b  ->  c

Does this make sense?

Well, mostly.

The "#/" and "#//" examples you cite above make a special case for empty names. In such cases, trailing slashes seem mandatory—if they weren't trailing, then "#/b" would need to become "#//b" (which is more confusing in my opinion—and why I tend to lean against leading slashes).

The only difference then between what you are proposing and what I am is that I am inclined to allow trailing slashes in all cases, not just when it's required for empty names.


ISTM slashes should mean what we say they mean. The various ambiguities introduces between fs path wrangling are a nightmare -- we have no need for ambiguities -- we can just be explicit and avoid them completely.

Agreed. I would like to make them explicit, both by example, and by syntax rule.

Paul

Paul C. Bryan

unread,
Jun 24, 2011, 12:03:23 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 07:20 -0600, Kris Zyp wrote:
I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one). This also avoids rules about when the slash is optional and when it is required. It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions). Is that worth it?

If we go with leading slash, then I think we need to accept this (borrowing from Dean's example):

{
    "": {
            "": "a",
            "b": "c"
    },
   "b": "d"
}

# → the root object
#/ → { "": "a", "b": "c" }
#// → "a"
#//b → "c"     (not as intuitive as I would like)
#/b → "d"

The "b" cases above are less to me than if expressed with optional trailing slashes:

# → the root object
#/ → { "": "a", "b": "c" }
#// → "a"
#/b → "c"     (more intuitive to me, but maybe not to others)
#b → "d"

Paul

Dean Landolt

unread,
Jun 24, 2011, 12:02:59 PM6/24/11
to json-...@googlegroups.com
What do you mean by mandatory? That implies there are two ways to interpret any one JSON Pointer, but what I'm suggesting has only one, unambiguous interpretation. Slashes are path separators -- there's nothing optional about them. If what looks like a trailing slash exists it's explicitly asking for a "" key. Always. Thus, my #/b example translates directly to obj[""]["b"]. In fact every single JSON Path could be expressed in one and only one bracketed notation.


 

The only difference then between what you are proposing and what I am is that I am inclined to allow trailing slashes in all cases, not just when it's required for empty names.


ISTM slashes should mean what we say they mean. The various ambiguities introduces between fs path wrangling are a nightmare -- we have no need for ambiguities -- we can just be explicit and avoid them completely.

Agreed. I would like to make them explicit, both by example, and by syntax rule.

Paul

Paul C. Bryan

unread,
Jun 24, 2011, 12:15:16 PM6/24/11
to json-...@googlegroups.com
Using this logic (slashes are delimiters) then, I should interpret "#/" to be obj[""][""], which is not correct, and "#//" to be obj[""][""][""], also not correct.

Dean Landolt

unread,
Jun 24, 2011, 12:14:34 PM6/24/11
to json-...@googlegroups.com
Okay, I finally see the ambiguity in my approach :-/

I totally overlooked it -- I should have tried to directly translate pointers to bracketed path notation earlier -- it's probably a better vehicle for examples anyway. So here's the example reframed and reified:

var root = {

    "": {
            "": "a",
            "b": "c"
    },
   "b": "d"
}

# → root → the root object
#/ → root[""] → { "": "a", "b": "c" }
#// → root[""][""] → "a"
#//b → root[""]["b"] → "c"     (not as intuitive as I would like)
#/b → root["b"] → "d"

The "b" cases above are less to me than if expressed with optional trailing slashes:

→ root[""] → the root object
#/ → root[""] → { "": "a", "b": "c" }
#// → root[""] → "a"
#/b → root[""]["b"] → "c"     (more intuitive to me, but maybe not to others)
#b → root["b"] → "d"

 

Paul

Dean Landolt

unread,
Jun 24, 2011, 12:19:03 PM6/24/11
to json-...@googlegroups.com

Whoops. Here's the right paths:

Dean Landolt

unread,
Jun 24, 2011, 12:20:06 PM6/24/11
to json-...@googlegroups.com
Yes, I realize that now. Sorry, I'm a bit slower than usual today :-/

Dean Landolt

unread,
Jun 24, 2011, 12:46:10 PM6/24/11
to json-...@googlegroups.com
As far as my preference, the latter case was obviously pretty intuitive to me too. I'm a lot more hung up on what happened with trailing slashes -- the leading slash handling just made sense to me. It's really as simple as this, right?

→ root
#a → root["a"]
#/a → root[""]["a"]
#//a → root[""][""]["a"]
#//a/ → root[""][""]["a"][""]
#/a// → root[""]["a"][""][""]

#a// 
→ root["a"]
[""][""]

#a/ → root["a"][""]
#a/b → root["a"]["b"]
#a/b/ → root["a"]["b"][""]


Paul C. Bryan

unread,
Jun 24, 2011, 1:05:30 PM6/24/11
to json-...@googlegroups.com
To answer your question with a question, please also provide examples that yield root[""] and root[""][""], in a manner that does not conflict with any of your examples above.

Paul

Dean Landolt

unread,
Jun 24, 2011, 1:10:25 PM6/24/11
to json-...@googlegroups.com
Oh, I thought that was a given (already covered in the previous examples). But here you go:

→ root
#a → root["a"]
#/a → root[""]["a"]
#//a → root[""][""]["a"]
#//a/ → root[""][""]["a"][""]
#/a// → root[""]["a"][""][""]
#a// → root["a"][""][""]
#a/ → root["a"][""]
#a/b → root["a"]["b"]
#a/b/ → root["a"]["b"][""]

#/ → root[""]
#// → root[""][""]
#/// → root[""][""][""]

Paul C. Bryan

unread,
Jun 24, 2011, 1:24:37 PM6/24/11
to json-...@googlegroups.com
These conflict from a syntax perspective with examples above. Example:

#/a// → root[""]["a"][""][""]

Paul

Dean Landolt

unread,
Jun 24, 2011, 2:54:33 PM6/24/11
to json-...@googlegroups.com
I guess this is where I keep getting hung up. If you have only slashes, drop one path part -- whether it's the head or tail (or from the middle) doesn't matter a bit. Best I can tell it leads to a clear and unambiguous translation and lets you address every possible path, including any of those with empty string keys.

Dean Landolt

unread,
Jun 24, 2011, 2:59:09 PM6/24/11
to json-...@googlegroups.com
To be more clear, here's the algorithm to build a resolution array:

function parse(value) {
    value = value.split("/");
    // drop a path component for empty paths
    var empty = !value.some(function(i) { return i });
    if (empty) value.pop();
    return value.map(function(part) {
        return decodeURIComponent(part);
    });
}


Dean Landolt

unread,
Jun 24, 2011, 3:21:18 PM6/24/11
to json-...@googlegroups.com
And just for good measure, here's a commonjs implementation with toString roundtripping, a toSource to get the resolution suffix and tests. I think I've got all the cases covered -- are there any I'm missing?


Paul C. Bryan

unread,
Jun 24, 2011, 3:24:54 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 14:54 -0400, Dean Landolt wrote:

I guess this is where I keep getting hung up. If you have only slashes, drop one path part -- whether it's the head or tail (or from the middle) doesn't matter a bit. Best I can tell it leads to a clear and unambiguous translation and lets you address every possible path, including any of those with empty string keys.

Seems like an odd rule to invoke only where there is nothing but empty property tokens. Not sure this would be any less odd than simply having a rule to ignore trailing slashes.

Paul

Dean Landolt

unread,
Jun 24, 2011, 3:37:00 PM6/24/11
to json-...@googlegroups.com
Odd though it may be it leads perfectly to our desired outcome. What does "ignore trailing slashes" even mean? Without a bunch of rules it's all kinds of ambiguous.

Paul C. Bryan

unread,
Jun 24, 2011, 3:46:49 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 15:37 -0400, Dean Landolt wrote:

What does "ignore trailing slashes" even mean? Without a bunch of rules it's all kinds of ambiguous.

Fair enough. It sounds like no matter what, there will be a bunch of rules.
So, to summarize, if I understand correctly:

1. You're presently in favour of no leading slashes, slashes as delimiter, except in the case of only slashes, at which point, one of the empty elements delimited is to be stripped.

2. I'm presently in favour of no leading slashes, slashes as a delimiter, except if the pointer ends in a slash, at which point it does not signify an additional property token.

3. I think Kris is (still?) in favour of the leading slash, which will maintain compatibility with the current JSON Schema specification.

Have I got it right? Any other takes on this issue?

Paul

Dean Landolt

unread,
Jun 24, 2011, 3:53:27 PM6/24/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 3:46 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Fri, 2011-06-24 at 15:37 -0400, Dean Landolt wrote:

What does "ignore trailing slashes" even mean? Without a bunch of rules it's all kinds of ambiguous.

Fair enough. It sounds like no matter what, there will be a bunch of rules.
So, to summarize, if I understand correctly:

1. You're presently in favour of no leading slashes, slashes as delimiter, except in the case of only slashes, at which point, one of the empty elements delimited is to be stripped.

I just need to come up with a better way to say this. There's a sane rule in there somewhere -- it's just that it doesn't really matter because it only comes up when properties
 

2. I'm presently in favour of no leading slashes, slashes as a delimiter, except if the pointer ends in a slash, at which point it does not signify an additional property token.

Are #a/b and #a/b/ equivalent? What about when #a/b is an object with an empty string key? Is it significant all the sudden? What about #a/b//////?
 

3. I think Kris is (still?) in favour of the leading slash, which will maintain compatibility with the current JSON Schema specification.

Have I got it right? Any other takes on this issue?


I believe the leading slash issue is orthogonal to the issue of empty-string key semantics. While I'm in favor of no leading slash my proposed approach could just as easily accommodate a leading slash without altering the semantics.

Dean Landolt

unread,
Jun 24, 2011, 3:55:12 PM6/24/11
to json-...@googlegroups.com
Sorry, premature send...

On Fri, Jun 24, 2011 at 3:53 PM, Dean Landolt <de...@deanlandolt.com> wrote:


On Fri, Jun 24, 2011 at 3:46 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Fri, 2011-06-24 at 15:37 -0400, Dean Landolt wrote:

What does "ignore trailing slashes" even mean? Without a bunch of rules it's all kinds of ambiguous.

Fair enough. It sounds like no matter what, there will be a bunch of rules.
So, to summarize, if I understand correctly:

1. You're presently in favour of no leading slashes, slashes as delimiter, except in the case of only slashes, at which point, one of the empty elements delimited is to be stripped.

I just need to come up with a better way to say this. There's a sane rule in there somewhere -- it's just that it doesn't really matter because it only comes up when properties

...it only comes up when paths only contain slashes.

Paul C. Bryan

unread,
Jun 24, 2011, 4:03:47 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 07:20 -0600, Kris Zyp wrote:

I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one). This also avoids rules about when the slash is optional and when it is required. It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions). Is that worth it?

Upon reflection, I'm now coming around full circle; I don't think it's worth it.

I'm persuaded that the leading-slash method on balance is the most intuitive, most straightforward to implement and is backward compatible with the existing schema spec.

The case where it's potentially less intuitive is empty property tokens—but empty tokens are not particularly intuitive! Hardly a strong reason to deviate.

Paul

Dean Landolt

unread,
Jun 24, 2011, 4:03:46 PM6/24/11
to json-...@googlegroups.com
Ignoring the leading slash issue for now, let's see if we can't agree on behavior. These seem indisputable:


→ root
#a → root["a"]
#a/b → root["a"]["b"]

Again, ignoring the leading slash, I suspect we'd all expect and agree on this behavior too:

#/a → root[""][""]
#/a/ → root[""]["a"][""]
#a/ → root["a"][""]

Thus, the logical conclusion:

#/ → root[""]
#// → root[""][""]
#/// → root[""][""][""]

What's not to like? It's clear, there's a simple rule, and it's incredibly easy to code.

Nate Morse

unread,
Jun 24, 2011, 4:06:25 PM6/24/11
to json-...@googlegroups.com
I really dislike the singular, anti-informative key value "",
and I think that it should be avoided (if not outlawed).
But couldn't we have an escaped version of #/""/""/"" to indicate
special case of empy-string keys?
And let the majority of well named keys have an easier syntax.
--Nate

Dean Landolt

unread,
Jun 24, 2011, 4:07:28 PM6/24/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 4:03 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Fri, 2011-06-24 at 07:20 -0600, Kris Zyp wrote:

I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one). This also avoids rules about when the slash is optional and when it is required. It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions). Is that worth it?

Upon reflection, I'm now coming around full circle; I don't think it's worth it.

I'm persuaded that the leading-slash method on balance is the most intuitive, most straightforward to implement and is backward compatible with the existing schema spec.

Again, I suspect the confusion is around the leading vs. trailing framing. In my framing the two issues can be completely orthogonal. What's not to like?
 
The case where it's potentially less intuitive is empty property tokens—but empty tokens are not particularly intuitive! Hardly a strong reason to deviate.


Supporting all possible paths is more than just a foolish consistency. I'd think it's a pretty important requirement.

Dean Landolt

unread,
Jun 24, 2011, 4:14:11 PM6/24/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 4:06 PM, Nate Morse <morse...@gmail.com> wrote:
I really dislike the singular, anti-informative key value "",
and I think that it should be avoided (if not outlawed).
But couldn't we have an escaped version of #/""/""/"" to indicate
special case of empy-string keys?
And let the majority of well named keys have an easier syntax.

Does it really need to be this complicated? What's wrong with this code -- it works for all cases, is completely correct, and is really easy to understand:


(Also, introducing another means of escapement will introduce more complications than you're likely anticipating!)

Paul C. Bryan

unread,
Jun 24, 2011, 4:35:43 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 16:07 -0400, Dean Landolt wrote:

On Fri, Jun 24, 2011 at 4:03 PM, Paul C. Bryan <paul....@forgerock.com> wrote:

Upon reflection, I'm now coming around full circle; I don't think it's worth it.

I'm persuaded that the leading-slash method on balance is the most intuitive, most straightforward to implement and is backward compatible with the existing schema spec.

Again, I suspect the confusion is around the leading vs. trailing framing. In my framing the two issues can be completely orthogonal. What's not to like?

How does your framing of this look with leading slash then? I suspect if we could all find ourselves in violent agreement. :-)

Paul

Gary Court

unread,
Jun 24, 2011, 4:38:00 PM6/24/11
to json-...@googlegroups.com
I believe that pointers should always start with a slash (/) for a few reasons:

1. Identifies that the pointer is using slash-delimited paths.
2. Indicates that we resolving from the root (#) of the instance.
3. Allows referencing empty property names
4. Keeps path sections consistent (always start with a slash)
5. Allows the ability for canonical references to internal json instances

The last two probably need clarification:

4. By removing the slash at the beginning of the path, we are creating
a special case that is different then how all other property names are
referenced. If paths start with a slash, then all properties are
easily recognizable as "/propertyName".

5. By enforcing paths to start with a slash, we can also leave open
the ability to create references to internal JSON structures. For
example, take the following JSON:

{
"a" : {
"b" : {
"c" : {
"id" : "#foo"
}
}
}
}

Assuming there is a schema applied to this JSON structure that states
the "id" property is a "self" link, we could then reference that
instance using the URL "#foo".

-Gary

Nate Morse

unread,
Jun 24, 2011, 4:41:08 PM6/24/11
to json-...@googlegroups.com
Your gist makes it clear enough. And one way to describe it (someday a
manual/tutorial will have to be written...) is:

The slash "/" character is used as either a separator or as a
substitute for an (ill advised) empty token... if a slash is at the
beginning, end or follows a slash then it refers to an empty token,
otherwise its a separator.

--- but this overloading strikes me as strange, I would rather see
%00 in the path for an empty string.

Dean Landolt

unread,
Jun 24, 2011, 4:45:48 PM6/24/11
to json-...@googlegroups.com
Prepend a slash to all my examples and there you have it :)

Paul C. Bryan

unread,
Jun 24, 2011, 4:50:20 PM6/24/11
to json-...@googlegroups.com
Presumably, all of the samples, except the ones with only slashes, because in such a case the extra slash would be superfluous.

Paul

Nate Morse

unread,
Jun 24, 2011, 4:51:47 PM6/24/11
to json-...@googlegroups.com
Right never mind about the escaping of an empty string.
Given a leading slash...

#/ → root
#// → root[""]
#/// → root[""][""]
#//b → root[""]["b"]
Question about trialing slashes (allowed?)
#//b/ → root[""]["b"]

Dean Landolt

unread,
Jun 24, 2011, 4:52:54 PM6/24/11
to json-...@googlegroups.com
No, all of them. # becomes #/ so #/ has to become #//.

Paul C. Bryan

unread,
Jun 24, 2011, 4:56:23 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 16:51 -0400, Nate Morse wrote:
Right never mind about the escaping of an empty string.
Given a leading slash...
#/ → root
#// → root[""]
#/// → root[""][""]
#//b → root[""]["b"]
Question about trialing slashes (allowed?)
#//b/ → root[""]["b"]

If leading slash, no trailing slashes, and no escaping of empty strings, then simply:

# → root

#/ → root[""]
#// → root[""][""]
#/// → root[""][""][""]
#//b → root[""]["b"]
#//b/ → root[""]["b"][""]
#/a → root["a"]

Paul

Dean Landolt

unread,
Jun 24, 2011, 4:55:50 PM6/24/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 4:38 PM, Gary Court <gary....@gmail.com> wrote:
I believe that pointers should always start with a slash (/) for a few reasons:

1. Identifies that the pointer is using slash-delimited paths.

Is there value in this? A JSON Pointer can only have slash delimited paths, right? Variable resolution protocols are for other specs. -- not the Pointer spec. Am I missing something?
 
2. Indicates that we resolving from the root (#) of the instance.

Is there any other way? Also note that you "root (#)", not root "(#/)" :)
 
3. Allows referencing empty property names

Again, this is orthogonal. In fact, I believe I've proven that without the leading slash you can reference empty property names with perfect fidelity.
 
4. Keeps path sections consistent (always start with a slash)

That depends on how you look at path sections. I'd argue path parts don't actually contain a slash, just as paths themselves don't actually contain a #.
 
5. Allows the ability for canonical references to internal json instances

The last two probably need clarification:

4. By removing the slash at the beginning of the path, we are creating
a special case that is different then how all other property names are
referenced. If paths start with a slash, then all properties are
easily recognizable as "/propertyName".

5. By enforcing paths to start with a slash, we can also leave open
the ability to create references to internal JSON structures. For
example, take the following JSON:

{
 "a" : {
   "b" : {
     "c" : {
       "id" : "#foo"
     }
   }
 }
}

Assuming there is a schema applied to this JSON structure that states
the "id" property is a "self" link, we could then reference that
instance using the URL "#foo".

I'll have to chew on this a bit, but I don't think it matters one way or the other whether Pointers have leading slashes for it. A pointer doesn't actually start with a "#" value either, right?

Dean Landolt

unread,
Jun 24, 2011, 4:57:39 PM6/24/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 4:56 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Fri, 2011-06-24 at 16:51 -0400, Nate Morse wrote:
Right never mind about the escaping of an empty string.
Given a leading slash...
#/ → root
#// → root[""]
#/// → root[""][""]
#//b → root[""]["b"]
Question about trialing slashes (allowed?)
#//b/ → root[""]["b"]
If leading slash, no trailing slashes, and no escaping of empty strings, then simply:

# → root

Oh right. I didn't consider that root still wouldn't have a /.

#/ → root[""]
#// → root[""][""]
#/// → root[""][""][""]
#//b → root[""]["b"]
#//b/ → root[""]["b"][""]
#/a → root["a"]

Paul

--

Dean Landolt

unread,
Jun 24, 2011, 5:00:13 PM6/24/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 4:57 PM, Dean Landolt <de...@deanlandolt.com> wrote:


On Fri, Jun 24, 2011 at 4:56 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Fri, 2011-06-24 at 16:51 -0400, Nate Morse wrote:
Right never mind about the escaping of an empty string.
Given a leading slash...
#/ → root
#// → root[""]
#/// → root[""][""]
#//b → root[""]["b"]
Question about trialing slashes (allowed?)
#//b/ → root[""]["b"]
If leading slash, no trailing slashes, and no escaping of empty strings, then simply:

# → root

Oh right. I didn't consider that root still wouldn't have a /.

#/ → root[""]
#// → root[""][""]
#/// → root[""][""][""]
#//b → root[""]["b"]
#//b/ → root[""]["b"][""]
#/a → root["a"]


Eh, something still doesn't sit right about this. It's terribly inconsistent, for starters, but I suspect it's got a hole in it too.

Paul C. Bryan

unread,
Jun 24, 2011, 5:01:43 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 16:55 -0400, Dean Landolt wrote:


On Fri, Jun 24, 2011 at 4:38 PM, Gary Court <gary....@gmail.com> wrote:
I believe that pointers should always start with a slash (/) for a few reasons:

1. Identifies that the pointer is using slash-delimited paths.


Is there value in this? A JSON Pointer can only have slash delimited paths, right? Variable resolution protocols are for other specs. -- not the Pointer spec. Am I missing something?

Yes, a JSON Pointer would only have slash-delimited paths. Perhaps a better way to put it would be to say that it better identifies that a fragment is using slash-delimited paths.

2. Indicates that we resolving from the root (#) of the instance.


Is there any other way? Also note that you "root (#)", not root "(#/)" :)

# → root
#/ → root[""]

 
3. Allows referencing empty property names


Again, this is orthogonal. In fact, I believe I've proven that without the leading slash you can reference empty property names with perfect fidelity.

Except the requirement of the funky rule that you must ignore the empty property if there is only slashes.


 
4. Keeps path sections consistent (always start with a slash)


That depends on how you look at path sections. I'd argue path parts don't actually contain a slash, just as paths themselves don't actually contain a #.
 
5. Allows the ability for canonical references to internal json instances

The last two probably need clarification:

4. By removing the slash at the beginning of the path, we are creating
a special case that is different then how all other property names are
referenced. If paths start with a slash, then all properties are
easily recognizable as "/propertyName".

5. By enforcing paths to start with a slash, we can also leave open
the ability to create references to internal JSON structures. For
example, take the following JSON:

{
 "a" : {
   "b" : {
     "c" : {
       "id" : "#foo"
     }
   }
 }
}

Assuming there is a schema applied to this JSON structure that states
the "id" property is a "self" link, we could then reference that
instance using the URL "#foo".


I'll have to chew on this a bit, but I don't think it matters one way or the other whether Pointers have leading slashes for it. A pointer doesn't actually start with a "#" value either, right?

Correct, a pointer doesn't contain the #. It's there to indicate that it's a fragment portion of a URI. A fragment identifier would be followed immediately by  a JSON Pointer.

Paul C. Bryan

unread,
Jun 24, 2011, 5:03:50 PM6/24/11
to json-...@googlegroups.com
On Fri, 2011-06-24 at 17:00 -0400, Dean Landolt wrote:
Eh, something still doesn't sit right about this. It's terribly inconsistent, for starters, but I suspect it's got a hole in it too.

I wouldn't say inconsistent, but rather, somewhat non-intuitive where empty property tokens are concerned. I'm blaming this on the use of empty property tokens rather than the syntax. ;-)

Where there are no empty property tokens, it actually works out to be very intuitive IMO.

Paul


Nate Morse

unread,
Jun 24, 2011, 5:20:41 PM6/24/11
to json-...@googlegroups.com
I think that it is inconsistent, only when there is a trailing empty token.

try this:
Yes ALWAYS a leading slash, optional trailing slash (except for a
final empty token), ONLY read the slash as a separator, An
empty token is always surrounded by slashes //


#/ → root
#// → root[""]
#/// → root[""][""]
#//b → root[""]["b"]
#//b/ → root[""]["b"]
#/a → root["a"]

Dean Landolt

unread,
Jun 25, 2011, 5:04:45 PM6/25/11
to json-...@googlegroups.com
On Fri, Jun 24, 2011 at 5:01 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
On Fri, 2011-06-24 at 16:55 -0400, Dean Landolt wrote:


On Fri, Jun 24, 2011 at 4:38 PM, Gary Court <gary....@gmail.com> wrote:
I believe that pointers should always start with a slash (/) for a few reasons:

1. Identifies that the pointer is using slash-delimited paths.


Is there value in this? A JSON Pointer can only have slash delimited paths, right? Variable resolution protocols are for other specs. -- not the Pointer spec. Am I missing something?

Yes, a JSON Pointer would only have slash-delimited paths. Perhaps a better way to put it would be to say that it better identifies that a fragment is using slash-delimited paths.

But does this really do user agents any favors? It's far too loose to be of any practical use. Fragments in text/html serializations, left to their own devices for a few decades, now may have various conflicting interpretations -- all with the potential to clash with their de facto semantics enforced by user agents. This is not a model, it's a mess.

2. Indicates that we resolving from the root (#) of the instance.


Is there any other way? Also note that you "root (#)", not root "(#/)" :)

# → root
#/ → root[""]

Yes, yes, we agree. Gary was referring to how the slash indicated the root -- I was suggesting it's strange to think that they could ever be resolved from anywhere but the root (but I could be missing the use case). And using the path separator to mean root just opens the door for a broken, untranslatable Pointer path. What does the Pointer "" mean? If for nothing else I think we should drop "/" as a pointer prefix for the same reasons we dropped "?" as a possible query prefix in RQL -- it lead to too much special case handling in code and possible ambiguities.

Why in the world should #/ mean something different than #? We shouldn't have to answer that question :)
 

 
3. Allows referencing empty property names


Again, this is orthogonal. In fact, I believe I've proven that without the leading slash you can reference empty property names with perfect fidelity.But when you have a dangling path with no value to suck up car

Except the requirement of the funky rule that you must ignore the empty property if there is only slashes.

That's not a funky rule people have to know -- it's just a simple shortcut implementers can use. The rule is that any dangling slash (whether a prefix or a suffix) represents an empty string key. And it should be obvious when you see one -- they should immediately smell funny (another great reason we should drop leading slashes!!!). Just as when you see #a/b you expect root["a"]["b"], when you see #a/b/ you'd similarly expect root["a"]["b"][""] -- there's nothing confusing about it. Likewise, when you see #/a/b you'd expect root[""]["a"]["b"] because that leading, dangling slash, and #a//b -- that smells funny too, but is obviously root["a"][""]["b"]. But when all you have is a dangling path part it's unbalanced -- #/ is clearly saying there's an empty-string key, but is it before or after the slash? Well, it doesn't matter. It so intuitively means root[""]. Thus #// means root[""][""]. And every single possible pointer is present and accounted for, and has a logical, unsurprising translation. Even if you don't care about empty keys (and I certainly don't) it's a wonderful thing that this proposal has absolutely perfect fidelity in both directions (does anyone know what this mathematical property is called?).

 


 
4. Keeps path sections consistent (always start with a slash)


That depends on how you look at path sections. I'd argue path parts don't actually contain a slash, just as paths themselves don't actually contain a #.
 
5. Allows the ability for canonical references to internal json instances

The last two probably need clarification:

4. By removing the slash at the beginning of the path, we are creating
a special case that is different then how all other property names are
referenced. If paths start with a slash, then all properties are
easily recognizable as "/propertyName".

5. By enforcing paths to start with a slash, we can also leave open
the ability to create references to internal JSON structures. For
example, take the following JSON:

{
 "a" : {
   "b" : {
     "c" : {
       "id" : "#foo"
     }
   }
 }
}

Assuming there is a schema applied to this JSON structure that states
the "id" property is a "self" link, we could then reference that
instance using the URL "#foo".


I'll have to chew on this a bit, but I don't think it matters one way or the other whether Pointers have leading slashes for it. A pointer doesn't actually start with a "#" value either, right?

Correct, a pointer doesn't contain the #. It's there to indicate that it's a fragment portion of a URI. A fragment identifier would be followed immediately by  a JSON Pointer.

For some media type(s). What a wonderful opportunity this is to right some wrongs -- for JSON media types there's absolutely no need for alternative resolution protocols. Programming languages get by with a single, fully stratified graph resolution mechanism (bracketed strings usually). Everything else is sugar. Thanks to preexisting url escapement rules the protocol describing above is already fully stratified. If you want fragment to signal something else to the user agent, this is what headers are for. Either use another content type, specify a parameter, do something. The fragment string itself is not the place -- trying to shoehorn a sigil into it is messy at best.

Dean Landolt

unread,
Jun 25, 2011, 5:23:41 PM6/25/11
to json-...@googlegroups.com
youyouyouyouyou

I should add: I know this whole paragraph is completely off topic for the purposes of JSON Pointer, but we all seem to be assuming that JSON Pointer (or object graph traversal in general) as the de facto interpretation of fragments in JSON media types. I do think it would be spectacular if we could formalize this but it may not be practical. Still, this is irrelevant -- the point I'm trying to make is that trying to use force a sigil into JSON Pointer would be a mistake regardless.

Paul C. Bryan

unread,
Jun 26, 2011, 12:07:50 PM6/26/11
to json-...@googlegroups.com
On Sat, 2011-06-25 at 17:04 -0400, Dean Landolt wrote:

On Fri, Jun 24, 2011 at 5:01 PM, Paul C. Bryan <paul....@forgerock.com> wrote:

[snip]


Yes, a JSON Pointer would only have slash-delimited paths. Perhaps a better way to put it would be to say that it better identifies that a fragment is using slash-delimited paths.

But does this really do user agents any favors? It's far too loose to be of any practical use. Fragments in text/html serializations, left to their own devices for a few decades, now may have various conflicting interpretations -- all with the potential to clash with their de facto semantics enforced by user agents. This is not a model, it's a mess.

I wouldn't say it's a compelling reason, and lacking a better way to handle fragment identifiers, better than nothing.

[snip]


Is there any other way? Also note that you "root (#)", not root "(#/)" :)

# → root
#/ → root[""]

Yes, yes, we agree. Gary was referring to how the slash indicated the root -- I was suggesting it's strange to think that they could ever be resolved from anywhere but the root (but I could be missing the use case). And using the path separator to mean root just opens the door for a broken, untranslatable Pointer path. What does the Pointer "" mean? If for nothing else I think we should drop "/" as a pointer prefix for the same reasons we dropped "?" as a possible query prefix in RQL -- it lead to too much special case handling in code and possible ambiguities.

I think a pointer of "" means root, while a pointer of "/" would indicate an empty child property of root object. There's no prefix per se, but as a delimiter, in most cases it will appear as a prefix. "/a" refers to the child property "a" of the root object.


Why in the world should #/ mean something different than #? We shouldn't have to answer that question :)

Because JSON specification elected to allow string property names of any value. If we didn't have empty names, they could have conceivably been able to be the same.

[snip]


Except the requirement of the funky rule that you must ignore the empty property if there is only slashes.


That's not a funky rule people have to know -- it's just a simple shortcut implementers can use. The rule is that any dangling slash (whether a prefix or a suffix) represents an empty string key. And it should be obvious when you see one -- they should immediately smell funny (another great reason we should drop leading slashes!!!). Just as when you see #a/b you expect root["a"]["b"], when you see #a/b/ you'd similarly expect root["a"]["b"][""] -- there's nothing confusing about it. Likewise, when you see #/a/b you'd expect root[""]["a"]["b"] because that leading, dangling slash, and #a//b -- that smells funny too, but is obviously root["a"][""]["b"]. But when all you have is a dangling path part it's unbalanced -- #/ is clearly saying there's an empty-string key, but is it before or after the slash? Well, it doesn't matter. It so intuitively means root[""]. Thus #// means root[""][""]. And every single possible pointer is present and accounted for, and has a logical, unsurprising translation. Even if you don't care about empty keys (and I certainly don't) it's a wonderful thing that this proposal has absolutely perfect fidelity in both directions (does anyone know what this mathematical property is called?).

Agreed, as long as there is a defined semantic, how implementations optimize are up to the implementations.

[snip]

Paul

Paul C. Bryan

unread,
Jun 29, 2011, 1:05:02 PM6/29/11
to json-...@googlegroups.com
Unless there are strong objections, I'd like to incorporate this proposal into the next revision of the draft. I believe this gives us the best balance, and only creates a requirement for leading slashes in the pathological case of empty fragment.

Paul

On Fri, 2011-06-24 at 07:53 -0600, Kris Zyp wrote:
Note that even if the spec is strict, implementations can certainly accept optional slashes. In order to allow for that and ensure compatibility, what I would suggest stating that all path segments SHOULD be preceded by a slash in a pointer fragment. However, if a fragment is being resolved, and the recipient knows the fragment follows the JSON pointer spec/slash delimited, and the first character of a non-empty string is not a slash, the first characters should be treated a path segment (as if it had been prepended with a slash). In other words, leading slashes SHOULD be used by authors, optional leading slashes SHOULD be accepted by parsers. This is compatible, clear, unambiguous, still allows for reduced slashes by implementations for more contained environments.

A little more inline...

On 6/24/2011 7:37 AM, Dean Landolt wrote:
I fail at email. Forwarding to the group...



On Fri, Jun 24, 2011 at 9:20 AM, Kris Zyp <kri...@gmail.com> wrote:
I believe part of the rationale for the required-leading-slash scheme (what is currently in JSON Schema) was that it could be clearly identified and disambiguated from other fragment resolution strategies (such as the prior dot-delimited one or any custom/future id-based one).


That's what I suspected. But really, isn't this what the hyperschema's for?

Yes, but I would presume that JSON Pointers are broadly applicable enough that they are going to be used in some situations where the recipient hasn't seen the hyperschema.

Is it your intention that all future fragment resolution strategies be identified by their first char? If so, should that be in the spec?
If not, we're back to needing the hyperschema for disambiguation, right?
 
This also avoids rules about when the slash is optional and when it is required.


Yeah, I agree that's way too complex. Did you see my alternative proposal?

No, which email is that in?

 
It is nice to shed a slash, but the the optional-trailing-slash scheme (proposed here) adds complexity, is incompatible with prior versions of slash delimited paths, and can't be identified as slash delimited (vs other fragment resolutions).
Is that worth it?



Perhaps not. But only for the sake of schemaless disambiguation, if anything.

Dean Landolt

unread,
Jun 29, 2011, 1:33:10 PM6/29/11
to json-...@googlegroups.com
On Wed, Jun 29, 2011 at 1:05 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
Unless there are strong objections, I'd like to incorporate this proposal into the next revision of the draft. I believe this gives us the best balance, and only creates a requirement for leading slashes in the pathological case of empty fragment.

This still has ambiguity (for the reasons I've listed exhaustively) but as it's really addressing the case of what should be in a fragment, and not what is in a pointer itself, I don't care all that much. I still don't understand why we should bother with optional leading slashes -- the only reason left is possible backcompat with JSON Schema -- in this light shouldn't the optional leading slash stuff go in the JSON Schema spec -- what place odes it have in this one? If the JSON Schema spec were to say JSON Pointer, SHOULD be prefixed with a slash -- it would satisfy all issues that have been raised, correct?

Paul C. Bryan

unread,
Jun 29, 2011, 2:27:05 PM6/29/11
to json-...@googlegroups.com
On Wed, 2011-06-29 at 13:33 -0400, Dean Landolt wrote:

This still has ambiguity (for the reasons I've listed exhaustively) but as it's really addressing the case of what should be in a fragment, and not what is in a pointer itself, I don't care all that much. I still don't understand why we should bother with optional leading slashes -- the only reason left is possible backcompat with JSON Schema -- in this light shouldn't the optional leading slash stuff go in the JSON Schema spec -- what place odes it have in this one? If the JSON Schema spec were to say JSON Pointer, SHOULD be prefixed with a slash -- it would satisfy all issues that have been raised, correct?

I don't think I'm following your point. As far as I know, the following should be true:

    fragment = "#" + JSON pointer

Why should there be any text in JSON Schema re: pointers beyond this?

Paul

Dean Landolt

unread,
Jun 29, 2011, 2:31:08 PM6/29/11
to json-...@googlegroups.com
JSON Schema's the thing that cares about "path resolution protocols". JSON Pointer is one path resolution protocol. I'm claiming that JSON Schema's default path resolution protocol could be specified as JSON Pointer with an optional leading slash and everyone wins. But this is JSON Schema's business -- no need to project it onto an otherwise perfectly symmetrical and clean JSON Pointer :)

Paul C. Bryan

unread,
Jun 29, 2011, 3:50:24 PM6/29/11
to json-...@googlegroups.com
On Wed, 2011-06-29 at 14:31 -0400, Dean Landolt wrote:

JSON Schema's the thing that cares about "path resolution protocols". JSON Pointer is one path resolution protocol. I'm claiming that JSON Schema's default path resolution protocol could be specified as JSON Pointer with an optional leading slash and everyone wins. But this is JSON Schema's business -- no need to project it onto an otherwise perfectly symmetrical and clean JSON Pointer :)

The objective of JSON Pointer is to support both string and fragment representations. It makes no sense to me to create exceptions in JSON Schema regarding how to interpret a fragment.

Paul

Dean Landolt

unread,
Jun 29, 2011, 3:56:36 PM6/29/11
to json-...@googlegroups.com
But JSON Schema already has exceptions for backcompat. As a counterpoint, it makes no sense to me to create exceptions in JSON Pointer regarding how JSON Schema should interpret a fragment. But I see JSON Pointer as nothing more than a direct mapping between a string and simple, direct graph traversal. It'd be great if could represent all fragments but I suspect that ship has sailed, at least for now -- there are multiple resolution protocols defined in JSON Schema which will probably remain for the foreseeable future.

Or am I wrong about that? Is removing the dot-resolution protocol on the table?

Paul C. Bryan

unread,
Jun 29, 2011, 4:08:25 PM6/29/11
to json-...@googlegroups.com
On Wed, 2011-06-29 at 15:56 -0400, Dean Landolt wrote:

Is removing the dot-resolution protocol on the table?

Yes, to my knowledge it's currently considered deprecated, and will likely not appear in the next draft of JSON Schema.

Paul

Dean Landolt

unread,
Jun 29, 2011, 4:15:37 PM6/29/11
to json-...@googlegroups.com
Oh, good. So what's the issue about backcompat then? Couldn't we deprecate but allow the current leading-slash semantics based on Kris' rule? It's unlikely to create real problems. But again, why should JSON Pointer suffer this ambiguity?

Either way, I'm not too concerned. But I still can't quite figure out what the problem is with my proposed approach -- I've proven it's completely symmetrical and unambiguous and IIUC we both agree it's the most intuitive. Am I missing something?

Nate Morse

unread,
Jun 29, 2011, 5:21:46 PM6/29/11
to json-...@googlegroups.com
Just to chime-in with an opinion, For me an initial slash is intuitive
in conveying root (similar to file-systems etc.).
The lack of an initial slash reads as some sort of relative path, but
if I am alone in this, I accept the majority opinion.
--Nate

Dean Landolt

unread,
Jun 29, 2011, 6:36:49 PM6/29/11
to json-...@googlegroups.com
On Wed, Jun 29, 2011 at 5:21 PM, Nate Morse <morse...@gmail.com> wrote:
Just to chime-in with an opinion, For me an initial slash is intuitive
in conveying root (similar to file-systems etc.).
 The lack of an initial slash reads as some sort of relative path, but
if I am alone in this, I accept the majority opinion.

I'm inclined to agree -- but the problem is that an initial slash also implies that a path can start somewhere other than root, which IIUC would never be possible and is not at all the intent of JSON Pointer.

Kris Zyp

unread,
Jun 30, 2011, 9:36:14 AM6/30/11
to json-...@googlegroups.com, Dean Landolt
On 6/29/2011 11:33 AM, Dean Landolt wrote:


On Wed, Jun 29, 2011 at 1:05 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
Unless there are strong objections, I'd like to incorporate this proposal into the next revision of the draft. I believe this gives us the best balance, and only creates a requirement for leading slashes in the pathological case of empty fragment.

This still has ambiguity (for the reasons I've listed exhaustively) but as it's really addressing the case of what should be in a fragment, and not what is in a pointer itself, I don't care all that much.
The ambiguity you listed was for the case of leading slashes being optional for empty strings, right? The text simply needs to be updated to say "all path segments SHOULD be preceded by a slash in a pointer fragment, and if the first path segment is an empty string, it MUST be preceded by a slash. However, if...".

I believe that should satisfy the desired use cases, avoid ambiguity, and maintain back-compat, does that sound good?
Thanks,
Kris


I still don't understand why we should bother with optional leading slashes -- the only reason left is possible backcompat with JSON Schema -- in this light shouldn't the optional leading slash stuff go in the JSON Schema spec -- what place odes it have in this one? If the JSON Schema spec were to say JSON Pointer, SHOULD be prefixed with a slash -- it would satisfy all issues that have been raised, correct?

Dean Landolt

unread,
Jun 30, 2011, 10:31:26 AM6/30/11
to Kris Zyp, json-...@googlegroups.com
On Thu, Jun 30, 2011 at 9:36 AM, Kris Zyp <kri...@gmail.com> wrote:
On 6/29/2011 11:33 AM, Dean Landolt wrote:


On Wed, Jun 29, 2011 at 1:05 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
Unless there are strong objections, I'd like to incorporate this proposal into the next revision of the draft. I believe this gives us the best balance, and only creates a requirement for leading slashes in the pathological case of empty fragment.

This still has ambiguity (for the reasons I've listed exhaustively) but as it's really addressing the case of what should be in a fragment, and not what is in a pointer itself, I don't care all that much.
The ambiguity you listed was for the case of leading slashes being optional for empty strings, right? The text simply needs to be updated to say "all path segments SHOULD be preceded by a slash in a pointer fragment, and if the first path segment is an empty string, it MUST be preceded by a slash. However, if...".

I believe that should satisfy the desired use cases, avoid ambiguity, and maintain back-compat, does that sound good?

IIUC you're suggesting this resolution mapping:

# -> root
#/ -> root
#foo -> root["foo"]
#/foo -> root["foo"]
#//foo -> root[""]["foo"]

In practice the algorithm would go something like this: strip off the first slash, if your path still beings with a slash it's referencing an empty string key. I agree this is unambiguous, but still a little goofier than it need be. But if I'm alone in being bothered by the fact that # is identical to #/  I'll let it go. I'll make one last appeal to see if I can't make more sense:

Kris will no doubt remember a time when a related syntax -- RQL -- was optionally prefixed by a  question mark. The question mark was harmless but experience taught us that it was quite an inconvenience -- always, err, sometimes stripping it off, among other issues. Luckily RQL was still a relatively new spec and didn't have many users so maintaining complete backward compatibility wasn't an absolutely necessity, and it was wonderful to rid ourselves of that unnecessary prefix noise.

I content that the same applies here. Think for a second if we specified that all JSON Pointers SHOULD start with a # -- after all, it's useful when talking about fragments to introduce the leading # prefix. We don't. Why not? It's completely unnecessary. We inherently know the "#" means this, or the root object. JSON Schema has had empty fragment URIs for as long as I've been around it. It just makes sense. JSON Pointers are always rooted at the object. Thus, the leading "/" is nothing more than noise, just the same as if we were to allow # into the Pointer spec. If we rid ourselves of the optional leading slash all encoding-normalized pointer strings have a unique translation to a parsed path.

Another reason the leading "/" bothers me is because if you're thinking of it as representing "root" it's a misnomer. As I mentioned above, the # is better though of as resource root. A pointer can be "rooted" to any object, even an object you've already started to traverse. For instance, given the fragment #/foo and the object { "foo": { "foo": "bar" } } if "/" represented root it would imply that resolving this path would be idempotent, right? Assuming a lib where we could wrap the above object and get hang a resolve function off of it, wouldn't you think that obj.resolve("/foo").resolve("/foo")... ad nasuem... always result in { "foo": "bar" }? But this doesn't make any sense -- I'd really want "bar" from applying the Pointer resolution twice. JSON Pointers keep no context, so they can't have any lasting notion of root. Which means a leading "/" is confusing.

In fact, I've actually already started using a version of the little example lib I whipped up (https://gist.github.com/1045467) as something like a soak operator. I suspect I'll soon write a python version as a nice universal way to avoid the KeyError madness. JSON Pointer is good at one thing -- walking a DAG -- and it's great to have a universal language for this. If these arguments aren't compelling I'll give up -- I just wanted to at least take another stab at explaining why I'm so reticent :)

Kris Zyp

unread,
Jun 30, 2011, 11:02:59 AM6/30/11
to Dean Landolt, json-...@googlegroups.com
On 6/30/2011 8:31 AM, Dean Landolt wrote:


On Thu, Jun 30, 2011 at 9:36 AM, Kris Zyp <kri...@gmail.com> wrote:
On 6/29/2011 11:33 AM, Dean Landolt wrote:


On Wed, Jun 29, 2011 at 1:05 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
Unless there are strong objections, I'd like to incorporate this proposal into the next revision of the draft. I believe this gives us the best balance, and only creates a requirement for leading slashes in the pathological case of empty fragment.

This still has ambiguity (for the reasons I've listed exhaustively) but as it's really addressing the case of what should be in a fragment, and not what is in a pointer itself, I don't care all that much.
The ambiguity you listed was for the case of leading slashes being optional for empty strings, right? The text simply needs to be updated to say "all path segments SHOULD be preceded by a slash in a pointer fragment, and if the first path segment is an empty string, it MUST be preceded by a slash. However, if...".

I believe that should satisfy the desired use cases, avoid ambiguity, and maintain back-compat, does that sound good?

IIUC you're suggesting this resolution mapping:

# -> root
#/ -> root

No, this one is incorrect, it should be #/ -> root[""] according to the proposed text.

I am not sure if the arguments below still apply, since they seem to be predicated on a slash leading all JSON pointers, which is not the case, a slash leads path segments, of which the root pointer has none.

Dean Landolt

unread,
Jun 30, 2011, 11:38:24 AM6/30/11
to Kris Zyp, json-...@googlegroups.com
On Thu, Jun 30, 2011 at 11:02 AM, Kris Zyp <kri...@gmail.com> wrote:
On 6/30/2011 8:31 AM, Dean Landolt wrote:


On Thu, Jun 30, 2011 at 9:36 AM, Kris Zyp <kri...@gmail.com> wrote:
On 6/29/2011 11:33 AM, Dean Landolt wrote:


On Wed, Jun 29, 2011 at 1:05 PM, Paul C. Bryan <paul....@forgerock.com> wrote:
Unless there are strong objections, I'd like to incorporate this proposal into the next revision of the draft. I believe this gives us the best balance, and only creates a requirement for leading slashes in the pathological case of empty fragment.

This still has ambiguity (for the reasons I've listed exhaustively) but as it's really addressing the case of what should be in a fragment, and not what is in a pointer itself, I don't care all that much.
The ambiguity you listed was for the case of leading slashes being optional for empty strings, right? The text simply needs to be updated to say "all path segments SHOULD be preceded by a slash in a pointer fragment, and if the first path segment is an empty string, it MUST be preceded by a slash. However, if...".

I believe that should satisfy the desired use cases, avoid ambiguity, and maintain back-compat, does that sound good?

IIUC you're suggesting this resolution mapping:

# -> root
#/ -> root

No, this one is incorrect, it should be #/ -> root[""] according to the proposed text.

I am not sure if the arguments below still apply, since they seem to be predicated on a slash leading all JSON pointers, which is not the case, a slash leads path segments, of which the root pointer has none.

So the slash is a path segment prefix, not a path segment separator (except, optionally, on the first one)? That clears it up a bit more in my head, thanks. (Though the argument that a leading "/" improperly suggests "root" still applies, as well as that RQL argument against unnecessary prefixes :)

Let me try again:

# -> root
#/ -> root[""]
#foo -> root["foo"]
#/foo -> root["foo"]

The above pairs strike me as inconsistent, but my delicate sensibilities will survive :) ... at least it's easy enough to grok at least.

#/ -> root[""]
#// -> root[""][""]
#//foo -> root[""]["foo"]
#/foo -> root["foo"]
#/foo/ -> root["foo"][""]
#/foo// -> root["foo"][""][""]
#//foo// -> root[""]["foo"][""][""]
#foo/ -> root["foo"][""]
#//foo -> root[""]["foo"]

Are all of these right? If so, the inconsistencies are strange enough to be jarring. If there's no chance of swaying opinion to drop the leading slash, I'd suggest there's little value in #foo being equal to #/foo. And then (as Gary had suggested) there'd still be room in the fragment space to allow for other resolution protocols (I still don't think this is a good idea but why rule it out completely just to introduce the above oddities?).


Paul C. Bryan

unread,
Jun 30, 2011, 1:46:30 PM6/30/11
to json-...@googlegroups.com
On Thu, 2011-06-30 at 11:38 -0400, Dean Landolt wrote:

So the slash is a path segment prefix, not a path segment separator (except, optionally, on the first one)? That clears it up a bit more in my head, thanks. (Though the argument that a leading "/" improperly suggests "root" still applies, as well as that RQL argument against unnecessary prefixes :)

Yes.


Let me try again:


# -> root
#/ -> root[""]
#foo -> root["foo"]
#/foo -> root["foo"]


The above pairs strike me as inconsistent, but my delicate sensibilities will survive :) ... at least it's easy enough to grok at least.

Okay.


#/ -> root[""]
#// -> root[""][""]
#//foo -> root[""]["foo"]
#/foo -> root["foo"]
#/foo/ -> root["foo"][""]
#/foo// -> root["foo"][""][""]
#//foo// -> root[""]["foo"][""][""]
#foo/ -> root["foo"][""]
#//foo -> root[""]["foo"]

Yes, based on Kris' propsal, this is how they would be interpreted.


Are all of these right? If so, the inconsistencies are strange enough to be jarring. If there's no chance of swaying opinion to drop the leading slash, I'd suggest there's little value in #foo being equal to #/foo. And then (as Gary had suggested) there'd still be room in the fragment space to allow for other resolution protocols (I still don't think this is a good idea but why rule it out completely just to introduce the above oddities?).

If was given the choice exclusively between "foo" and "/foo", then I would chose the former, "foo". It is more intuitive in our use cases where you simply want to refer to some property in an object.

That said, Kris' proposal allows the syntax to remain intuitive, except when the pathological case of an empty property name is exercised. I think under either proposal, the pathological case is ugly.

Paul
Reply all
Reply to author
Forward
0 new messages