I think the issue is more fundamental: IMO Validate is attempting to perform the equivalent of compile-time static type checking of (XPath) expression operands, whereas in reality XPath is (merely) an interpreted language [for lack of a better description] whose operand types are dynamically type cast - at runtime - to accommodate whatever current operator is being evaluated. This is typically accomplished by implicitly wrapping operators/arguments in the XPath primitives string(), number(), boolean(). The rules for these casts/conversions are quite explicit in the XPath spec, as are the consequences when (at runtime) the XPath processor finds it cant convert the underlying value; eg NaN.
I dont think this dynamic type-casting is necessarily flawed in any way, its just the way XPath works, and we should probably embrace it.
So I dont think we should introduce, and make users now include, entirely new XPath functions (eg to_date()
) which are redundant in terms of contributing anything to the calculation result, just to satisfy Validate's desire for everything to be statically typed [sic]. That feels like trying to force a square peg into a round hole...
[and if we were to go down that path, arguably Validate should never permit NaNs to crop up either!
]
I'd expect that types should always have precedence over any calculate expression's value.
...
Explore the idea of following the types declared in bind's
But that's simply not how XPath works. And I dont think we want to attempt to rewrite XPath to accommodate.
In order for Validate to be 100% accurate in its determination of validity, it must evaluate all XPath expressions within the same scope and following the same process as prescribed (proscribed?) for evaluating Xpath expressions, which involves type-casting operator arguments at runtime according to their current value. And I fundamentally see no way Validate can do so treating all variables as NULL during its static analysis.
Again, I think Validate's intentions are truly noble, and indeed very useful in providing form writers a quick preliminary check that their calculations aren't obviously syntactically broken. But it cant through static analysis determine what will/not in fact work at runtime (ie logic errors). So it should really be treated as a warning, and not a fatal, blocking error as it is presently.
That's why I don't like ambiguous type declarations like select (should be string, because a value from a select field will always be a string).
[At the risk of digressing completely from the topic at hand...] I totally agree. And disagree!. IMO the binding type of a select shouldn't be "select1", or even "string" for that matter; it should in fact be whatever type of value you are selecting, which could be a string ("Banana"), a number ("1") or even a date ("2019-11-20"). And the situation is even worse when it comes to select-multi, which should really be an array - of a basic type - neither of which we have anything in XForms presently to leverage. But I'll save that soapbox for another thread/time... 