Skip to content

Semantic skeletons design #1067

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

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft

Conversation

aphillips
Copy link
Member

This design document contains the proposed design for including semantic skeletons into Unicode MessageFormat's functions.

This PR is based on @sffc's doc

This design document contains the proposed design for including semantic skeletons into Unicode MessageFormat's functions.

This PR is based on @sffc's [doc](https://docs.google.com/document/d/1s7GeN5V0cnw9B1erfMHTWwmnxz0EJkq2v78ZjzRq2t8/edit)
@aphillips aphillips added the design Design document or issues related to design label Apr 6, 2025
@aphillips aphillips requested review from eemeli and sffc April 6, 2025 15:13
Comment on lines 115 to 118
2. It should be possible to format field-based time types
(e.g. those that contain seperate values per field type in a date/time, such as a year-month)
3. It should be possible to format [floating time](https://www.w3.org/TR/timezone/#dfn-floating-time) values
(e.g. those that are not tied to a specific time zone)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we care about the input value's type? Are these not implementation concerns?

Copy link
Member Author

Choose a reason for hiding this comment

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

These are implementation concerns. But they generate requirements for date/time formatting options.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Really? Could you give an example, because I don't see how.

Copy link
Member Author

Choose a reason for hiding this comment

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

One such problem is the need to manage an input value's relationship to the timeline. While temporal types trying to pack all of the information into strongly typed objects, classical time values are usually timestamps (seconds or millis of epoch time). Formatting them requires a time zone (or at least an offset). Which means some external way of expressing the zone when it is different from the runtime's default time zone.

Delivery time local to you and not this web server will be: {$timestamp :datetime timezone=$usersTimeZone}

There is also a need to be able to "float" a value: remove it from the timeline so that field values stay constant regardless of time zone. This involves removing the time zone from the value, the equivalent of ZonedDateTime.toLocalDateTime() in Java:

Your birthday is: {$birthday :datetime offset=none} (option name made up on the spot)

Comment on lines 119 to 120
4. Date/time formatters should not permit users to format fields that don't exist in the value
(e.g. the "month" of a time, the "hour" of a date)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Again, isn't this an implementation concern? I don't see what this has to do with the shape of the formatting options.

Copy link
Member

@sffc sffc Apr 22, 2025

Choose a reason for hiding this comment

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

This is one of the main benefits of the semantic skeleton design, and I think points 1-4 can all be merged into this one. The point is that not all date types are the same and not all formatters are the same, and the date type needs to be able to expose all fields that the formatter needs.

aphillips and others added 5 commits April 22, 2025 08:22
Co-authored-by: Eemeli Aro <eemeli@mozilla.com>
- Put all the time types together in a single requirement about operands
```
{$date :datetime dateFields="YMD"}
{$date :datetime date="YMD"}
{$date :datetime fields="YMD"}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are dateFields, date and fields just different possible names for the same option? Or do they mean different things? (Same question about timePrecision vs. time below.)

Copy link
Member

Choose a reason for hiding this comment

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

Different possible names for the same option.

```

#### TimePrecision

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this needs a little more explanation (it should be possible to follow this doc without reading the other linked-to docs).

Copy link
Member Author

Choose a reason for hiding this comment

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

This part of the spec is basically empty and in need of work. I started to noodle around with it today. Each one of the options will need quasi-complete descriptions in order to see how they'll work and the relative usability of each.

aphillips and others added 5 commits April 22, 2025 16:00
Co-authored-by: Tim Chevalier <tjc@igalia.com>
Co-authored-by: Tim Chevalier <tjc@igalia.com>
Co-authored-by: Tim Chevalier <tjc@igalia.com>
Copy link
Member

@sffc sffc left a comment

Choose a reason for hiding this comment

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

The more I think about it, the more I think we should either go all-in on 4 functions or all-in on 1 function. The "middle ground" :date, :time, :datetime just seems flawed to me: it is trying to be type-safe but it fails at being type-safe.

Comment on lines +167 to +169
1. Date/time formatters should permit users to specify the desired width of indvidual fields
in a manner similar to classical skeletons,
while relying on locale data to prevent undesirable results.
Copy link
Member

Choose a reason for hiding this comment

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

I want to be more clear about what is "required" versus "wanted".

I think "required" is that users should specify an overall length, and "wanted" to hint at the width of an individual field independently of the overall length.

- Better at documenting the message author's intention

_Cons_
- _Lots_ of functions
Copy link
Member

Choose a reason for hiding this comment

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

But only 1 more than the previous option. The only one this adds is :zoneddatetime.


`:date`, `:time`, `:datetime`, `:zoneddatetime`, *maybe* `:zoneddate`, `:zonedtime`, `:timezone`

Problem: Most users are likely to prefer date/time/datetime to zoneddate/zonedtime/zoneddatetime
Copy link
Member

Choose a reason for hiding this comment

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

Great, so if naming is the only problem here, let's bikeshed the names and make another set of names. Let's try not to deviate too much from java.time and Temporal. :)

Copy link
Member Author

Choose a reason for hiding this comment

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

You mean like java.time and JS Temporal just did with Local vs. Plain? 🤣

Let's not overlook the fact that lots of platforms still don't have temporal types for date/time values. And that platforms that do have temporal types also have timestamps and classical time values that require formatting. The problem I'm calling out here is absolutely about bikeshedding the names/options--in order to ensure that we get the most usable syntax in MF. That shouldn't deviate one whit from what our Java/JS friends (who are mostly us after all) have done, except to make the concepts portable.

Comment on lines 251 to 253
Problem: Different platforms cannot agree on what to call a Floating Time Value: HTML and Java use `LocalXXX`,
JavaScript has adopted `PlainXXX`,
some others use different terms, such as `CivilXXX`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand the relevance of this. Isn't this purely an implementation concern, which has no visibility in the MF2 syntax? As I understand it, the idea is for the function names to describe the formatted output, not the input.

Copy link
Member Author

Choose a reason for hiding this comment

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

A reasonable approach would be to name the functions consistent with usage. The point here is that there is not agreement on what to call these.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I still don't understand how naming concerns about an input value type would transmit to the syntax. For example, I would expect an expression for a time with hours and minutes to look something like

{$t :datetime hour=numeric minute=numeric}

or maybe

{$t :time fields=hm}

irrespective of whether $t held a floating time value, or one with a timezone attached, or any other representation of the value to be formatted.

Or do you think we ought to have different functions for each input datetime type supported by an implementation?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is capturing some of the conversation in Monday's call. Ultimately this isn't the place for it.

Some people, such as @sffc, have expressed a desire for the functions to be "type safe". This might mean naming functions for the the underlying behavior, e.g. :localdate or :localtime--- s/local/[civil|plain|...]/g

Copy link
Member

Choose a reason for hiding this comment

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

By "type safe" I mean that there should be well-defined semantics around when implementations should emit a Bad Operand error. For example, if you pass an implementation-specific "time-only" type to :date, you should get a Bad Operand error.

aphillips and others added 4 commits April 29, 2025 07:57
Co-authored-by: Eemeli Aro <eemeli@mozilla.com>
Co-authored-by: Eemeli Aro <eemeli@mozilla.com>
Co-authored-by: Eemeli Aro <eemeli@mozilla.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Design document or issues related to design
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants