-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend FLWOR expressions to maps #31
Comments
I like this, but shouldn't it be
XDM doesn't explicitly define entry, but it's used exclusively in FO, e.g.:
|
It could also be done without the temporary map. For example:
|
I would be happy with
|
I'm not entirely convinced. Mainly because "entries" in a map aren't values in the data model; also because maps are unordered, and also because unlike processing arrays, it's not very difficult or inconvenient to do it using "for $k in map:keys($m), $v in $m($k) return.... |
@michaelhkay commented: It is high time that we come up with a set type in XPath. We actually have to deal all the time with sets (not just node-sets, but sets of any-type values), and it is painful to read in the spec how two maps are compared for equality when explaing "If $i1 and $i2 are both ·maps·, the result is true if and only if all the following conditions apply: Both maps have the same number of entries. For every entry in the first map, there is an entry in the second map that: has the ·same key· (note that the collation is not used when comparing keys), and has the same associated value (compared using the fn:deep-equal function, under the collation supplied in the original call to fn:deep-equal)." When if we had the set type the above would simply say: "If $i1 and $i2 are both ·maps·, the result is true if and only if the sets of their keys are equal, and the corresponding values for each key in the two maps are deep-equal." I propose that starting with XPath 4.0 we introduce the set type and define set equality, the union ( | ), intersection (intersect) and set difference (except) not only for node-sets but for sets of any-typed values. Then we can have a function: This makes We will no longer have to explain in a "Remarks" section that the result of a function is "unordered" or that its order is "implementation-defined" -- just by making this function return a set. How can almost all major programming languages (not even speaking of SQL), such as C#, Python and Java can have a set data type / interface, but even in XPath version 4 we still have to describe it in a free language narrative? Thanks, |
From a technical point of view, I concur. However, I want to restrict the scope of what we're attempting in this version: the reason the last version took 10 years to complete is that we were too ambitious. The most expensive changes to make are those that change the data model, and I think we should strongly resist doing that. |
Let's see what other people have to say. Should the language still be incomplete and encumbered, or can we do something good here? |
What we could contemplate, however, is a library of functions for manipulating sets of atomic values, using a map as the underlying representation. For example set:of("a", "b", "c") Going beyond sets of atomic values to sets of arbitrary values immediately gets you into the problem of defining equality between arbitrary values, which is a quagmire. |
I completely agree with Michael Kay here. Smaller steps to start with won’t prevent us from doing bigger steps later on. And I personally feel it's helpful not to go beyond the scope of the original issue in the discussion (here, it was “Extend the for member syntax to maps”). Otherwise, issues like this tend to be closed later on and replaced by new issues. |
Agreed, I submitted this as a new issue: |
People do it in other PLs. In the .NET world one simply uses |
It's unfortunate that in 3.1, the map:entry() and map:merge() functions model a key-value pair as a singleton map. I'm coming to the conclusion that decomposing a map into (key, value) records ( |
Instead of for key $key in ...
for value $value in ...
for key $key value $value in ... Related: https://lists.w3.org/Archives/Public/public-xslt-40/2023Jun/0026.html |
The grammar for the
|
FLWOR: for key $k value $v. qt4cg/qtspecs#31
I would love to find a more specific term than "value" for use when we talk of key-value pairs. Both for use in narrative prose and for use in this new syntax. It needs something that alerts the reader that we're talking about values in a key-value pair, not just any old value. |
Maybe Or |
The terms Therefore, I would personally object to something else used in the proposed syntax. For the prose, we could use something like "map value" or "value of the map" if we want to be specific -- I wouldn't object to something like that. Things like "projection" and "result" have different meaning that is likely to confuse a user. |
Yes, that’s a tricky one. In an ideal world, I would prefer another term as well, but I don’t expect it to be misleading in the given context: When talking about maps, directories, associative arrays etc., it’s just too common to talk about keys & values or names & values. If you don’t have maps as input, there’ll be no reason to use the keyword in your FLWOR expression. |
Shall we go for |
Now when we have established the record type (or haven't we?) why not use just a single |
A while ago when we gathered feedback, separate key/value variables were considered to be more intuitive (see also #31 (comment)). |
Speaking about convenience, I would prefer something like:
Another possible issue is that the order of the results is unpredictable, thus it may be useful to have:
which would return the |
I'd be happy to have either
or
With a preference for the former as it's better aligned with the syntax But what about "as" and "at" clauses? As for sorting, I think a standard |
My preference is for the latter - more concise and succinct. |
If we added Next,
for $key at $pos in map:keys($map)
for $value in $map($key)
return $pos || '. ' || $key || ': ' || $value Similarly, I would keep |
Note that the |
The XPath 4.0 discussion is in issue #37 for the |
I would favor that. |
What about the standard F&O 3.1 functions fn:load-xquery-module and fn:transform that even now (after waiting 10+ years) are still not implemented in BaseX? Yes, someone could tell us that "there is something like this... in BaseX", but the fact remains that BaseX is not even 3.1-compliant 10 years after publishing the official F&O Specs. Isn't this an intentional effort to prevent portability and interoperability in order to lock users into BaseX? Why worrying only about some users and not about other, who need to rely on compliance and interoperability? Please, be aware of this fact, which suggests that at least some users may have become desperate by now. |
I’m not sure how that relates to my observation. The point I was trying to make is that we are seeing more and more 4.0 features being used in production environments – it’s not just a hypothesis. I certainly won’t object, though, if the majority of us believes that it’s better to revert or revise features of the drafts. If you rather want to point out we should take our work on BaseX more seriously, or set other priorities, and if you want to learn what others think about it, our mailing list may be a better platform than this thread. Another option is to participate. As you may know, it’s all Open Source and freely available to everyone… |
I was just pointing out the fact that BaseX is in a hurry to implement new 4.0 features, while at the same time this application still remains incompliant with 3.1. This points out to particular, special and selective preferences in the implementors' decision-making. Personally, as a user I would prefer a compliant and interoperable XPath implementation to one that might be even more optimized and might have implemented a lot of new features, but at the same time has remained incompliant with established, official versions and specifications, which hinders interoperability and results in user-lockdown. |
Just use the alternatives ;) |
This is not the right place to discuss the conformance level of implementations. As regards the point:
I think we should avoid encouraging users to believe that they can rely on stability in the current draft specifications. A level of stability is desirable because it is the only way we will ever finish, but we should not allow that kind of argument to prevent us improving the work we have done where improvements are identified. |
Closed by virtue of PR #1249 |
Edit: Current proposal (#31 (comment)):
With the addition of the
for member
syntax for arrays, it is possible to use a ForExpr/FLWORExpr to enumerate the contents of sequences and arrays, but not maps. In order to be consistent and symmetric across these types, thefor member
syntax should be extended to support maps by enumerating the key/value entries of the map.Given a map of type
map(K, V)
the member RecordTest would berecord(key as K, value as V)
. Given a map of typemap(*)
, the member RecordTest would berecord(key, value)
.This would allow a user to write expressions like:
NOTE: With the addition of the
array:values
andmap:entries
functions in issue #29, it is possible to avoid the need of thefor member
syntax for arrays and maps, but may be worth keeping for people who prefer the wordy style of the XPath/XQuery syntax.The text was updated successfully, but these errors were encountered: