ietf-wg-jsonpath / draft-ietf-jsonpath-base

Development of a JSONPath internet draft
https://ietf-wg-jsonpath.github.io/draft-ietf-jsonpath-base/
Other
58 stars 20 forks source link

Why does `length()` return 1 for unsupported inputs? #361

Closed gregsdennis closed 1 year ago

gregsdennis commented 1 year ago

For length(), the spec defines

Its only argument is a value (possibly taken from a singular path as in the example above). The result also is a value, an unsigned integer.

  • If the argument value is a string, the result is the number of Unicode scalar values in the string.
  • If the argument value is an array, the result is the number of elements in the array.
  • If the argument value is an object, the result is the number of members in the object.
  • For any other argument value, the result is one.

Why return 1? That's a possible value for length() to return for valid inputs. Wouldn't it make sense to return a value that can't be returned by a valid input, like -1?

$[?length(@.authors) == 1]
[
  { "data": "no authors here" },
  { "authors": [ "a single author" ] }
]

Currently, this returns the both objects in the array, which is counter-intuitive. The length of the authors property in {"data": "no authors here" } is nonsensical because it doesn't contain an authors property.

cabo commented 1 year ago

Well, I picked this hoping people would notice this... 🤡

We have two different cases that probably also need different answers.

The one the text addresses: A non-container, non-string value, e.g., length(3) I think I can argue that 1 is a good value for that.

The one the text does not address: An empty nodelist (Nothing). 1 is definitely not a good value for that.
Nothing speaks for -1 except FORTRAN-era conventions. I think we want to be able to return Nothing here.

gregsdennis commented 1 year ago

The one the text addresses: A non-container, non-string value, e.g., length(3) I think I can argue that 1 is a good value for that.

I disagree. I don't think the "length" of 3 is 1. I think it's nonsensical. Numbers, booleans, nulls, and Nothing (really all that's left) don't have a "length." (We've also decided that we don't do any kind of type coersion, so interpreting length(3) as length([3]) is invalid.)

I think we want to be able to return Nothing here.

I'm happy with this.

glyn commented 1 year ago

I'd be comfortable with length(3) returning Nothing.