Original text:
Each parameter as well as the result of a function extension must have a declared type. <del> A type is a set of instances.  Declared types enable checking a JSONPath query for well-typedness independent of any query argument the JSONPath query is applied to. </del>  <del> tbl-types defines the available types in terms of abstract instances, where "v" denotes a value, and "nl" denotes a nodelist. </del>  Notes: <del> "ValueType" is an abstraction of a JSON value or "Nothing". </del>  <del> "LogicalType" is an abstraction of the result of a "logical-expr". Its two instances, "LogicalTrue" and "LogicalFalse", are not related to the JSON literals "true" and "false" and have no direct syntactical representation in JSONPath. </del>  <del> "NodesType" is an abstraction of a "filter-query" (which appears in a test expression or as a function argument).  Members of "NodesType" have no direct syntactical representation in JSONPath. The abstract instances above can be obtained from the concrete representations in tbl-typerep. </del>  2.6.2. The following implicit type conversion may occur: <del> Where a member of "NodesType" needs to be converted to a </del>  "LogicalType", the conversion proceeds as follows: If the nodelist contains one or more nodes, the conversion The argument is a function expression with declared result type that is the same as the declared type of the parameter. <del> The argument is a literal primitive value and the defined type of the parameter is "ValueType". </del>  <del> The argument is a Singular Query or "filter-query" (which includes Singular Queries), or a function expression with 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. </del>  2.6.4.

Reviewer comments:
Also tidy up the well-typedness rules and add an example. Fixes URL
NAME I'm going to merge this as I'm sure it will satisfy your concern - it follows pretty closely your preferred solution.
I am working my way through 2.6.1 and my progress is being hampered by the use of the undefined terms "instance" and "abstract". I'm trying to understand this: "A type is a set of instances." The difficulty is increased when I run into undefined notations such as . I think you're trying to say something like "A type is construct that constrains what can appear as an argument to a function and the result of evaluating a function." I'm not sure Table 13 is helpful at all, the bullet list seems to contain all the useful information without relying on mysterious notations. And I'm not sure you need to use the words "abstract" or "abstraction" at all. For example, is the following clearer? "ValueType" means either a JSON value or Nothing. "LogicalType" means the result of a logical-expr. Its possible values, LogicalTrue and LogicalFalse, are not related to the JSON literals true and false and have no direct syntactical representation in JSONPath. "NodesType" means the results of evaluating a filter-query (which appears in a test expression or as a function argument). Members of NodesType have no direct syntactical representation in JSONPath.
As you point out, this is tricky language for readers unfamiliar with abstract data types. It would be good to find wording which presumes less background knowledge. I have three concerns over the rewording you propose: the loss of abstraction, whether the resultant types are well defined, and the impact on the spec. The types are intended to be abstract: each JSONPath implementation is free to choose its own concrete representation of each type. Let's take as an example. As you observe, it's meant to cover two possibilities. Either it corresponds to a JSON value or to the abstract value Nothing. The value doesn't correspond to any JSON value. So an implementation in C could represent a as a pointer to a JSON value (possibly a struct) with the null pointer representing . On the other hand, an implementation in Haskell could use a data declaration: Note that in both these implementations, is distinct from JSON values: a JSON value is not valid as a . If we removed the "abstract" language, we'd need to ensure that these kinds of implementations, and others, are still acceptable. The spec doesn't define a type system for all JSONPath subexpressions. In particular, does not have a type, so it's not clear how we define as a type in terms of the results of a . Similarly doesn't have a type, so the same concern applies to defining as the result of a . If we were to define as the result of a , then we'd presumably need to allow any as an argument to a parameter of type - something the current well-typedness rules disallow. We may decide this is a desirable spec change, but it is a change.
For example, currently isn't allowed.
I think this is not just good, but essential. I really don't think it's OK to introduce this terminology without defining what it means. In table 14, you have an excellent explanation of what Nothing means. I think it'd be valuable to hoist that language up near the top of the Type System section, and then when you say "JSON value or Nothing" I think that's all an implementer needs to be told. I can think, in Java or C or Go, of a variety of ways I might represent Nothing, and I can't imagine that spec language getting in my way. Actually, I went and looked again and I'm increasingly convinced that your useful definition of Nothing needs to appear in that section. before you start using it. Well, their acceptability is surely to be judged by whether their behaviour conforms to the spec. So the spec's job is to define behaviour with sufficient clarity to establish that. It's not obvious to me that the (unspecified) formalisms you're using are required to do that. Fair enough; I suggest that all you need to say is that LogicalType can be either LogicalTrue or LogicalFalse, which are interpreted in the usual way for booleans but are distinct from the JSON true / false values. What is "abstract" about this? Draft currently says "NodesType is an abstraction of a filter-query". I'm sorry, I don't understand that. What does "abstraction" mean? My guess was that you meant "what a filter-query returns" and that made sense when I ran some examples in my head but I guess I got it wrong. Hmm, evaluating a filter-query generates a NodeList, no? Is the constraint that the argument/result must be a NodeList (something that a developer who's read this far into the spec is certainly going to know how to deal with)?
NAME I agree that it's essential to find wording which presumes less background knowledge, particularly of (you may be interested in following this link if you'd like to understand my usage of the term abstraction). I'll have a shot at a PR tomorrow.
FWIW, in JSON Schema, "instance" is the term we use for the subject data (the data being validated). For us, that's the data being searched.
It's hard to avoid overlap with other specs! (I'd prefer to talk about "values", rather than instances, of types, but that's a loaded term in the JSONPath spec.)
I'm not worried about overlap. I was just offering another usage of the term.
Yep, the JSON vobaculary is often getting in the way. We used some of this experience when defining the vocabulary for CBOR; e.g. "data item" for what is "value" in JSON, and "map" for what is "object" in JSON.

Revised text:
Each parameter as well as the result of a function extension must have a declared type.  <ins> Declared types enable checking a JSONPath query for well-typedness independent of any query argument the JSONPath query is applied to. </ins>  <ins> tbl-types defines the available types in terms of the instances they contain. </ins> Notes:  <ins> The only instances that can be directly represented in JSONPath syntax are certain JSON values in "ValueType" expressed as literals (which, in JSONPath, are limited to primitive values). </ins>  <ins> "Nothing" represents the absence of a JSON value and is distinct from any JSON value, including "null". </ins>  <ins> "LogicalTrue" and "LogicalFalse" are unrelated to the JSON values expressed by the literals "true" and "false". </ins> 2.6.2. The following implicit type conversion may occur:  <ins> Where an instance of "NodesType" needs to be converted to a </ins> "LogicalType", the conversion proceeds as follows: If the nodelist contains one or more nodes, the conversion The argument is a function expression with declared result type that is the same as the declared type of the parameter.  <ins> The argument is a function expression with declared result type "NodesType" and the declared type of the parameter is "LogicalType".  In this case the argument is converted to "LogicalType". The argument is a value expressed as a literal and the defined type of the parameter is "ValueType". The argument is a query and the declared type of the parameter is "NodesType". </ins>  <ins> The argument is a query and the declared type of the parameter is "LogicalType".  In this case the argument is converted to "LogicalType". </ins> 2.6.4.