Hi Stas, Axel,
Thanks for the feedback!
Stas:
> What if we limit the foo[bar] accessor syntax to values which are a
Pattern with a single select expression which must not have a
selector? Otherwise [bar] is ignored and normal semantics of resolving
the Pattern apply.
Great point. I did not consider that.
I believe that your proposal is good. It's perfectly in line of solving the common case well, and leaving a more esoteric variant of the problem for later, as long as we agree that it seems like we'll be able to find a solution that won't require backward incompatible changes.
I think that all more complex specifiers/accessors can be added later if we find uses for them, and putting this limitation will not impair any use case I can think of right now while allowing us to simplify the syntax and make it more intuitive.
So, +1 :)
Axel:
> One problem statement is the difference between internal and external
traits.
Yes. Out of the three cases I listed, two (multi-variant values and meta-information) are internal, and one (multi-valued translation unit) is external.
> I strongly believe that they should not be used together in practice.
I agree. And the fact that the design of the syntax does not distinguish between them and gets us in a position that, in theory, a gender variant of the value will have the same syntax as a gender meta-information, has been bothering me ever since we came up with traits.
I believe that this proposal solves it by:
a) moving multi-variant values to use our variant selector syntax
b) renaming the external traits to what everyone in the world calls them - attributes
Traits in their original form fit only the meta-information piece, but because of their open, catch-all nature, we put the other two uses in them and then had to come up with namespaces to distinguish between them.
> This is something that we can enforce in linters and other tools.
Or via syntax. Which is what I'm proposing here.
> You lost me here.
Sorry, I was overly defensive. In short, I believe that we should focus on the most common case and make it be the most readable and easy to understand.
The most common use of multi-variant value in FTL is going to be a single variant list for the whole value, like:
brandName =
[nominative] Firefox
[possesive] Firefoksa
And I believe that there's no reason to keep it as separate syntax from our variant selector syntax because those are variants of the message.
My argument is that you will never want to have both, the value, and this case of traits, because those traits *are* the value.
So I suggest merging them back:
brandName = {
[nominative] Firefox
[possesive] Firefoksa
}
When we originally talked about this we discussed more complex cases and how to handle them in FTL, which is what I tried to address here, but those are edge cases and it's worth saying that I believe that we will be able to solve them without any breaking changes if we ever have to.
> I personally think that this makes things worse. Reminds me of the <> we
had in .lols. Everybody cheered when we got rid of those.
I don't think I understand how it reminds you of <>. This and your next comment:
> One of the big wins of FTL was that everything about the message was in
> the value part of the syntax.
>
> I'd not want to give this up for the multiple messages syntax.
makes me think that maybe I failed to communicate this part of the proposal well.
In the current syntax, the multi-varaint value is outside of the value itself.
In other words:
key = { [one] One [other] Other }
is a single value for ID `key`, with the following AST:
{
id: 'key',
value: [Placeable(SelectorExpression)]
}
but:
key =
[nominative] One
[possesive] Other
is not! We have a value here (which is empty) and two traits which are separate from the message. The AST is:
{
id: 'key',
value: null,
traits: [
{ id: 'nominative', value: 'One'},
{ id: 'possesive', value: 'Other'},
]
}
My proposal actually does exactly what you're advocating for - merges those traits back into the message value:
key = { [nominative] One [possesive] Other }
The only missing part is how to refer to a particular case, and I propose that we keep the same syntax: key[nominative] to resolve the first selector of the message using 'nominative' variant.
:stas suggests that for now, we limit the syntax to this, and leave the door open to explore supporting more complex accessors (for values with multiple selectors or nested selectors) in the future
> b) is the same thing as traits right now, just that we re-introduce a
different syntax to distinguish private from public ones, right? And
dropping the namespaces.
Yes! Once we merge (a) back into entity's value, we're left with two uses of traits: multi-value and meta-info. The former is external, the latter internal.
Both don't fit into entity's value variant-selector and shouldn't have a "default" option.
Since they serve very different purposes, I suggest reviewing them separately and tried to come up with how I envision they should look to a reader.
They also differ in severity. (b) is going to be a very common case for most UI toolkits, including Gecko itself and in the future web components. (c) so far seems to serve an important, but a very rare case.
For that reason I'd like to focus on (b) and answer a question:
How would we design a single entity with an optional main value and multiple named additional "values".
I believe that we would name those named values "attributes" and design something like I proposed:
key = Value
key.attribute1 = Value 2
key.attribute2 = Value 3
> We struggled with those functions that don't actually return anything,
but that are just semantic sugar.
I envision that more as a smart-function that iterates over the variants and selects the first that matches.
> Also, as above, this moves content outside of the message value, which
causes grief on the tooling side.
I disagree that it moves content outside of the message value.
The (a) proposal moves the content back into the value, quite in line with your sentiment
The (b) keeps the separate value but makes it more readable - we can't move this content back into the main value because it's whole goal is to be a separate value
And the (c) is, imho, not content, it's meta-information, and as such cannot be part of the value.
It can annotate a value, or an entity. During brainstorm stas asked if it's possible to design it so that it annotates a single value.
We can look for a solution.
> I'm generally not too happy about the tagging piece, as I think it makes
it easier to get them wrong. Like, is "mazculine" a thing that's new or
a typo?
I'm pretty open to other proposals. I just believe that it's distinct enough from the other two uses (a and b) that it should not share the syntax with them.
If we agree on the new syntax for the other two, we're left with meta-infromation use case and we can keep it as-is, but that doesn't address the problem nr. 2 - that the trait syntax looks like variant syntax.
Regarding your concerns about typo. I'm not sure how is it different from making the same typo here:
key =
[gender] mazculine
The tools can aid by raising a warning if you use tags that don't match anything else, or help you design a list of tags applicable to your language and auto-suggest them.
I'm also open to brainstorm different syntax for the meta-information case than tags. Out of the three I'm least opinionated about it and I think there's no "natural" syntax for it like I believe there is for (a) and (b).
It seems to me that your concerns are most prominent with regards to the (c). I'd be happy to keep brainstorming that and separate out the other two parts of the proposal.
zb.