- From: Christian Grün <cg@basex.org>
- Date: Wed, 29 Jan 2025 09:41:38 +0000
- To: Michael Kay <mike@saxonica.com>, "public-xslt-40@w3.org" <public-xslt-40@w3.org>
- Message-ID: <AS4PR09MB554902005B35F809EEA33EDBC7EE2@AS4PR09MB5549.eurprd09.prod.outlook.com>
Hi Michael, > Unfortunately this cannot be implemented using map:put as a primitive, because `map:put($map, $key, $value)` is currently defined to return a map in which the new `$key` replaces the old. My feeling is that the current definitions are a bit ambiguous or vague. XQFO 4.0 says for map:put: > The entry order of the entries in the returned map is as follows: if $map contains an entry whose key is $key, then the new value replaces the old value and the position of the entry is not changed; otherwise, the new entry is added after all existing entries. The last sentence implies that only the value is replaced. XPDM says: > The key/value pairs in the returned map are as follows: > • One key/value pair for every key/value pair present in $map whose key is not equal to $key; plus > • One key/value pair whose key is $key and whose associated value is $value. > The entry order in the returned map reflects the entry order in the supplied $map. If the key of the new entry was present in $map then the new entry replaces that entry retaining its current position; otherwise, the new entry is added after all existing entries. It implies that there will be a new entry (consisting of the supplied key and value) which will replace the old one. Maybe we can refine it: "If the key of the new entry was present in $map" implies that the key is exactly the same key, but we actually have 3 cases: 1. Keys are exactly the same (e.g., integers 1 and 1) 2. Keys are regarded as equal, but are different (e.g., integer 1 and double 1e0) 3. Keys are different (e.g., integers 1 and 2) I believe that 2. can be restricted to cases for which fn:atomic-equal returns true, but where the type of the compared keys differs. In https://github.com/qt4cg/qtspecs/issues/1725#issuecomment-2609624271, my proposal was to treat 2. and 3. identically: > Another edge case that may need to be refined in the spec is the replacement of different keys that are deemed equal (1 vs 1.0) with map:put: > { 1: 'integer', 2e0: 'double' } => map:put(1.0, 'decimal') > As the stored key is changed by this update, I think we should treat it not as an in-place update, but as a delete-and-insert operation. > One advantage of this would be that the resulting order would unveil what has been going on. What do you think? > I considered using map:replace() instead of map:put(). The prose of map:replace suggests that the old key is retained, but the "formal equivalent" is defined using map:put(), which uses the new key. There is an open issue that may result in dropping map:replace. Maybe we could decide rather earlier than later whether we want to keep the function: https://github.com/qt4cg/qtspecs/issues/583. Thanks, Christian
Received on Wednesday, 29 January 2025 09:41:47 UTC