Skip to content

Commit 5065a51

Browse files
eemeliaphillipsstasm
authored
Use input and local keywords instead of let in declarations (#488)
Co-authored-by: Addison Phillips <[email protected]> Co-authored-by: Stanisław Małolepszy <[email protected]>
1 parent 977297c commit 5065a51

File tree

5 files changed

+88
-61
lines changed

5 files changed

+88
-61
lines changed

spec/data-model/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ interface SelectMessage {
4343
```
4444

4545
Each message _declaration_ is represented by a `Declaration`,
46-
which connects the `name` of the left-hand side _variable_
47-
with its right-hand side `value`.
46+
which connects the `name` of the _variable_
47+
with its _expression_ `value`.
4848
The `name` does not include the initial `$` of the _variable_.
4949

5050
```ts

spec/formatting.md

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ when formatting a message for display in a user interface, or for some later pro
77

88
To start, we presume that a _message_ has either been parsed from its syntax
99
or created from a data model description.
10-
If this construction has encountered any Syntax or Data Model errors,
10+
If this construction has encountered any Syntax or Data Model Errors,
1111
their handling during formatting is specified here as well.
1212

1313
Formatting of a _message_ is defined by the following operations:
@@ -67,7 +67,7 @@ At a minimum, it includes:
6767
This will be used by strategies for bidirectional isolation,
6868
and can be used to set the base direction of the _message_ upon display.
6969

70-
- A mapping of string identifiers to values,
70+
- An **_<dfn>input mapping</dfn>_** of string identifiers to values,
7171
defining variable values that are available during _variable resolution_.
7272
This is often determined by a user-provided argument of a formatting function call.
7373

@@ -83,11 +83,15 @@ Implementations MAY include additional fields in their _formatting context_.
8383

8484
_Expressions_ are used in _declarations_, _selectors_, and _patterns_.
8585

86-
In a _declaration_, the resolved value of the _expression_ is assigned to a _variable_,
86+
In a _declaration_, the resolved value of the _expression_ is bound to a _variable_,
8787
which is available for use by later _expressions_.
8888
Since a _variable_ can be referenced in different ways later,
8989
implementations SHOULD NOT immediately fully format the value for output.
9090

91+
In an _input-declaration_, the _variable_ operand of the _variable-expression_
92+
identifies not only the name of the external input value,
93+
but also the _variable_ to which the resolved value of the _variable-expression_ is bound.
94+
9195
In _selectors_, the resolved value of an _expression_ is used for _pattern selection_.
9296

9397
In a _pattern_, the resolved value of an _expression_ is used in its _formatting_.
@@ -106,7 +110,7 @@ and different implementations MAY choose to perform different levels of resoluti
106110
> Alternatively, it could be an instance of an ICU4J `FormattedNumber`,
107111
> or some other locally appropriate value.
108112
109-
Depending on the presence or absence of an _operand_
113+
Depending on the presence or absence of a _variable_ or _literal_ operand
110114
and a _function_, _private-use_, or _reserved_ _annotation_,
111115
the resolved value of the _expression_ is determined as follows:
112116
@@ -119,8 +123,7 @@ its resolved value is defined according to the implementation's specification.
119123
Else, if the _expression_ contains an _annotation_,
120124
its resolved value is defined by _function resolution_.
121125
122-
Else, the _expression_ will contain only an _operand_,
123-
which consists of either a _literal_ or a _variable_.
126+
Else, the _expression_ will contain only either a _literal_ or a _variable_.
124127
125128
If the _expression_ consists of a _variable_,
126129
its resolved value is defined by _variable resolution_.
@@ -150,9 +153,9 @@ its resolved value is defined by _literal resolution_.
150153
> an _annotation_ needs to be provided:
151154
>
152155
> ```
153-
> let $aNumber = {1234 :number}
154-
> let $aDate = {|2023-08-30| :datetime}
155-
> let $aFoo = {|some foo| :foo}
156+
> local $aNumber = {1234 :number}
157+
> local $aDate = {|2023-08-30| :datetime}
158+
> local $aFoo = {|some foo| :foo}
156159
> {You have {42 :number}}
157160
> ```
158161
@@ -175,13 +178,10 @@ The resolution of a _text_ or _literal_ token MUST always succeed.
175178
### Variable Resolution
176179
177180
To resolve the value of a _variable_,
178-
its _name_ is used to identify either a local variable,
179-
or a variable defined elsewhere.
180-
If a local variable and an externally defined one use the same name,
181-
the local variable takes precedence.
182-
183-
It is an error for a local variable definition to
184-
refer to a local variable that's defined after it in the message.
181+
its _name_ is used to identify either a local variable or an input variable.
182+
If a _declaration_ exists for the _variable_, its resolved value is used.
183+
Otherwise, the _variable_ is an implicit reference to an input value,
184+
and its value is looked up from the _formatting context_ _input mapping_.
185185
186186
The resolution of a _variable_ MAY fail if no value is identified for its _name_.
187187
If this happens, an Unresolved Variable error MUST be emitted.
@@ -272,12 +272,12 @@ rather than the _expression_ in the _selector_ or _pattern_.
272272
> attempting to format either of the following messages:
273273
>
274274
> ```
275-
> let $var = {|horse| :func}
275+
> local $var = {|horse| :func}
276276
> {The value is {$var}.}
277277
> ```
278278
>
279279
> ```
280-
> let $var = {|horse|}
280+
> local $var = {|horse|}
281281
> {The value is {$var :func}.}
282282
> ```
283283
>
@@ -690,7 +690,7 @@ These are divided into the following categories:
690690
> ```
691691
>
692692
> ```
693-
> let $var = {|no message body|}
693+
> local $var = {|no message body|}
694694
> ```
695695
696696
- **Data Model errors** occur when a message is invalid due to
@@ -744,16 +744,15 @@ These are divided into the following categories:
744744
> ```
745745
>
746746
> ```
747-
> let $one = {|The one|}
747+
> local $one = {|The one|}
748748
> match {$one}
749749
> when 1 {Value is one}
750750
> when * {Value is not one}
751751
> ```
752752
>
753753
> ```
754-
> let $one = {|The one| :func}
755-
> let $two = {$one}
756-
> match {$two}
754+
> input {$one}
755+
> match {$one}
757756
> when 1 {Value is one}
758757
> when * {Value is not one}
759758
> ```
@@ -769,7 +768,7 @@ These are divided into the following categories:
769768
> ```
770769
>
771770
> ```
772-
> let $foo = {horse :func one=1 two=2 one=1}
771+
> local $foo = {horse :func one=1 two=2 one=1}
773772
> {This is {$foo}}
774773
> ```
775774
@@ -844,7 +843,7 @@ These are divided into the following categories:
844843
> ```
845844
>
846845
> ```
847-
> let $sel = {|horse| :plural}
846+
> local $sel = {|horse| :plural}
848847
> match {$sel}
849848
> when 1 {The value is one.}
850849
> when * {The value is not one.}
@@ -873,7 +872,7 @@ These are divided into the following categories:
873872
> ```
874873
>
875874
> ```
876-
> let $id = {$user :get field=id}
875+
> local $id = {$user :get field=id}
877876
> {Hello, {$id :get field=name}!}
878877
> ```
879878
>

spec/message.abnf

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
message = [s] *(declaration [s]) body [s]
22

3-
declaration = let s variable [s] "=" [s] expression
3+
declaration = input-declaration / local-declaration
4+
input-declaration = input [s] variable-expression
5+
local-declaration = local s variable [s] "=" [s] expression
6+
47
body = pattern
58
/ (selectors 1*([s] variant))
69

@@ -9,8 +12,10 @@ selectors = match 1*([s] expression)
912
variant = when 1*(s key) [s] pattern
1013
key = literal / "*"
1114

12-
expression = "{" [s] ((operand [s annotation]) / annotation) [s] "}"
13-
operand = literal / variable
15+
expression = literal-expression / variable-expression / function-expression
16+
literal-expression = "{" [s] literal [s annotation] [s] "}"
17+
variable-expression = "{" [s] variable [s annotation] [s] "}"
18+
function-expression = "{" [s] annotation [s] "}"
1419
annotation = (function *(s option)) / reserved / private-use
1520

1621
literal = quoted / unquoted
@@ -19,7 +24,8 @@ function = (":" / "+" / "-") name
1924
option = name [s] "=" [s] (literal / variable)
2025

2126
; reserved keywords are always lowercase
22-
let = %x6C.65.74 ; "let"
27+
input = %x69.6E.70.75.74 ; "input"
28+
local = %x6C.6F.63.61.6C ; "local"
2329
match = %x6D.61.74.63.68 ; "match"
2430
when = %x77.68.65.6E ; "when"
2531

spec/registry.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,5 +184,5 @@ which expects the `plural` and `case` options:
184184
The following message references the second signature of `:adjective`,
185185
which only expects the `accord` option:
186186

187-
let $obj = {$object :noun case=nominative}
188-
{You see {$color :adjective article=indefinite accord=$obj} {$obj}!}
187+
input {$object :noun case=nominative}
188+
{You see {$color :adjective article=indefinite accord=$object} {$object}!}

spec/syntax.md

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,12 @@ The complete formal syntax of a _message_ is described by the [ABNF](./message.a
8585
### Well-formed vs. Valid Messages
8686

8787
A _message_ is **_<dfn>well-formed</dfn>_** if it satisfies all the rules of the grammar.
88+
Attempting to parse a _message_ that is not _well-formed_ will result in a _Syntax Error_.
8889

89-
A _message_ is **_<dfn>valid</dfn>_** if it is _well-formed_ and **also** meets the additional content restrictions
90+
A _message_ is **_<dfn>valid</dfn>_** if it is _well-formed_ and
91+
**also** meets the additional content restrictions
9092
and semantic requirements about its structure defined below.
93+
Attempting to parse a _message_ that is not _valid_ will result in a _Data Model Error_.
9194

9295
## The Message
9396

@@ -108,14 +111,14 @@ A **_<dfn>message</dfn>_** is the complete template for a specific message forma
108111
> > **Example** This _message_:
109112
> >
110113
> > ```
111-
> > let $foo = { |horse| }
114+
> > local $foo = { |horse| }
112115
> > {You have a {$foo}!}
113116
> > ```
114117
> >
115118
> > Can also be written as:
116119
> >
117120
> > ```
118-
> > let $foo={|horse|}{You have a {$foo}!}
121+
> > local $foo={|horse|}{You have a {$foo}!}
119122
> > ```
120123
> >
121124
> > An exception to this is: whitespace inside a _pattern_ is **always** significant.
@@ -127,12 +130,27 @@ A _message_ consists of two parts:
127130
128131
### Declarations
129132
130-
A **_<dfn>declaration</dfn>_** binds a _variable_ identifier to the value of an _expression_ within the scope of a _message_.
131-
This local variable can then be used in other _expressions_ within the same _message_.
133+
A **_<dfn>declaration</dfn>_** binds a _variable_ identifier to a value within the scope of a _message_.
134+
This _variable_ can then be used in other _expressions_ within the same _message_.
132135
_Declarations_ are optional: many messages will not contain any _declarations_.
133136
137+
An **_<dfn>input-declaration</dfn>_** binds a _variable_ to an external input value.
138+
The _variable-expression_ of an _input-declaration_
139+
MAY include an _annotation_ that is applied to the external value.
140+
141+
A **_<dfn>local-declaration</dfn>_** binds a _variable_ to the resolved value of an _expression_.
142+
143+
Declared _variables_ MUST NOT be used before their _declaration_,
144+
and their values MUST NOT be self-referential;
145+
otherwise, a _message_ is not considered _valid_.
146+
147+
Multiple _declarations_ MUST NOT bind a value to the same _variable_;
148+
otherwise, a _message_ is not considered _valid_.
149+
134150
```abnf
135-
declaration = let s variable [s] "=" [s] expression
151+
declaration = input-declaration / local-declaration
152+
input-declaration = input [s] variable-expression
153+
local-declaration = local s variable [s] "=" [s] expression
136154
```
137155
138156
### Body
@@ -335,30 +353,39 @@ during the _message_'s formatting.
335353
An _expression_ MUST begin with U+007B LEFT CURLY BRACKET `{`
336354
and end with U+007D RIGHT CURLY BRACKET `}`.
337355
An _expression_ MUST NOT be empty.
338-
An _expression_ can contain an _operand_,
339-
an _annotation_,
340-
or an _operand_ followed by an _annotation_.
356+
357+
A **_<dfn>literal-expression</dfn>_** contains a _literal_,
358+
optionally followed by an _annotation_.
359+
360+
A **_<dfn>variable-expression</dfn>_** contains a _variable_,
361+
optionally followed by an _annotation_.
362+
363+
A **_<dfn>function-expression</dfn>_** contains only an _annotation_.
341364

342365
```abnf
343-
expression = "{" [s] ((operand [s annotation]) / annotation) [s] "}"
344-
operand = literal / variable
366+
expression = literal-expression / variable-expression / function-expression
367+
literal-expression = "{" [s] literal [s annotation] [s] "}"
368+
variable-expression = "{" [s] variable [s annotation] [s] "}"
369+
function-expression = "{" [s] annotation [s] "}"
345370
annotation = (function *(s option)) / private-use / reserved
346371
```
347372

348373
There are several types of _expression_ that can appear in a _message_.
349374
All _expressions_ share a common syntax. The types of _expression_ are:
350375

351-
1. The value of a _declaration_
376+
1. The value of a _local-declaration_
352377
2. A _selector_
353378
3. A _placeholder_ in a _pattern_
354379

380+
Additionally, an _input-declaration_ can contain a _variable-expression_.
381+
355382
> Examples of different types of _expression_
356383
>
357384
> Declarations:
358385
>
359386
> ```
360-
> let $x = {|This is an expression|}
361-
> let $y = {$operand :function option=operand}
387+
> input {$x :function option=value}
388+
> local $y = {|This is an expression|}
362389
> ```
363390
>
364391
> Selectors:
@@ -375,15 +402,6 @@ All _expressions_ share a common syntax. The types of _expression_ are:
375402
> {This placeholder references a function on a variable: {$variable :function with=options}}
376403
> ```
377404
378-
### Operand
379-
380-
An **_<dfn>operand</dfn>_** is a _literal_ or a _variable_ to be evaluated in an _expression_.
381-
An _operand_ MAY optionally be followed by an _annotation_.
382-
383-
```abnf
384-
operand = literal / variable
385-
```
386-
387405
### Annotation
388406
389407
An **_<dfn>annotation</dfn>_** is part of an _expression_ containing either
@@ -394,6 +412,9 @@ a _private-use_ or _reserved_ sequence.
394412
annotation = (function *(s option)) / reserved / private-use
395413
```
396414
415+
An **_<dfn>operand</dfn>_** is the _literal_ of a _literal-expression_ or
416+
the _variable_ of a _variable-expression_.
417+
397418
An _annotation_ can appear in an _expression_ by itself or following a single _operand_.
398419
When following an _operand_, the _operand_ serves as input to the _annotation_.
399420

@@ -570,11 +591,12 @@ This section defines common elements used to construct _messages_.
570591

571592
A **_<dfn>keyword</dfn>_** is a reserved token that has a unique meaning in the _message_ syntax.
572593

573-
The following three keywords are reserved: `let`, `match`, and `when`.
594+
The following four keywords are reserved: `input`, `local`, `match`, and `when`.
574595
Reserved keywords are always lowercase.
575596

576597
```abnf
577-
let = %x6C.65.74 ; "let"
598+
input = %x69.6E.70.75.74 ; "input"
599+
local = %x6C.6F.63.61.6C ; "local"
578600
match = %x6D.61.74.63.68 ; "match"
579601
when = %x77.68.65.6E ; "when"
580602
```
@@ -583,9 +605,9 @@ when = %x77.68.65.6E ; "when"
583605

584606
A **_<dfn>literal</dfn>_** is a character sequence that appears outside
585607
of _text_ in various parts of a _message_.
586-
A _literal_ can appear in a _declaration_,
608+
A _literal_ can appear
587609
as a _key_ value,
588-
as an _operand_,
610+
as the _operand_ of a _literal-expression_,
589611
or in the value of an _option_.
590612
A _literal_ MAY include any Unicode code point
591613
except for surrogate code points U+D800 through U+DFFF.

0 commit comments

Comments
 (0)