Skip to content
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9520b5d
Create 0483-beauty-contest.md
aphillips Sep 25, 2023
7f5503b
style: Apply Prettier
github-actions[bot] Sep 25, 2023
48c110c
Update 0483-beauty-contest.md
aphillips Sep 26, 2023
bac6a65
style: Apply Prettier
github-actions[bot] Sep 26, 2023
4529da2
tweaks to single-line
aphillips Sep 26, 2023
95fb27e
Update 0483-beauty-contest.md
aphillips Sep 26, 2023
b4da4f6
Update exploration/0483-beauty-contest.md
aphillips Sep 27, 2023
b375e67
More examples
aphillips Sep 27, 2023
4419aa2
style: Apply Prettier
github-actions[bot] Sep 27, 2023
2c0d5d2
Update 0483-beauty-contest.md
aphillips Sep 27, 2023
3659bd9
Add Mihai's example
aphillips Oct 2, 2023
52ee4ef
style: Apply Prettier
github-actions[bot] Oct 2, 2023
eee521d
Refining layout
aphillips Oct 4, 2023
e847a93
style: Apply Prettier
github-actions[bot] Oct 4, 2023
51b5443
typo...
aphillips Oct 4, 2023
03cfaae
Rename 0483-beauty-contest.md to beauty-contest.md
aphillips Oct 9, 2023
bf7bf00
Start implementing whitespace decision
aphillips Oct 9, 2023
c0baa8f
Add option 1a, fix mistakes in option 0
eemeli Oct 10, 2023
6e8f4ad
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
c4d91c7
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
ed139a7
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
c7782c7
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
4870430
style: Apply Prettier
github-actions[bot] Oct 10, 2023
5299aac
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
c3d7b35
style: Apply Prettier
github-actions[bot] Oct 10, 2023
d8f161d
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
f0b42d7
Fix contestant 4
aphillips Oct 10, 2023
e04aef6
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
b4af5ca
Update exploration/beauty-contest.md
aphillips Oct 10, 2023
ec18300
Add 3a per slack conversation
aphillips Oct 11, 2023
ff67c9c
style: Apply Prettier
github-actions[bot] Oct 11, 2023
69ec709
Add feature description table
aphillips Oct 11, 2023
50617d5
style: Apply Prettier
github-actions[bot] Oct 11, 2023
daa7920
Update exploration/beauty-contest.md
aphillips Oct 11, 2023
cd8e69b
Update exploration/beauty-contest.md
aphillips Oct 11, 2023
7d412d6
Update exploration/beauty-contest.md
aphillips Oct 11, 2023
097980d
Update exploration/beauty-contest.md
aphillips Oct 11, 2023
1993659
Merge branch 'main' into aphillips-beauty-contest
eemeli Oct 11, 2023
b2960f4
Update exploration/beauty-contest.md
aphillips Oct 11, 2023
a06bfd1
Update exploration/beauty-contest.md
aphillips Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
384 changes: 384 additions & 0 deletions exploration/beauty-contest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,384 @@
# Syntax Variation Beauty Contest

As discussed in the 2023-09-25 teleconference, we need to choose a syntax to proceed with.
This page hosts various options for considering in the 2023-10-02 call.

## Shorthand description of some aspects of the options

Please dispute factual errors in this. The table uses multiple `-` when an option requires more than one of something. `+` is not weighted.

| Option | Description | Doesn’t Nest {} | Doesn’t Need More Escapes | Doesn’t Require Quoted Pattern | Allows Unquoted Literal Operands | Counted {} works | Adds no sigils |
| :----- | :------------------------------------------------------------- | :-------------- | :------------------------ | :----------------------------- | :------------------------------- | :--------------- | :------------- |
| 0 | Current syntax, starts in code mode | - | + | -- | + | - | + |
| 1 | Invert for text mode | - | + | + | - | + | + |
| 1a | Invert for text mode, distinguish statements from placeholders | - | + | + | + | + | - |
| 2 | Text first, but always code mode after code | - | + | - | - | + | + |
| 3 | Use sigils for code mode | + | - | + | + | + | -- |
| 3a | Use sigils for code mode, use {/} for keys | + | - | + | + | + | - |
| 4 | Reducing keywords | + | --- | + | + | + | --- |
| 5 | Use blocks for declarations and body | -- | - | + | - | - | - |
| 5a | Use blocks for declarations but sigils for selectors | + | -- | + | - | - | - |
| 6 | Use statements | -- | --- | + | + | + | - |

## 0. Current

