qt4cg / qtspecs

QT4 specifications
https://qt4cg.org/
Other
28 stars 15 forks source link

Align AnyMapTest, AnyArrayTest and with ElementTest #1403

Open line-o opened 4 weeks ago

line-o commented 4 weeks ago

I always wondered why ElementTests for any element can be written as element() which is equivalent to element(*) but as map() and as array() are not permitted and always have to include the asterisk (map(*)) .

This is still the case even in XPath4 and I think we should have a look, if this can be omitted. It does not add any value IMHO, but maybe I am overlooking something important.

https://qt4cg.org/specifications/xquery-40/xquery-40.html#doc-xquery40-ElementTest https://qt4cg.org/specifications/xquery-40/xquery-40.html#doc-xquery40-ArrayTest https://qt4cg.org/specifications/xquery-40/xquery-40.html#doc-xquery40-MapTest

The "fix" would be as simple as

[255]   AnyMapTest   ::=  "map" "(" "*"? ")"
[265]   AnyArrayTest ::=  "array" "(" "*"? ")"

-- update after comment from @michaelhkay --

The same does not apply to FunctionTest as as function() specifies a zero-arity function wheras as function(*) matches functions of any arity.

ChristianGruen commented 4 weeks ago

Sounds reasonable to me. We should also allow fn() and function().

michaelhkay commented 4 weeks ago

Yes, I agree, this would be more logical.

line-o commented 3 weeks ago

I'll prepare a PR

michaelhkay commented 3 weeks ago

I don't think function() is a good idea because it's easily confused with function() as item()* which only matches a zero-arity function. It also introduces a potential ambiguity/incompatibility with things like "function() as function() as item()*"

line-o commented 3 weeks ago

I agree function() is different from function(*)

line-o commented 3 weeks ago

Sounds reasonable to me. We should also allow fn() and function().

@ChristianGruen Sadly, we cannot do that.

line-o commented 3 weeks ago

Do I read the EBNF for FunctionTests correctly, function() is only allowed in combination with the return type ("function" "(" ")" "as" SequenceType)?

https://qt4cg.org/specifications/xquery-40/xquery-40.html#prod-xquery40-FunctionTest

[251] FunctionTest ::= Annotation* ( AnyFunctionTest | TypedFunctionTest ) 
[252] AnyFunctionTest ::= ("function" | "fn") "(" "*" ")" 
[253] TypedFunctionTest ::= ("function" | "fn") "(" (SequenceType ("," SequenceType)*)? ")" "as" SequenceType

Shouldn't this be

[253] TypedFunctionTest ::= ("function" | "fn") "(" (SequenceType ("," SequenceType)*)? ")" ("as" SequenceType)?
ChristianGruen commented 3 weeks ago

@ChristianGruen Sadly, we cannot do that.

Just fine, makes sense, thanks.

ChristianGruen commented 3 weeks ago

Slightly off-topic: Hardly anyone seems to understand why some data types are prefixed (like xs:string), whereas others are not and look like function calls (like item()). Would it be too big a step to introduce prefixed alternatives, only followed by parentheses if the type is further refined?

Currently Alternative
item() xs:item
node()? xs:node?
element(a)* xs:element(a)*
map(*)+ xs:map+
map(xs:int, xs:item+) xs:map(xs:int, xs:item+)
function(*) xs:function
function() as xs:int xs:function() as xs:int

If someone believes that my proposal is not just weird, I’ll be happy to create a separate issue for it.

line-o commented 3 weeks ago

Not sure how I feel about your idea @ChristianGruen. Trading three characters at the end with three characters at the beginning and having to educate users what this means when they see it in other people's code. Having all common types in one namespace seems valuable, though.

michaelhkay commented 3 weeks ago

function() is only allowed in combination with the return type ("function" "(" ")" "as" SequenceType)?

Correct. You can either omit all the types, so function(*) matches any function, or you have to include all the argument types AND the return type.

michaelhkay commented 3 weeks ago

item() vs xs:item

Having two ways of doing the same thing has the danger of creating more confusion; for the average reader, they'll assume these mean different things and have to go to the spec to find out that they don't.

In addition, it doesn't work for nodetests because these can be used in axis steps, for example child::text() which can't be replaced by child::xs:text, because xs:text is a valid element name.

ChristianGruen commented 3 weeks ago

Thanks. Yes, it’s too late for such fantasies.