Change:
This PR also addresses URL
My now implements everything in the spec, including this PR. (It also supports math operations in expressions, which isn't part of the spec (yet).) The function infrastructure was a struggle (mostly because I'm in a strongly typed language, I suspect), but once implemented, creating the functions themselves and registering them so that they can be parsed was easy! With my lib, the user would implement a "function definition" interface which exposes the name, the range of parameters expected (min/max), and the logic for the function itself (which follows a pattern defined in my lib). Once an instance of their definition is registered, it's available to be parsed. The parsing logic handles validating that the function receives the correct number of parameters, too, so if you send seven arguments, it'll fail to parse.
Tangentially related to , would we consider the use of a function as an argument to another function. Currently this is not allowed as a function is not a . An example for this may be: to determine if the maximum between and is less than 10.
Yes, I hope to support using the result of a function as an argument to a(nother) function in URL Note that I don't intend to support passing a function as an argument to a(nother) function or returning a function from a(nother) function, as in the following example, which does both:
FWIW I'd be fine with this being in a follow-up PR to .
It actually looks like this is already supported. can be a can be a takes zero or more s as parameters
Would we consider allowing advanced expressions usages? This would return the objects with s 1 and 4. (Yeah, we don't support currently, but the example illustrates the idea.) This would return the object with 1. There are probably other ways expressions could be used, too.
Note that function extensions, with the improvements anticipated in URL, may be able to address the above use cases:
I think what I've written is probably the more intuitive given the gamut of features in programming languages available today. What you have is definitely more functional (i.e. functional programming style), but I would tend toward using the operators for these examples. This issue isn't about "how could this be done with what we have?" but rather "is this something we want to support?"
Interestingly, I found a test in the comparison project that treats an expression as a : .
Here's . There is no consensus among implementations, although 14 of them behave the way this issue is proposing. (Embarrassingly, my Go implementation gets just the opposite of that result. That looks like a bug IIRC.)
2023-01-10 Interim: Do not do this enhancement.
Currently function extensions that return a nodelist must return a nodelist consisting of a single node. When a function extension is used as a comparable, it should be able to return an empty nodelist. When a function extension is used in an existence test, it should be able to return any number of nodes in its nodelist. (Currently, such an existence test always yields true since the returned nodelist is non-empty.)
Also if a function is used as an input to another function, it should be allowed to return multiple nodes.
Agreed. PR 330 addresses this.
This issue was addressed by PR .
I believe this is ready for merging (to serve as the next baseline). My comments can either be resolved or entered as new issues.

Discussion:
under consideration was constructed out of JSON text that exhibits multiple members for a single object that share the same member name ("duplicate names", see RFC8259).  Also, selecting a child by name <del> (name-selector) and comparing strings (comparisons in Section filter- </del> <ins> (name-selector) and comparing strings (comparisons in filter- </ins> selector) assume these strings are sequences of Unicode scalar values, becoming unpredictable if they are not (RFC8259).

)-1]. <del> The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further errors relating to the well-formedness and the validity of a JSONPath query can be raised during application of the query to a value. </del> <ins> Uses of function extensions must be correctly typed, as described in fnex. A JSONPath implementation MUST raise an error for any query which is not well-formed and valid.  The well-formedness and the validity of JSONPath queries are independent of the JSON value the query is applied to; no further errors relating to the well-formedness and the validity of a JSONPath query can be raised during application of the query to a value. </ins> Obviously, an implementation can still fail when executing a JSONPath query, e.g., because of resource depletion, but this is not modeled

. <del> The syntax and semantics of segments are defined in Section segments- details. </del> <ins> The syntax and semantics of segments are defined in segments-details. </ins> 2.3.

expression, usually involving the current node, is evaluated and the current node is selected if and only if the expression yields true. <del> Paths in filter expressions are Singular Paths, each of which selects at most one node. </del> The current node is accessible via the current node identifier "@". <ins> An existence expression may test the result of a function expression (see fnex). </ins> Parentheses MAY be used within "boolean-expr" for grouping. <del> Comparisons are restricted to Singular Path values, each of which selects at most one node, and primitive values (that is, numbers, strings, "true", "false", and "null"). </del> <ins> Comparisons are restricted to primitive values (that is, numbers, strings, "true", "false", and "null").  These can be notated as literal values, or they can be derived from Singular Paths, each of which selects at most one node.  Function expressions (see fnex) used in comparison expressions return a primitive value or at most one node. </ins> Alphabetic characters in ABNF are case-insensitive, so "e" can be either "e" or "E".

2.5.5.2.4. Filter selectors may use function extensions, which are covered in <del> Section fnex. </del> <ins> fnex. </ins> 2.5.5.3.