This is the current syntax,
including the changes introduced in [#488](https://github.com/unicode-org/message-format-wg/pull/488).
The list of messages in this section also serves as the basis for all other examples.

```
{Hello world!}

{Hello {$user}}

input {$var :function option=value}
{Hello {$var}}

input {$var :function option=value}
local $foo = {$bar :function option=value}
{Hello {$var}, you have a {$foo}}

match {$foo} {$bar}
when foo bar {Hello {$foo} you have a {$var}}
when * * {{$foo} hello you have a {$var}}

match {$foo :function option=value} {$bar :function option=value}
when a b { {$foo} is {$bar} }
when x y { {$foo} is {$bar} }
when * * { {$foo} is {$bar} }

input {$var :function option=value} local $foo = {$bar :function option=value}{Hello {$var}, you have a {$foo}}

match {$foo} {$bar} when foo bar {Hello {$foo} you have a {$var}} when * * {{$foo} hello you have a {$var}}

match {$foo :function option=value} {$bar :function option=value}when a b { {$foo} is {$bar} }when x y { {$foo} is {$bar} }when * * { {$foo} is {$bar} }
```

## 1. Invert for Text Mode

Consumes exterior whitespace.

Requires dropping unquoted literal operands from the syntax.

```
Hello world!

Hello {$user}

{input $var :function option=value}
Hello {$var}

{input $var :function option=value}
{local $foo = $bar :function option=value}
Hello {$var}, you have a {$foo}

{match {$foo} {$bar}}
{when foo bar} Hello {$foo} you have a {$var}
{when * *} {$foo} hello you have a {$var}

{match {$foo :function option=value} {$bar :function option=value}}
{when a b} {{ {$foo} is {$bar} }}
{when x y} {{ {$foo} is {$bar} }}
{when * *} {| |}{$foo} is {$bar}{| |}

{input $var :function option=value}{local $foo = $bar :function option=value}Hello {$var}, you have a {$foo}

{match {$foo} {$bar}}{when foo bar} Hello {$foo} you have a {$var}{when * *} {$foo} hello you have a {$var}

{match {$foo :function option=value}{$bar :function option=value}}{when a b} {{ {$foo} is {$bar} }}{when x y} {{ {$foo} is {$bar} }}{when * *} {| |}{$foo} is {$bar}{| |}
```

## 1a. Invert for Text Mode, distinguish statements from placeholders

Same as 1, but non-placeholder statements use a `#` prefix.
This allows us to keep unquoted literal syntax.

```
Hello world!

Hello {$user}

{#input $var :function option=value}
Hello {$var}

{#input $var :function option=value}
{#local $foo = $bar :function option=value}
Hello {$var}, you have a {$foo}

{#match {$foo} {$bar}}
{#when foo bar} Hello {$foo} you have a {$var}
{#when * *} {$foo} hello you have a {$var}

{#match {$foo :function option=value} {$bar :function option=value}}
{#when a b} {{ {$foo} is {$bar} }}
{#when x y} {{ {$foo} is {$bar} }}
{#when * *} {| |}{$foo} is {$bar}{| |}

{#input $var :function option=value} {#local $foo = $bar :function option=value} Hello {$var}, you have a {$foo}

{#match {$foo} {$bar}} {#when foo bar} Hello {$foo} you have a {$var} {#when * *} {$foo} hello you have a {$var}

{#match {$foo :function option=value}{$bar :function option=value}} {#when a b} {{ {$foo} is {$bar} }} {#when x y} {{ {$foo} is {$bar} }} {#when * *} {| |}{$foo} is {$bar}{| |}
```

## 2. Text First, but Always Code After Code-Mode

This is @mihnita's proposal, mentioned in the 2023-10-02 call.
Start in text mode, but stay in code mode once you get there.
Adapted @eemeli's start-in-text-mode syntax for these examples.

Requires dropping unquoted literal operands from the syntax.

```
Hello world!

Hello {$user}

{input $var :function option=value}
{{Hello {$var}}}

{input $var :function option=value}
{local $foo = $bar :function option=value}
{{Hello {$var}, you have a {$foo}}}

{match {$foo} {$bar}}
{when foo bar} {{Hello {$foo} you have a {$var}}}
{when * *} {{{$foo} hello you have a {$var}}}

{match {$foo :function option=value} {$bar :function option=value}}
{when a b} {{ {$foo} is {$bar} }}
{when x y} {{ {$foo} is {$bar} }}

{input $var :function option=value}{local $foo = $bar :function option=value}{{Hello {$var}, you have a {$foo}}}

{match {$foo} {$bar}}{when foo bar} {{Hello {$foo} you have a {$var}}}{when * *}{{{$foo} hello you have a {$var}}}

{match {$foo :function option=value}{$bar :function option=value}}{when a b} { {$foo} is {$bar} }{when x y} { {$foo} is {$bar} }
```

## 3. Use sigils for code mode

Try to redues the use of `{`/`}` to just expressions and placeholders instead of the three
uses we have now (the other use is for patterns). This requires escaping whitespace or using
a placeholder for it.
See [#487](https://github.com/unicode-org/message-format-wg/pull/487) for a discussion of whitespace options.

The sigil `#` was chosen because `#define` type constructs are fairly common.
Introduces `[`/`]` for keys.

Requires escaping `#` when used as a pattern character.

```
#input {$var :function option=value}
Hello {$var}

#input {$var :function option=value}
#local $foo = {$bar :function option=value}
Hello {$var}, you have a {$foo}

#match {$foo} {$bar}
#when[foo bar] Hello {$foo} you have a {$var}
#when[ * *] {$foo} hello you have a {$var}

#match {$foo :function option=value} {$bar :function option=value}
#when [a b] {{ {$foo} is {$bar} }}
#when [x y] {||} {$foo} is {$bar} {||}
#when [* *] {| |}{$foo} is {$bar}{| |}

#input {$var :function option=value}#local $foo = {$bar :function option=value}Hello {$var}, you have a {$foo}

#match {$foo} {$bar}#when[foo bar] Hello {$foo} you have a {$var}#when[* *] {$foo} hello you have a {$var}

#match {$foo :function option=value} {$bar :function option=value}#when [a b] {{ {$foo} is {$bar} }} #when [x y] {||} {$foo} is {$bar} {||}#when [* *] {| |}{$foo} is {$bar}{| |}
```

## 3a. Use sigils for code mode, use `{`/`}` for keys

Similar to 3, but uses braces instead of `[`/`]` square brackets for keys, reducing variation and
the need for additional pattern escapes.
See Slack thread.

Requires `#` to be escaped in unquoted patterns.

```
#input {$var :function option=value}
Hello {$var}

#input {$var :function option=value}
#local $foo = {$bar :function option=value}
Hello {$var}, you have a {$foo}

#match {$foo} {$bar}
#when{foo bar} Hello {$foo} you have a {$var}
#when{ * *} {$foo} hello you have a {$var}

#match {$foo :function option=value} {$bar :function option=value}
#when {a b} {{ {$foo} is {$bar} }}
#when {x y} {||} {$foo} is {$bar} {||}
#when {* *} {| |}{$foo} is {$bar}{| |}

#input {$var :function option=value}#local $foo = {$bar :function option=value}Hello {$var}, you have a {$foo}

#match {$foo} {$bar}#when{foo bar} Hello {$foo} you have a {$var}#when{* *} {$foo} hello you have a {$var}

#match {$foo :function option=value} {$bar :function option=value}#when{a b}{{ {$foo} is {$bar} }} #when{x y}{||} {$foo} is {$bar} {||}#when{* *}{| |}{$foo} is {$bar}{| |}
```

## 4. Reducing keywords

Avoids keywords in favor of sigil based parsing.
The theory here is that the syntactic sugar of `match` and `when` are nice the first time you use them
but the benefit is lost or reduced after that.

Uses double or paired sigils to reduce the need for escaping common characters (such as `?`)

Requires escaping `#` in a pattern.
Requires escaping `??` at the start of a pattern.
Requires escaping `::[` in a pattern.

```
#{$var :function option=value}
Hello {$var}

#{$var :function option=value}
#$foo = {$bar :function option=value}
Hello {$var}, you have a {$foo}

?? {$foo} {$bar}
::[ foo bar] Hello {$foo} you have a {$var}
::[ * *] {$foo} hello you have a {$var}

?? {$foo :function option=value} {$bar :function option=value}
::[a b] {{ {$foo} is {$bar} }}
::[x y] {{ {$foo} is {$bar} }}
::[* *] {| |}{$foo} is {$bar}{| |}

#{$var :function option=value}#$foo = {$bar :function option=value}Hello {$var}, you have a {$foo}

??{$foo}{$bar}::[foo bar] Hello {$foo} you have a {$var}::[* *] {$foo} hello you have a {$var}

??{$foo :function option=value}{$bar :function option=value}::[a b] { {$foo} is {$bar} }::[x y] { {$foo} is {$bar} }::[* *] {| |}{$foo} is {$bar}{| |}
```

## 5. Use "blocks" for declarations and body

Use code-mode "blocks" to introduce code. _(This section has an additional example)_

The theory here is that a "declarations block" would be a natural add-on and it doesn't
require additional typing for each declaration.

Note too that this syntax could be extended to allow other types of blocks,
such as comments or different types of statement.

Requires escaping `[` when used as a pattern character in an unquoted pattern.

```
{#
input {$var :function option=value}
}
Hello {$var}

// might be more natural as:
{#input {$var :function option=value}}
Hello {$var}

{#
input {$var :function option=value}
local $foo = {$bar :function option=value}
}
Hello {$var}, you have a {$foo}

{#
match {$foo} {$bar}
[ foo bar] Hello {$foo} you have a {$var}
[ * *] {$foo} hello you have a {$var}
}

{#
input $foo :function option=value
}{
Comment on lines +298 to +299
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm presuming from the preceding example that the match statement may also go in the block. Or does it need a separate block, and does that also start with {#?

Suggested change
input $foo :function option=value
}{
input $foo :function option=value

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original theory was: "declaration block" and "body block". The body block only needs to be bracketed when it contains code (i.e. a match). There's no reason to have blocks if they aren't separate (that would just be option 2 then)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok. Then I think lines 257 and 259 may need fixing, because together with this we've got all of:

  • { match
  • {#match
  • match

I can't tell which of these three is the proposed syntax here.

match {$foo :function option=value} {$bar :function option=value}
[a b] {{ {$foo} is {$bar} }}
[x y] {{ {$foo} is {$bar} }}
[* *] {| |}{$foo} is {$bar}{| |}
}

{#input {$var :function option=value}}Hello {$var}

{#input {$var :function option=value} local $foo = {$bar :function option=value}}Hello {$var}, you have a {$foo}

{#match {$foo} {$bar}[foo bar] Hello {$foo} you have a {$var}[* *] {$foo} hello you have a {$var}}

{#input {$foo :function option=value}match {$foo :function option=value} {$bar :function option=value}[a b] {{ {$foo} is {$bar} }}[x y] {{ {$foo} is {$bar} }}[* *] {| |}{$foo} is {$bar}{| |}}
```

## 5a. Declaration block but sigils for selectors

Start in text mode.
Enclose declarations in a block.
Use a sigil for `match` selector.

Requires escaping `[` when used as a pattern character,
and the sequence `#match` when used at the start of a pattern.

```
{# input $var :function option=value}
Hello {$var}

{# input $var :function option=value
local $foo = {$bar :function option=value}
}
Hello {$var}, you have a {$foo}

#match {$foo :function option=value} {$bar :function option=value}
[a b] {$foo} is {$bar}
[x y] {$foo} is {$bar}
[* *] {$foo} is {$bar}

{#input $foo :function option=value
local $baz = {|some annotation|}}
#match {$foo} {$bar :function}
[a b] {$foo} is {$bar}
[x y] {$foo} is {$bar}
[* *] {$foo} is {$bar}
```

## 6. Use "statements"

Many languages delimit statements using a terminator, such as `;`.
In some languages, the terminator is the newline and lines can be extended using an escape like `\`.
Here we use `;` as a terminator.
Note that the closing `;` on `match` might be optional.

Defining a statement syntax might allow us to introduce different types of selectors in future versions,
such as looping constructs.

Requires escaping the word `when` and the character `;` in a pattern,
and the character `#` when used at the start of a pattern.

```
#input {$var :function option=value};
Hello {$var}

#input {$var :function option=value};
#local $foo = {$bar :function option=value};
Hello {$var}, you have a {$foo}

#match {$foo} {$bar}
when [ foo bar] Hello {$foo} you have a {$var}
when [ * *] {$foo} hello you have a {$var}
;

#match {$foo :function option=value} {$bar :function option=value}
when [a b] { {$foo} is {$bar} }
when [x y] { {$foo} is {$bar} }
when [* *] {| |}{$foo} is {$bar}{| |}
;

#input {$var :function option=value};#local $foo = {$bar :function option=value};Hello {$var}, you have a {$foo}

#match {$foo}{$bar}when [foo bar] Hello {$foo} you have a {$var}when [* *] {$foo} hello you have a {$var};

#match {$foo :function option=value}{$bar :function option=value}when [a b] { {$foo} is {$bar} }when[x y] { {$foo} is {$bar} }when[* *] {| |}{$foo} is {$bar}{| |};

```