projectfluent / fluent

Fluent — planning, spec and documentation
https://projectfluent.org
Apache License 2.0
1.4k stars 45 forks source link

Allow selectors to be lists #4

Open stasm opened 7 years ago

stasm commented 7 years ago

Goal

Allow for alternative syntax for nested variants.

Description

Nested variants are currently hard to write and result in some repetition. ICU's experience with MessageFormat also suggests that it is easier for localizers to work with full sentences as variants.

The proposed solution is to allow lists as selectors in select-expression and as variant keys:

key = { $items, $buckets ->
  [one, one]     Found 1 item in 1 bucket.
  [one, other]   Found 1 item in { $buckets } buckets.
  [other, one]   Found { $items} items in 1 bucket.
  [other, other] Found { $items} items in { $buckets } buckets.
}

Dependencies

2, #3.

Discussion

https://groups.google.com/forum/#!topic/mozilla.tools.l10n/YBNCSp7J0zU

stasm commented 7 years ago

I've removed this issue from the 0.3 milestone. I'd like to release 0.3 shortly after 0.2 and I don't want to block it with this issue. It's something that we all agree is desirable but it's also pretty big in scope. As the proposal is backwards-compatible, we can add it in a future milestone—when we're ready.

gunchleoc commented 7 years ago

I agree that having full sentences is better, but that will only be workable if you need only a few of the rules - it's a lot of typing otherwise. So, as an option, great, but it should not be made mandatory. e.g. for gd we would get 4x4 = 16 entries for such a string.

stasm commented 6 years ago

The last time I talked to @zbraniecki about this, we considered the following syntax for list-typed variant keys:

key = { $items, $buckets ->
    [one][one] Found 1 item in 1 bucket.
    [one][other] Found 1 item in { $buckets } buckets.
    [other][one] Found { $items} items in 1 bucket.
   *[other][other] Found { $items} items in { $buckets } buckets.
}

It would be similar, but not equivalent, to the exploded version:

key = { $items ->
    [one] { $buckets ->
        [one] Found 1 item in 1 bucket.
       *[other] Found 1 item in { $buckets } buckets.
    }
   *[other] { $buckets ->
        [one] Found { $items} items in 1 bucket.
       *[other] Found { $items} items in { $buckets } buckets.
    }
}

The key difference between the two is that in the first one, [other][other] is the default value for any errors in either $items or $buckets while in the second one, $items can properly resolve to [one] if the only error is in $buckets.

A variant expression of the form key[var1][var2] could be used to access variants in both the flattened and the nested version. I'm not sure what should happen if there's a key conflict, however:

key = { $items ->
    [one][one] Found 1 item in 1 bucket.
    [one] { $buckets ->
        [one] Found 1 item in 1 bucket.
    }
    …
}
stasm commented 5 years ago

The syntax idea which I mentioned in https://github.com/projectfluent/fluent/issues/4#issuecomment-356001351 has drawbacks related to the whitespace relaxation (#87):

key = { $items, $buckets ->
    [one][one] Found 1 item in 1 bucket.
    [one][other] Found 1 item in { $buckets } buckets.
    [other][one] Found { $items} items in 1 bucket.
   *[other][other] Found { $items} items in { $buckets } buckets.
}

To stay consistent with the rest of the grammar, [one][other] should also be allowed to be written as [one]····[other] or even [one]\n[other] — at which point it looks much like two variants (even though it's not, because [one] needs a value to be a valid variant).

This leads me to strongly prefer the following syntax, which was made possible by #127:

key = { $items, $buckets ->
    [one, one] Found 1 item in 1 bucket.
    [one, other] Found 1 item in { $buckets } buckets.
    [other, one] Found { $items} items in 1 bucket.
    [other, other] Found { $items} items in { $buckets } buckets.
}

This, in turn, offers a use-case for #90, in which I proposed allowing StringLiterals as variant keys:

key = { $errorCode, $count ->
    ["0xDEADBEEF", one] One fatal error has occurred.
    …
}

If there are still reasons to consider the [one][one] syntax, we should make sure that it's possible to add it after 1.0 in a compatible manner. Forbidding [ as the first character of Patterns would be one way of doing it. Right now, [one][one] is valid syntax and parses as Variant {key: Identifier {name: "one"}, value: Pattern {elements: [TextElement {value: "one"}]}. I'm not fond of this solution, however, because it's not consistent with how the other special character, the dot (.), is only special in block_text, and allowed in inline_test.

stasm commented 5 years ago

If there are still reasons to consider the [one][one] syntax, we should make sure that it's possible to add it after 1.0 in a compatible manner.

I'm going to keep this issue untriaged for one more week to make sure I don't forget about this.