add filter expression functionality: "Function Extensions". A function extension defines a registered name (see iana-fnex) that <del> can be applied to a sequence of zero or more arguments, resulting in a result.  A function-expression stands for ("returns") a nodelist or a value.  The arguments are filter expressions that are to be interpreted as nodelists or values.  For each argument and for the result, the function extension defines the "kind" of the item, i.e., whether the item is a value or a nodelist ("nodes"). Syntactically, a function-expression can occur anywhere where a singular-path can occur (exist-expr, comparable).  A function- expression that employs a function extension that returns a nodelist MUST return a singular node to be used in a comparable. </del> <ins> can be applied to a sequence of zero or more arguments, producing a result. A function argument is a "filter-path" or a "comparable". According to filter-selector, a "function-expression" is valid as a "filter-path" or a "comparable". Any function expressions in a query must be well-formed (by conforming to the above ABNF) and correctly typed, otherwise the JSONPath implementation MUST raise an error (see synsem-overview). To define which function expressions are correctly typed, a type system is first introduced. </ins> 2.6.1. <ins> Each argument and result of a function extension must have a declared type. A type is a set of instances.  A type is a subtype of another type if its set of instances (possibly after coercion) is a subset of the set of instances of the other type. tbl-types defines the available types in terms of abstract instances, where "n" denotes a node, "v" denotes a value, and "nl" denotes a non-empty nodelist.  The table also lists the subtypes of each type. Notes: "OptionalNodeOrValue" is an abstraction of a "comparable" (which may appear on either side of a comparison or as a function argument). "OptionalNode" is an abstraction of a Singular Path. "Value" is an abstraction of a primitive value. "Boolean" is an abstraction of a primitive value that is either "true" or "false". "OptionalValue" is an abstraction of a primitive value that may also be absent. "Absent" is an abstraction of an empty nodelist. "OptionalNodes" is an abstraction of a "filter-path" (which appears in an existence test or as a function argument). The abstract instances above can be obtained from the concrete representations in tbl-typerep. The following subtype relationships depend on coercion: "OptionalNode" is a subtype of "OptionalValue" via coercion since the "OptionalNode" instance "Node(n)" can be coerced to the "OptionalValue" instance "Value(v)", where "v" is the value of the node "n". "OptionalNode" is a subtype of "OptionalNodes" via coercion since the "OptionalNode" instance "Node(n)" can be coerced to the "OptionalNodes" instance "Nodes(l)", where "l" is a nodelist consisting of just the node "n". The type correctness of function expressions can now be defined in terms of this type system. 2.6.2. A function expression is correctly typed if all the following are true: If it occurs as a "filter-path" in an existence test, the function is defined to have result type "OptionalNodes" or one of its subtypes, or to have result type "OptionalBoolean" or one of its subtypes. If it occurs as a "comparable" in a comparison, the function is defined to have result type "OptionalNodeOrValue" or one of its subtypes. For it and any function expression it contains, each argument of the function matches the defined type of the argument according to one of the following rules: The argument is a function expression with defined result type that is the same as, or a subtype of, the defined type of the argument. The argument is a literal primitive value and the defined type of the argument is "Value" or any type of which "Value" is a subtype. The argument is a Singular Path and the defined type of the argument is "OptionalNode" or any type of which "OptionalNode" is a subtype. The argument is a "filter-path" or a Singular Path and the defined type of the argument is "OptionalNodes". 2.6.3. </ins> The "length" function extension provides a way to compute the length of a value and make that available for further processing in the filter expression:

For any other argument value, the result is one. <del> 2.6.2. </del> <ins> 2.6.4. </ins> The "count" function extension provides a way to obtain the number of nodes in a nodelist and make that available for further processing in

integer, that gives the number of nodes in the nodelist.  Note that there is no deduplication of the nodelist. [dedup] <del> 2.6.3. </del> <ins> 2.6.5. </ins> The "match" function extension provides a way to check whether (the entirety of, see search below) a given string matches a given regular

contained in the string that is the second argument.  The result is "true" if the string matches the iregexp and "false" otherwise. <del> 2.6.4. </del> <ins> The result is "Nothing" if the first argument is not a string or the second argument is not a string conforming to I-D.draft-ietf- jsonpath-iregexp. 2.6.6. </ins> The "search" function extension provides a way to check whether a given string contains a substring that matches a given regular expression, which is in I-D.draft-ietf-jsonpath-iregexp form. <ins> The result is "Nothing" if the first argument is not a string or the second argument is not a string conforming to I-D.draft-ietf- jsonpath-iregexp. </ins> Its first argument is a string that is searched for at least one substring that matches the iregexp contained in the string that is the second argument.  The result is "true" if such a substring exists, "false" otherwise. <ins> 2.6.7. </ins> 2.7. Segments apply one or more selectors to an input value and