kdl-org / kdl

the kdl document language specifications
https://kdl.dev
Other
1.1k stars 61 forks source link

Does argument order w.r.t. properties matter? #205

Closed CAD97 closed 2 years ago

CAD97 commented 2 years ago

The spec says that

Arguments are ordered relative to each other and that order must be preserved in order to maintain the semantics.

By contrast, Property order SHOULD NOT matter to implementations. Children should be used if an order-sensitive key/value data structure must be represented in KDL.

My question is: if a property is between two arguments, is that allowed to impact the semantics of the arguments in a fully-SHOULD-compliant implementation?

Using the given example,

foo 1 key="val" 3 {
    bar
    (role)baz 1 2
}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// is that semantically different from
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
foo 1 3 key="val" {
    bar
    (role)baz 1 2
}

More informally, does the spec require grouping the above node as roughly foo (1) (key="val") (3), or is an implementation allowed to interpret it as foo (1) key=("val" 3)?

If argument/property mixing SHOULD NOT matter to implementations, I suggest the following clarification to the spec:

@@ -60,2 +60,2 @@
-Arguments are ordered relative to each other and that order must be preserved
-in order to maintain the semantics.
+Arguments are ordered relative to each other (but not Properties), and that
+order must be preserved in order to maintain the semantics.

If argument/property mixing MAY matter to implementations, I suggest the following clarification to the spec:

@@ -60,6 +60,6 @@
-Arguments are ordered relative to each other and that order must be preserved
-in order to maintain the semantics.
+Arguments are ordered relative to each other and to Properties, and that
+order must be preserved in order to maintain the semantics.

-By contrast, Property order _SHOULD NOT_ matter to implementations.
-[Children](#children-block) should be used if an order-sensitive key/value
-data structure must be represented in KDL.
+By contrast, Property order relative to each other _SHOULD NOT_ matter
+to implementations. [Children](#children-block) should be used if an
+order-sensitive key/value data structure must be represented in KDL.

The scope of this question is that I'm drafting out a semi-formal spec for Serde-in-KDL (SiK) a la JiK or XiK, describing how to map between the Serde data model and KDL. Current draft here. I want SiK to feel like natural KDL use as much as possible, and I think I've captured that, save for one current limitation: mixing properties and arguments in a single node isn't supported. In the document I have a potential way to support arguments before properties, but whether this is possible depends on whether this is deserializable within serde's API (unknown, slightly positive), and arguments mixed with properties will need to know the answer to the above spec clarification before I can even consider deciding what the semantics of such should be.

And yes, I am reaching out to collaborate with Lucretiel/kaydle, now that I'm aware of that effort.

djmattyg007 commented 2 years ago

I don't see how the relative ordering of arguments to properties can be considered significant. Attempting to make it significant would make the ordering of properties themselves significant.

CAD97 commented 2 years ago

Property ordering relative to other properties can still be insignificant, even while argument ordering w.r.t. properties is significant.

For the serde use case example, it roughly goes as:

And a slightly different case

In neither of these cases is the property order w.r.t. other properties semantic, as the properties always refer to their named field, and mixing only impacts the meaning of arguments.

zkat commented 2 years ago

No, argument vs property ordering does not matter. The only thing that matters is argument ordering vs other arguments. Property ordering does not matter except when you deal with duplicates, in which case only the last duplicate wins. No other ordering matters.

CAD97 commented 2 years ago

So w.r.t. SiK, the only correct interpretation is that foo 1 key="val" 3 and foo 1 3 key="val" are equivalent, so arguments must (if supported for structs) be the fields counting from the start, ignoring properties. I think for simplicity, if I end up allowing these in SiK, I'd only allow arguments before properties in the SiK microsyntax.

(The rightmost-property-wins rule is interesting for the serde mapping, as the serde-native interpretation is just to pass this duplication along to the impl Deserialize and let that decide how to handle it (typically, error for struct, last-wins for maps). I think I'll end up just saying "not allowed; implementation defined results" in the SiK spec.)

(Very side note: would kdl-org (or even this repo) be interested in hosting a SiK spec, once it's reasonably solidified and @Lucretiel is also on board with it?)

djmattyg007 commented 2 years ago

Doesn't the "last duplicate always wins" rule only affect deserialisation anyway? There's nothing stopping you from outputting the duplicates during serialisation.

CAD97 commented 2 years ago

Yes; I'm trying to take a holistic design view for SiK even though I've only implemented a serializer so far. Also, serialization almost certainly won't generate duplicates, as that would require a nonstandard Serialize implementation to serialize multiple fields with the same name. (In such a case, I would need to open up a children block; SiK does not distinguish between properties and children nodes.) Serde maps must always be a children block and not properties, as serde maps MAY be order sensitive.