From e3f8a3bfe71044c494b9267b11e4d2d0da2cf0f1 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Thu, 22 Feb 2024 16:26:07 -0800 Subject: [PATCH 01/17] Add note to "Function Resolution" section about function argument and result types --- spec/formatting.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/formatting.md b/spec/formatting.md index 17b2abfd79..9b7ec7ed94 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -222,6 +222,11 @@ the following steps are taken: The form that resolved _operand_ and _option_ values take is implementation-defined. + Since the result of a function call can be bound to a _variable_, + the output of one _function_ may be the input of another _function_. + Thus, formatting functions SHOULD use a structure for the resolved _operand_ value + that is interconvertible with the structure for the result of the _function_. + An implementation MAY pass additional arguments to the function, as long as reasonable precautions are taken to keep the function interface simple and minimal, and avoid introducing potential security vulnerabilities. From eb397b1a5980c9c6c076d1dc345a362405e3f3a3 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 26 Feb 2024 12:21:26 -0800 Subject: [PATCH 02/17] Rephrase the 'result of a function call' sentence --- spec/formatting.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 9b7ec7ed94..487ef24257 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -222,8 +222,10 @@ the following steps are taken: The form that resolved _operand_ and _option_ values take is implementation-defined. - Since the result of a function call can be bound to a _variable_, - the output of one _function_ may be the input of another _function_. + A _local-declaration_ binds the resolved value of an _expression_ + to a _variable_. + Thus, the output of one _function_ is potentially the _operand_ + of another _function_. Thus, formatting functions SHOULD use a structure for the resolved _operand_ value that is interconvertible with the structure for the result of the _function_. From 9024a5b5097ff8ca55b813c03c72fc251e706753 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 26 Feb 2024 12:48:12 -0800 Subject: [PATCH 03/17] Rewrite the description of "composability" Avoid using the word "interconvertible" Include example of composability Include example for how the function interface would be defined in a typed implementation language Add note about multiple interpretations of composition that requests feedback --- spec/formatting.md | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 487ef24257..17ca8e1460 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -225,9 +225,49 @@ the following steps are taken: A _local-declaration_ binds the resolved value of an _expression_ to a _variable_. Thus, the output of one _function_ is potentially the _operand_ - of another _function_. - Thus, formatting functions SHOULD use a structure for the resolved _operand_ value - that is interconvertible with the structure for the result of the _function_. + of another _function_. In other words, formatting functions + compose with each other. + For example, in + ``` + .input {$n :number minIntegerDigits=3} + .local {$n1 :number maxFractionDigits=3} + ``` + the second call to `:number` composes with the first call. + + Implementations SHOULD provide a means for formatting functions + to compose with each other. + Implementations that provide a means for defining custom functions + SHOULD provide a means for those functions to return values + that contain enough information + (e.g. the resolved _operand_ and _option_ values + that the function was called with) + to be used as inputs to subsequent function calls. + For example, an implementation in a typed programming language + MAY define an interface that custom functions implement. + Such an interface SHOULD define an implementation-specific + argument type `T` and return type `U` for custom functions + such that `U` can be coerced to `T` without loss of information. + +> [!NOTE] +> In the Tech Preview, the spec leaves the behavior of the previous +> example implementation-dependent. Supposing that +> the external input variable `n` is bound to the string `"1"`, +> and that the implementation formats to a string, +> the formatted result of the following message: +> +> ``` +> .input {$n :number minIntegerDigits=3} +> .local {$n1 :number maxFractionDigits=3} +> {{$n1}} +> ``` +> +> is implementation-dependent. +> Depending on whether the options are preserved across +> the two calls to `:number`, a conformant implementation +> could produce either "001.000" or "1.000" +> Feedback from users and implementers is desired +> about whether to require one interpretation or the other +> in the spec. An implementation MAY pass additional arguments to the function, as long as reasonable precautions are taken to keep the function interface From 2c7aaebb7eacbab3b8d868f8209f14cce4474f40 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Mon, 26 Feb 2024 12:52:03 -0800 Subject: [PATCH 04/17] Add specific text on selector functions --- spec/formatting.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 17ca8e1460..ce0c06b264 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -234,8 +234,13 @@ the following steps are taken: ``` the second call to `:number` composes with the first call. + In addition, selector functions compose with formatting functions + in the sense that a selector function's _operand_ + may be the output of any formatting function. + Implementations SHOULD provide a means for formatting functions - to compose with each other. + to compose with each other + and for formatting functions to compose with selector functions. Implementations that provide a means for defining custom functions SHOULD provide a means for those functions to return values that contain enough information @@ -245,8 +250,11 @@ the following steps are taken: For example, an implementation in a typed programming language MAY define an interface that custom functions implement. Such an interface SHOULD define an implementation-specific - argument type `T` and return type `U` for custom functions + argument type `T` and return type `U` for custom formatting functions such that `U` can be coerced to `T` without loss of information. + The type `U` + (or a type that `U` can be coerced to without loss of information) + SHOULD also be the input type of custom selector functions. > [!NOTE] > In the Tech Preview, the spec leaves the behavior of the previous From 9353c1f8db1a75aa95b04d25cb4622f806564fc5 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 09:54:31 -0800 Subject: [PATCH 05/17] Fix .local syntax in example --- spec/formatting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index ce0c06b264..07c722b490 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -230,7 +230,7 @@ the following steps are taken: For example, in ``` .input {$n :number minIntegerDigits=3} - .local {$n1 :number maxFractionDigits=3} + .local $n1 = {$n :number maxFractionDigits=3} ``` the second call to `:number` composes with the first call. From 5803dd8f0ad074cff3fc5f2aa847f3989f1f4a05 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 10:37:06 -0800 Subject: [PATCH 06/17] Address various review comments --- spec/formatting.md | 61 ++++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 07c722b490..1ccdb34608 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -225,40 +225,41 @@ the following steps are taken: A _local-declaration_ binds the resolved value of an _expression_ to a _variable_. Thus, the output of one _function_ is potentially the _operand_ - of another _function_. In other words, formatting functions - compose with each other. + of another _function_, + or the value of one of the _options_ for another function. For example, in ``` .input {$n :number minIntegerDigits=3} .local $n1 = {$n :number maxFractionDigits=3} ``` - the second call to `:number` composes with the first call. + the output of the first call to `:number` + is the input of the second call to `:number`. - In addition, selector functions compose with formatting functions - in the sense that a selector function's _operand_ - may be the output of any formatting function. - - Implementations SHOULD provide a means for formatting functions - to compose with each other - and for formatting functions to compose with selector functions. Implementations that provide a means for defining custom functions - SHOULD provide a means for those functions to return values - that contain enough information + SHOULD provide a means for function implementations + to return values that contain enough information (e.g. the resolved _operand_ and _option_ values that the function was called with) - to be used as inputs to subsequent function calls. - For example, an implementation in a typed programming language - MAY define an interface that custom functions implement. + to be used as arguments to subsequent calls + to the function implementations. + For example, a MessageFormat implementation in a typed programming language + MAY define an interface for custom function implementations. Such an interface SHOULD define an implementation-specific - argument type `T` and return type `U` for custom formatting functions + argument type `T` and return type `U` + for implementations of formatting functions such that `U` can be coerced to `T` without loss of information. The type `U` (or a type that `U` can be coerced to without loss of information) - SHOULD also be the input type of custom selector functions. + SHOULD also be the input type of implementations of + custom selector functions. + Implementations of specific functions MAY + signal errors if supplied an _operand_ that + does not make sense for the particular function + being implemented. > [!NOTE] -> In the Tech Preview, the spec leaves the behavior of the previous -> example implementation-dependent. Supposing that +> The behavior of the previous example is +> implementation-dependent. Supposing that > the external input variable `n` is bound to the string `"1"`, > and that the implementation formats to a string, > the formatted result of the following message: @@ -270,12 +271,24 @@ the following steps are taken: > ``` > > is implementation-dependent. -> Depending on whether the options are preserved across -> the two calls to `:number`, a conformant implementation +> Depending on whether the options are preserved +> between the resolution of the first `:number` _annotation_ +> and the resolution of the second `:number` _annotation_, +> a conformant implementation > could produce either "001.000" or "1.000" -> Feedback from users and implementers is desired -> about whether to require one interpretation or the other -> in the spec. +> +> Each function implementation MAY have +> its own rules to preserve some options in the returned structure +> and discard others. +> +> +> [!NOTE] +> During the Technical Preview, +> feedback on how the registry describes +> the flow of _resolved values_ and _options_ +> from one _function_ to another, +> and on what requirements this specification should impose, +> is highly desired. An implementation MAY pass additional arguments to the function, as long as reasonable precautions are taken to keep the function interface From 0f41bfc89921daa09d36dd755c22d512fb3facda Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 11:24:04 -0800 Subject: [PATCH 07/17] Update spec/formatting.md Co-authored-by: Richard Gibson --- spec/formatting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index 1ccdb34608..33c637f58a 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -266,7 +266,7 @@ the following steps are taken: > > ``` > .input {$n :number minIntegerDigits=3} -> .local {$n1 :number maxFractionDigits=3} +> .local $n1 = {$n :number maxFractionDigits=3} > {{$n1}} > ``` > From 6e7d1c2a5065ae8073caa94df8d1d2a757781e4a Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:21:28 -0800 Subject: [PATCH 08/17] Update spec/formatting.md Co-authored-by: Eemeli Aro --- spec/formatting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index 33c637f58a..9f24574bdc 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -222,7 +222,7 @@ the following steps are taken: The form that resolved _operand_ and _option_ values take is implementation-defined. - A _local-declaration_ binds the resolved value of an _expression_ + A _declaration_ binds the resolved value of an _expression_ to a _variable_. Thus, the output of one _function_ is potentially the _operand_ of another _function_, From 23c032ad54e686ea5b48456f127c7dcacfaf61ea Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:23:18 -0800 Subject: [PATCH 09/17] Add the words "a representation of" to allow implementations... ...to bundle their results with a "parsed" version of their input --- spec/formatting.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index 9f24574bdc..23162c6074 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -238,7 +238,8 @@ the following steps are taken: Implementations that provide a means for defining custom functions SHOULD provide a means for function implementations to return values that contain enough information - (e.g. the resolved _operand_ and _option_ values + (e.g. a representation of + the resolved _operand_ and _option_ values that the function was called with) to be used as arguments to subsequent calls to the function implementations. From 632f9a9439ba1c437355dc74d39e0cba2df320b1 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:33:52 -0800 Subject: [PATCH 10/17] Update spec/formatting.md Co-authored-by: Eemeli Aro --- spec/formatting.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 23162c6074..8efe435e87 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -247,12 +247,8 @@ the following steps are taken: MAY define an interface for custom function implementations. Such an interface SHOULD define an implementation-specific argument type `T` and return type `U` - for implementations of formatting functions + for implementations of functions such that `U` can be coerced to `T` without loss of information. - The type `U` - (or a type that `U` can be coerced to without loss of information) - SHOULD also be the input type of implementations of - custom selector functions. Implementations of specific functions MAY signal errors if supplied an _operand_ that does not make sense for the particular function From 8a5f5893a866a2bab49c0f64b92948c2ccab01f7 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:42:19 -0800 Subject: [PATCH 11/17] Avoid use of 'input'/'output' --- spec/formatting.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 8efe435e87..07582f1016 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -224,7 +224,7 @@ the following steps are taken: A _declaration_ binds the resolved value of an _expression_ to a _variable_. - Thus, the output of one _function_ is potentially the _operand_ + Thus, the result of one _function_ is potentially the _operand_ of another _function_, or the value of one of the _options_ for another function. For example, in @@ -232,8 +232,10 @@ the following steps are taken: .input {$n :number minIntegerDigits=3} .local $n1 = {$n :number maxFractionDigits=3} ``` - the output of the first call to `:number` - is the input of the second call to `:number`. + the value bound to `$n` is the + resolved value used as the _operand_ + of the `:number` _function_ + when resolving the value of the _variable_ `$n1`. Implementations that provide a means for defining custom functions SHOULD provide a means for function implementations From 723941fb92ec65dec60cbf894a89e037cd240b31 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:43:47 -0800 Subject: [PATCH 12/17] Update spec/formatting.md Co-authored-by: Addison Phillips --- spec/formatting.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 07582f1016..8728226716 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -245,8 +245,7 @@ the following steps are taken: that the function was called with) to be used as arguments to subsequent calls to the function implementations. - For example, a MessageFormat implementation in a typed programming language - MAY define an interface for custom function implementations. + For example, an implementation might define an interface that allows custom function implementation. Such an interface SHOULD define an implementation-specific argument type `T` and return type `U` for implementations of functions From bd7bf09df922f88ac2717ac0d4d8769aca18815d Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:44:37 -0800 Subject: [PATCH 13/17] Update spec/formatting.md Co-authored-by: Addison Phillips --- spec/formatting.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 8728226716..3ebe72215d 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -250,10 +250,9 @@ the following steps are taken: argument type `T` and return type `U` for implementations of functions such that `U` can be coerced to `T` without loss of information. - Implementations of specific functions MAY - signal errors if supplied an _operand_ that - does not make sense for the particular function - being implemented. + Implementations of a _function_ SHOULD emit an + _Invalid Expression_ error for _operands_ whose resolved value + or type is not supported. > [!NOTE] > The behavior of the previous example is From 39000d296ceac4b10b069d2baaf69d49171d3fb9 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:58:30 -0800 Subject: [PATCH 14/17] Update spec/formatting.md Co-authored-by: Mark Davis --- spec/formatting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index 3ebe72215d..c1a636eca4 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -256,7 +256,7 @@ the following steps are taken: > [!NOTE] > The behavior of the previous example is -> implementation-dependent. Supposing that +> currently implementation-dependent. Supposing that > the external input variable `n` is bound to the string `"1"`, > and that the implementation formats to a string, > the formatted result of the following message: From 5f664cf9dd31acafc3c59518c7e5eb3b720ced94 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 12:58:59 -0800 Subject: [PATCH 15/17] Update spec/formatting.md Co-authored-by: Mark Davis --- spec/formatting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index c1a636eca4..47851fcc0d 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -267,7 +267,7 @@ the following steps are taken: > {{$n1}} > ``` > -> is implementation-dependent. +> is currently implementation-dependent. > Depending on whether the options are preserved > between the resolution of the first `:number` _annotation_ > and the resolution of the second `:number` _annotation_, From 6a3a965f91f739baf72f0640a58bf0ab60cbb528 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 13:02:18 -0800 Subject: [PATCH 16/17] Update spec/formatting.md Co-authored-by: Mark Davis --- spec/formatting.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/formatting.md b/spec/formatting.md index 47851fcc0d..510b29ba15 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -274,9 +274,13 @@ the following steps are taken: > a conformant implementation > could produce either "001.000" or "1.000" > -> Each function implementation MAY have +> Each function **specification** MAY have > its own rules to preserve some options in the returned structure -> and discard others. +> and discard others. +> In instances where a function specification does not determine whether an option is preserved or discarded, +> each function **implementation** of that specification MAY have +> its own rules to preserve some options in the returned structure +> and discard others. > > > [!NOTE] From 7ccec7c2b0cba1c1e2b457ee0722f0d8894d2f59 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 27 Feb 2024 13:57:59 -0800 Subject: [PATCH 17/17] Update spec/formatting.md Co-authored-by: Mark Davis --- spec/formatting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/formatting.md b/spec/formatting.md index 510b29ba15..56e880a50f 100644 --- a/spec/formatting.md +++ b/spec/formatting.md @@ -249,7 +249,7 @@ the following steps are taken: Such an interface SHOULD define an implementation-specific argument type `T` and return type `U` for implementations of functions - such that `U` can be coerced to `T` without loss of information. + such that `U` can be coerced to `T`. Implementations of a _function_ SHOULD emit an _Invalid Expression_ error for _operands_ whose resolved value or type is not supported.