Closed line-o closed 1 year ago
JSONiq had a map merge syntax that could be used similarly:
let $my-var := (:map:) { "my-var": <root/> }
let $other := (:map:) { "a": [ 1, 2, 3 ] }
return {|
$my-var,
$other
|}
Interesting, @benibela. Thanks for bringing it to attention.
Having an explicit map constructor for maps constructed by variable references was also proposed by Liam Quinn on Slack: vmap{ $a, $b }
It limits the construction of maps to exclusively use one or the other method. I do find it useful to mix both methods (as you can in JavaScript)
let {a, c} = {a:1, b:2, c:3}
let next = {a, c, q: "sth"}
The difference is of course that there is no way to construct keys from variables in object literals in JavaScript as one can in XQuery.
This proposal violates the principle that variables should be substitutable by their values. This principle is very important in allowing optimization. The expression
let $my-var := <root />
let $other := map { "a": [ 1, 2, 3 ] }
return map {
$my-var,
$other
}
should be statically rewritable as:
map{<root />, map { "a": [ 1, 2, 3 ] }}
The danger is that optimizations are prevented even if the new feature is never used.
The danger is that optimizations are prevented even if the new feature is never used.
I had similar thoughts. Maybe the problem can be circumvented by generating the key/value representation at parse time?
I would be more sympathetic if the $my-var
didn't look like an ordinary variable reference, for example if it used some custom syntax like $$my-var
- though I don't like that syntax.
Perhaps
let $my-var := <root />
let $other := map { "a": [ 1, 2, 3 ] }
return variable-map {
$my-var,
$other
}
I think I agree, even though the JavaScript syntax is sometimes convenient.
Treating code and data equally can be dangerous, if not critical, for example when you perform refactorings and rename variables.
I see both map destructuring and construction of entries by variable reference as syntactic sugar. So adding a step in compilation to get to a normal form sounds about right. @michaelhkay doesn't #37 then also violate the (static) variable substitution principle?
OK, so there is some consensus in introducing a new keyword vmap
, variable-map
, varmap
or similar.
Mixing both the current and the terser syntax would then come down to
let $b := 2
return
map:merge((
map { "a": 1 },
(: the new construct :)
varmap { $b }
))
If it is crucial to syntactically differentiate between the two entry construction methods we could also revisit the jsoniq syntax {| $var |}
.
map {| $a, $b, $c |}
I was not aware of the principle in XQuery that variables need to be able to be substituted by their value at all time.
@ChristianGruen renaming a variable is then also renaming the key. This needs then taken into account.
I also have not thought about the new record
type and how it might affect this proposal.
I was not aware of the principle in XQuery that variables need to be able to be substituted by their value at all time.
It's not specifically a principle for XQuery, it's a general principle of orthogonal language design in expression-based languages, that anywhere you can write the value 42, you can replace it with an expression that evaluates to 42 without changing the meaning; conversely, anywhere you write an expression, you can replace it by the value of the expression (assuming the value is effable).
If you would introduce a kind of dereferencing syntax then it might be intuitive to have it resemble the destructuring syntax for maps.
let ${a, b} := map { "a": 1, "b": 2 }
return map { ${a}, ${b}, "c": 3 }
or let $m := map { ${ a, b } }
or even let $m := ${ a, b}
NOTE: There might be a better syntax for both operations, but they should be aligned.
The CG agreed to close this issue at meeting 024
@ndw Reading through the Meeting minutes this issue was closed because it is not a concrete proposal. What would be needed for this to be concrete? I want to know for future and still open proposals what the shortcomings are.
That's not a good summary of why it was closed. Basically, we've been closing a few issues where the discussion explored a variety of alternatives but failed to converge on a consensus design. In such cases we've usually found that it's best to learn from the discussion, think again about what we're trying to achieve, and either drop the idea, or come up with a new proposal that meets the objections and difficulties that were encountered, and articulates the alternative options and their pros and cons.
The root idea lives on in the following threads:
@Arithmeticus I read all three linked issues. To me they are unrelated as none of them addresses the construction of maps.
Allow variables to be used to construct map entries with
The syntax would change to something along
Example:
evaluates to
This is the inverse operation of destructuring a map as proposed in https://github.com/qt4cg/qtspecs/issues/37
In the Slack discussion John Lumley and Liam Quinn raised concerns this construct might be error prone when both methods to construct an entry can be mixed