Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEEDBACK] Resolution between input calendar and message calendar #963

Open
sffc opened this issue Nov 25, 2024 · 8 comments
Open

[FEEDBACK] Resolution between input calendar and message calendar #963

sffc opened this issue Nov 25, 2024 · 8 comments
Labels
LDML47 LDML 47 Release (Stable) Preview-Feedback Feedback gathered during the technical preview registry Issue pertains to the function registry

Comments

@sffc
Copy link
Member

sffc commented Nov 25, 2024

This is similar to #961, but about calendars.

There could be two sources for calendars: the input type being formatted, and the message string. (Actually, there is a third, the locale of the message formatter.)

The spec should be more clear about resolution when these are in conflict with one another.

As a reference point, in Temporal, we throw an exception if two of the calendars differ and they are not ISO-8601. For example:

Calendar 1 Calendar 2 Resolved
iso8601 iso8601 iso8601
iso8601 buddhist buddhist
buddhist chinese ERROR
@sffc sffc added the Preview-Feedback Feedback gathered during the technical preview label Nov 25, 2024
@aphillips
Copy link
Member

(as individual contributor)

The spec should be more clear about resolution when these are in conflict with one another.

I don't agree. The option calendar is RECOMMENDED (i.e. optional) and the spec in no way defines what the option does. Actually, if you read our spec carefully, it doesn't define what any of the options do precisely. The actual performance is implementation defined. The cases you point out could reasonably result in a Bad Option or Unsupported Operation error in MF2 at the implementer's discretion. We allow this and we explicitly say:

Accepting a function or its options does not mean that a particular output is produced. Implementations MAY emit an Unsupported Operation error for options or option values that they cannot support.

You also noted:

(Actually, there is a third, the locale of the message formatter.)

Note that the calendar option explicitly exists to override this one. Its affect on the expression is presumably that it subordinates (or tries to) the value's calendar too.

@sffc
Copy link
Member Author

sffc commented Nov 25, 2024

The job, I would say only job, of a specification is to guarantee interoperability between implementations. It is not interoperable if one implementation throws an error and another doesn't in the same message

@macchiati
Copy link
Member

MF2 specifically doesn't specify exactly what happens with each message in each locale, and also allows for implementations to limit what they support (locales, etc). So in that sense, it is not 'interoperable between implementations'. But it also can't be, not if we want it to be adopted broadly when the underlying systems don't have full access to all data necessary for implementing all functions.

Personally, I think that it would be useful to have more information in the errors, and stipulate when they MUST/SHOULD/MAY/MUST NOT... be emitted. And add notion of a warning (signaling that the message was formatted meaningfully even though an option value couldn't be handled). For example we could have something like:

Ill_formed_Option_Value — emitted as an error iff the the option is ill-formed, like style=|!#$@|

  • requires us to specific in the registry what the well-formed option values are, explicitly or by reference

Unavailable_Locale — emitted as a warning iff the locale doesn't have the information to handle a particular function.

...

@aphillips
Copy link
Member

@macchiati Note that some of the kinds of errors you mention are at a different level from what MF2 prescribes at the message level.

Personally, I think that it would be useful to have more information in the errors

We don't forbid this. Error handling is reasonably diverse, such that it's hard to do things without making life difficult for some implementations.

The dichotomy between function handler and MF2 implementation is also at play here. We literally have no idea of the universe of things that might go wrong in a function (especially when we get to custom functions!!) so we leave a lot of leeway for the function handler to blow up and have the MF2 implementation report out what happened. Most of what you're talking about here can reside at the function handler level (in the date/time functions, in the case of calendar).

It also makes sense to push option validation down into the function handler or at least the glue layer between MF2 and the function itself. This allows the implementer of :datetime, for example, to handle the calendar argument in code that already knows about calendar systems or depend on e.g. DateTimeFormatter code to error back to her. The MF2 code only guarantees that the expression syntax is well formed and that the option value was correctly unboxed from any |quotes| and that the operand (if any) is resolved. This separation of concerns is important for extensibility, but requires spec readers to view the registry as somewhat separate from the rest of the spec.

and stipulate when they MUST/SHOULD/MAY/MUST NOT... be emitted

We do, much of the time. Many types of error are obligatory and there are places where errors MUST NOT be emitted. If there are gaps in this where you think errors aren't sufficiently prescribed, we should fix that.

Unavailable_Locale — emitted as a warning iff the locale doesn't have the information to handle a particular function.

This is one super tricky, no? Almost all of our standards depend on locale-based fallbacks for locale and data selection. In a previous life, we emitted a warning when the fallback crossed a language boundary (that is, when the fallback for the language priority list br-FR, fr-FR crosses from Breton to French, but not for br-FR=>br or fr-FR to fr). Sometimes the root locale has the information and we want to fall back to it!

@sffc sffc added registry Issue pertains to the function registry LDML47 LDML 47 Release (Stable) labels Dec 28, 2024
@sffc
Copy link
Member Author

sffc commented Dec 28, 2024

In LDML 47, can we change the calendar option to be Proposed instead of Recommended so we have more flexibility to explore the behavior here?

@macchiati
Copy link
Member

We agreed in 2025-01-13 that supporting the calendar option should be either SHOULD or MAY and not MUST.

@sffc
Copy link
Member Author

sffc commented Jan 13, 2025

A bit more background on the Temporal design here... (cc @mihnita)

There are several ways to construct a Temporal date:

  1. From an ISO-8601 format string: Temporal.PlainDate.from("2025-01-13")
  2. From a timestamp: Temporal.Instant.fromEpochMilliseconds(12345678)
  3. From the system: Temporal.Now.instant()
  4. From an option bag: Temporal.PlainDate.from({ year: 2025, month: 1, day: 13 })

In all of these, the calendar ends up as undefined or "iso8601" which is considered a neutral/weak calendar.

To specify a strong calendar, there are a number of options:

  1. Conversion function: date.withCalendar("buddhist")
  2. Explicit in option bag: Temporal.PlainDate.from({ year: 1445, month: 1, day: 1, calendar: "islamic" })
  3. Explicit in string: Temporal.PlainDate.from("2025-01-13[u-ca=hebrew]") // this is 2025-01-13 projected into Hebrew

As far as java.time, if you explicitly construct a java.time.chrono.JapaneseDate, I would consider that to be a strong calendar, and a java.time.LocalDate would be a weak calendar. So, this seems compatible with the strong/weak framing.

@macchiati
Copy link
Member

Sounds good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LDML47 LDML 47 Release (Stable) Preview-Feedback Feedback gathered during the technical preview registry Issue pertains to the function registry
Projects
None yet
Development

No branches or pull requests

3 participants