This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
XPath can now create empty arrays or create arrays from literals, two of the uses of map:new(). The third use is to merge arrays - for this purpose it would be helpful to have a more meaningful name. Consider the following two expressions, which differ only by the name of the function: $map => map:new( { "counter" : $map($key) + 1 } ) $map => map:merge( { "counter" : $map($key) + 1 } ) To my eyes, the meaning is much more obvious with the name map:merge(). I suggest: 1. Either keep the zero-arity and 1-arity map:new() as is or drop them in favor of the new constructors. 2. Create a new function called map:merge() with the same semantics as the current map:new() with arity greater than 1
The most recent decision of the joint WGs is that arrays are no longer a specialisation of maps. Presumably, therefore, this bug report is obsolete? At any rate, many of the justifications it uses no longer apply.
Hi Mike, I must be exhausted, I don't know why I said 'arrays' when I meant 'maps'. Here is the corrected text. ---------------------- XPath can now create empty maps or create maps from literals, two of the uses of map:new(). The third use is to merge maps - for this purpose it would be helpful to have a more meaningful name. Consider the following two expressions, which differ only by the name of the function: $map => map:new( { "counter" : $map($key) + 1 } ) $map => map:merge( { "counter" : $map($key) + 1 } ) To my eyes, the meaning is much more obvious with the name map:merge(). I suggest: 1. Either keep the zero-arity and 1-arity map:new() as is or drop them in favor of the new constructors. 2. Create a new function called map:merge() with the same semantics as the current map:new() with arity greater than 1
I think it might be a good idea to review where we stand on namespaces for these functions before we review the local names.
The XSL WG telcon looked at this today briefly; we didn't feel ready to make a decision but there was some sympathy to the idea of keeping the map:new#0 function to create an empty map, and renaming map:new#1 as map:merge#1. Given that we can also create a new map using the XPath 3.1 syntax map{}, the only real case for keeping map:new#0 is the transitional benefit that it provides a way of creating a map using functions alone, without relying on new syntax. But if the only purpose is transitional, then map:merge(()) (merging an empty set of maps to create an empty map) might be good enough for the requirement.
The WG looked at this today and agreed that it would be a good idea to try and find function names that more closely matched the tasks being performed, however elegant it might appear to have one multi-purpose function. The editor was asked to produce a proposal. I'm inclined to go with the following: (1) To create an empty map, use either map{} or map:merge(()). (2) map:merge() acts lile the current map:new() - it takes a sequence of maps and merges them into a single map, resolving duplicate keys. (3) To add an entry to a map (creating a new map), use map:put($map, $key, $value). The new entry replaces any existing entry with the same key. This function works well with the new function chaining operator: map{} => map:put("a", 1) => map:put("b", 2) (though of course simple cases like this can be done equally well with a map expression). (4) map:entry() which creates a singleton map, can now be dropped. Anyone who really wants this function can either use map expressions, or implement it as let $map:entry := map:put(map{}, ?, ?) So we end up with two functions map:merge() replacing map:new(), and map:put() replacing map:entry().
I agree to renaming map:merge. Also, allowing map{} makes sense, but it doesn't require a change, it is already allowed: MapExpr ::= "map{" (KeyExpr ":" ValueExpr ("," KeyExpr ":" ValueExpr )*)? "}" I would prefer to keep map:entry (or perhaps map:item) as the equivalent counterpart of xsl:map-entry (or xsl:map-item). Note also that we used to have map:put, but don't have it anymore. Furthermore, it strikes me as odd that map:put would _not_ throw an error if the item already existed. I would like to argue, in line with existing maps/dictionaries/hashsets in other programming languages, that adding an item that already exists is not allowed. We could consider both a map:put and map:set, where the latter overrides an existing entry, or adds it if it doesn't exist, and the former (map:put) raises an error if an item exists. Instead of map:put, perhaps map:add is better. To summarize, I would like: 1) map:add (error if exists) 2) map:put/set (no error if exists, overwrites) 3) map:merge (as per MK's proposal) 4) map{} (as per MK's proposal) 5) map:entry (retain it) 6) remove map:new
The XSL WG looked at this on 8 May 2014. We propose, subject to the XQuery WG concurring, the following: 1. map:new#0 is dropped. An empty map can be constructed using map{}. 2. map:new#1 is renamed map:merge, with no change in behaviour. 3. A new function map:put($map, $key, $value) is defined. The semantics are equivalent to map:merge(($map, map{$key, $value}))
Item 3 in the previous comment should read: 3. A new function map:put($map, $key, $value) is defined. The semantics are equivalent to map:merge(($map, map{$key : $value}))
Looks good to me.
The proposal has been accepted by both XSL WG and XQuery WG and will be implemented in both XSLT 3.0 and F+O 3.1.