Change:
This implicit conversion can be surprising in some situations, so it is made explicit via the value() function. Calling the value() function is a conscious choice, so should not be a surprise to the user. Fixes URL
I specifically do not like conversion functions. They are unnecessary cruft. For the conversion from to , I'm happy forbidding it, as we have in . I see no reason why a multiple nodelist should ever be converted to a value, even if it happens to have zero or one node.
Along with URL, I'm going to say that I'm okay with this as long as it's not trying to address the issues that is trying to address. My only argument against is that it enables behavior that can be unintuitive, even if it's explicit. I don't see any reason for a multiple-nodelist to be converted into a value. No one has provided a use case for this. This needs to be merged after .
Merged. See URL for the rationale behind this.
These questions/hurdles/nits came up while reading PR and related issues/PR's carefully.
In (L-1473) a nodelist. That '' for node seems to be used nowhere else.
Example (L-1552) What, if function returns ? Is , is it a comparable?
Example (L-1581) What is the return type, if the argument is ?
Nit (L-1650) ... 'an instance' ...
Consider What is the result, if the return value of is ? Shouldn't I always guard this by I think, I always would.
If I, as a non-implementer of JSONPath, would like to register a function, say ... taking a as single argument and returning an array of normalized pathes or ... I would need to know the implementation specific shape of and . As a consequence of this only implementers can register (or implement already registered) functions, as long as they didn't document internal aspects of and . If we do not want such a scenario, how could we achieve an implementation-independent interface (types) for functions?
Yep, this is a remnant. Fixed in e6dc704
Is declared as a ValueType, so it is well-typed as a . Section says: Then it goes on to say: So is false (5 is not Nothing), and also is false. Finally, it says: Since neither is the case, the answer is that the comparison is false.
NodesType does not have Nothing as a special value; this would be an empty nodelist. Count so it returns 0 on this case, as there is no (0) node in the nodelist.
Fixed in ff5f2a3
That is a matter of style, and I don't disagree with being explicit. value() still has to have a defined value as we don't have short-circuiting in JSONPath.
You can register it right away, but then you need to get the new function extension into implementations. JSONPath does not provide a way to define your own functions, so indeed, you'll have to wait for implementers. An expression language that allows to define functions in-language would be an interesting project, but probably going beyond what we can do here. No/Yes, see above. This type and this value are well-defined, so describing them in a registration should pose no problems. I'm having a hard time imagining such an interface. It would need to be different for different platforms, and for different strategies for implementing JSONPath on such a platform. So it would, for all intents and purposes, be implementation dependent. Unless/Until we define the abovementioned powerful expression language.
Oh, and remember that we are still in the filter selector expression mechanism, so it is not clear that such a function extension would be particularly useful. Adding Projection/Transformations to JSONPath is another interesting project that goes beyond base.
NAME : thanks for clarification of all ...
I believe the required changes were covered by URL Please re-open if this is not the case.
JSON Path may not provide this, but the more user-friendly implementations likely will (mine does). So you can register your function, then go on to implement the function and plug it in.
Indeed, it should not be too hard to do this for any single implementation (my PoC implementation currently doesn't, because I didn't need to prove that particular concept :-), but it will). Defining a way to do this across implementations, in a "standard" way, is much harder.
I don't think we need to define it. We can just state something like, or some such. The wording isn't great. We would need to be careful to not open the door for arbitrary custom functions (although implementations can still do that if they want; it just wouldn't be spec-sanctioned).
URL Followup issue from
If we want to know whether a function will return a singular nodelist or potentially a full one, we need to add to the declared types. We could define explicit conversion functions from nodelists and/or the new singular nodelist type to JSON values. So would become , making it explicit that we are not comparing the nodelists.
I think (type conversions) needs to be explored (and probably settled) before we can rightfully address this.
I had considered this as well, but with the conversions, I think they just muddy up the syntax.
To me could be taken a number of different ways. Either the node lists are the same or each element has an and a that must be equal. It could also mean some exists that equals some . Wouldn't it be better to use a nested selector (sorry if my terminology is incorrect) such as ?
I just noticed the double-dot. I'm not sure what you would mean by . This isn't valid (enforced by ABNF), and I don't think anyone is arguing that it should be. For , I think the type conversions are obvious. For something like , I'm not sure what to do. With the current conversions, you have three cases: (please forgive the incorrect syntax) both independently give no nodes or multiple nodes, implying returning true both give one node, meaning returning whatever the result of that is (could be true or false) one gives either no nodes or multiple nodes, and the other gives one node, meaning returning false I think the one we're hung up on here is the first case because and also in most cases . Moreover, we don't have a mechanism to compare multiple-node nodelists at all.
I see your line of thinking is to compare the node lists for a boolean result. There are case where a comparison is clear for lists of one or less. If that option was to be allowed and not just return false in all cases then I would think that the lists could only consistently be compared as to the contained nodes in any order since the ancestor () results could be in any order if one of the ancestor nodes was an object which is generally considered to be unordered.
is merely editorial, so it shouldn't block this issue.
PR is my preferred solution to this issue. PR 420 encapsulates the surprising behavior, which is the subject of this issue, in the function. The use of the function in queries becomes an explicit and conscious choice. The following alternative solutions have been suggested: PR proposes that all type conversions be explicit. This adds some precision to the spec and makes the well-typedness rules very compact, but at the cost of usability. The "Conversion example" section in PR 410 highlights the potential surprises remaining in the approach of PR 410. PR builds on PR 410 by adding a . This further impacts usability, as highlighted by the example query . PR 414 provides a type equivalent of a singular nodelist (the result of evaluating a Singular Path). is used either as a variant of in test expressions or as a way of obtaining a value in a comparison. Unlike Singular Paths, which are a syntactic device for avoiding multi-nodelist comparisons, does not appear to pull its weight in terms of specification precision vs the extra complexity/verbosity involved. PR also adds the , but without the usability downsides of the type conversion functions of PRs 410/414. The above critique of the applies to PR 412 too. PR 412 co-opts some implicit conversion rules in the rest of the spec into the function type system, making well-typedness more complex to define and understand.
After clarification of some points everything is ok.

Discussion:
JSONPath query is applied to. tbl-types defines the available types in terms of abstract instances, <del> where "n" denotes a node, "v" denotes a value, and "nl" denotes a nodelist. </del> <ins> where "v" denotes a value, and "nl" denotes a nodelist. </ins> Notes:

2.6.2. <del> The following type conversions may occur: Where an expression with a declared type of "NodesType" needs to be converted to a "ValueType", the conversion proceeds as follows: If the nodelist contains a single node, the conversion result is the value of the node. If the nodelist is empty or contains multiple nodes, the conversion result is "Nothing". </del> <ins> The following implicit type conversion may occur: </ins> Where a member of "NodesType" needs to be converted to a "LogicalType", the conversion proceeds as follows:

If the nodelist is empty, the conversion result is "LogicalFalse". <ins> Given an expression with a declared type of "NodesType", a "ValueType" can be obtained using a function such as "value()" (see value). </ins> The well-typedness of function expressions can now be defined in terms of this type system.

The argument is a Singular Path or "filter-path" (which includes Singular Paths), or a function expression with <del> declared result type "NodesType".  Where the declared type of the parameter is not "NodesType", a conversion applies. 2.6.3.1. While functions returning "NodesType" can appear in both comparisons and test expressions, path authors must be aware of the conversions and the potential outcomes.  Specifically, nodelists convert to values and logicals according to tbl-typeconv: For example, given a function "myfunc()" of declared result type "NodesType", the following filter expressions are both valid but can have different and unexpected results: Note that a multiple-node nodelist result is deemed "LogicalTrue" in the test expression, but cannot be used for conversion to a single value and thus feeds a comparison with "Nothing". </del> <ins> declared result type "NodesType" and the defined type of the parameter is "NodesType".  Where the declared type of the parameter is not "NodesType", a conversion applies. </ins> 2.6.4.

2.6.8. <ins> The "value" function extension provides a way to convert an instance of "NodesType" to a value and make that available for further processing in the filter expression: Its only argument is an instance of "NodesType" (possibly taken from a "filter-path" as in the example above).  The result is an instance of "ValueType". If the argument contains a single node, the result is the value of the node. If the argument is "Nothing" or contains multiple nodes, the result is "Nothing". 2.6.9. </ins> 2.7. For each node in an input nodelist, segments apply one or more