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

TypedArray interface #964

Open
alippai opened this issue Oct 5, 2020 · 11 comments
Open

TypedArray interface #964

alippai opened this issue Oct 5, 2020 · 11 comments
Labels
documentation Additions to documentation
Milestone

Comments

@alippai
Copy link

alippai commented Oct 5, 2020

Would adding a 32-bit date representation for Temporal.Date (eg. days since 1970-01-01 like Apache Arrow does) be in scope of this spec? Similarly 64-bit datetime for Temporal.DateTime could work.

Maybe this would help WASM interoperability too.

I know anybody can map the Date and DateTime to 32 and 64bit numbers resp., but adding the reference values would make sense. Adding a few extra methods to a Uint32Array/Float64Array subclass would make the developer experience better, too.

@justingrant
Copy link
Collaborator

Hi @alippai - There are two questions you're raising:

  1. How should Temporal objects interoperate with WASM and other low-level interfaces?
  2. How should Temporal objects be converted into a single number-since-epoch?

For (1), I'm not sure what thinking (if any) has been happening on that topic so I'll leave it to others. It's a good question.

For (2), a core concept in Temporal is the idea of "exact time" (measured in nanoseconds since epoch) and "local time" which displays human-readable values we think of as calendar dates and clock time. Converting exact time to a number is easy, using the Temporal.Instant type:

instant = Temporal.Instant.from('2020-01-01T00:00Z');
instant.getOffsetNanoseconds(); // this is a `bigint`
instant.getOffsetMilliseconds();  // this is a `number`
instant.toZonedDateTime('Europe/Budapest');  // coming soon
instant.toDateTime('Europe/Budapest');

Other than Temporal.Instant and Temporal.ZonedDateTime, the other Temporal date and time types types (Temporal.DateTime, Temporal.Date, Temporal.Time, Temporal.YearMonth, and Temporal.MonthDay) all are local time types. This means that they do not know their relationship to UNIX epoch. Additionally, Temporal.ZonedDateTime also stores a time zone and a calendar in addition to nanoseconds-since-epoch which means that it cannot be translated to a single number. Only Temporal.Instant can be losslessly serialized into a single 64-bit number.

Your question about Temporal.Date is an interesting one. The problem is that Temporal.Date stores (at least) four values internally: calendar (usually 'iso8601') and year, month, and day according to the ISO calendar. So there's no way to losslessly serialize a Temporal.Date into a single number without limiting it to the ISO calendar, which you can certainly do in userland.

@alippai
Copy link
Author

alippai commented Oct 6, 2020

@justingrant yes, it's indeed doable in userland. My idea was making a "fastpath" for the 80% of the use-cases both for:

  1. the implementations (so they would just store it similarly as a 32-bit number and not converting it back and forth)
  2. developers so when working across languages (either WASM or network) they wouldn't need to reimplement everything.

I wasn't aware of the different calendars, but having a default serialization at least of the "default" types (so Temporal.Date with iso calendar as int32 or Temporal.DateTime without timezone as something derived from int64 as it's not part of JSON).

Adding a recommendation to reduce the overhead of parsing/serializing could be a nice touch - for a single date it's not that important, but this is why I was asking about typed data. We don't have dataframe-like operations in JS, but there are use-cases where you want to keep a date array standard and compact, charting (x-axis) is one, often you pass thousands of values (coming from an API or generated in WASM).

My end-to-end example would be:

  1. serialize a dataframe (timeseries data) using pyarrow
  2. send it using HTTP or WebSockets
  3. parse the table using Apache Arrow JS
  4. convert it to a typedarray
  5. pass the series to https://github.com/leeoniya/uPlot

Tldr; Highcharts, uPlot and others uses int timestamps for temporal data, this might be a use-case we want to support better

@ptomato
Copy link
Collaborator

ptomato commented Oct 8, 2020

We discussed this in the Oct. 8 meeting and have concluded that WASM code (or other code that requires a binary serialization of Temporal types) is not likely to have one binary serialization that we could prefer above all others. So, we will include an example of binary serialization in the cookbook, but we don't believe that there is one particular format that is used generally enough in interchange to be part of the API.

A possible route to achieving that might be to try to get an "ISO 8601 binary format" standardized.

@ptomato ptomato added documentation Additions to documentation and removed enhancement feedback labels Oct 8, 2020
@leeoniya
Copy link

leeoniya commented Oct 8, 2020

(author of uPlot here)

there's definitely a void that needs to be filled in frontend applications that must deal with nanosecond resolution timestamps. right now all the options are rather awkward BigNum math or slow and reliant on string parsing like https://github.com/jcgertig/nano-date.

uPlot tries to minimize its use of Date objects in general and does a lot of the math externally on timestamps, only using Date for sanity-checking leap years, DST rollovers, etc.

@ptomato
Copy link
Collaborator

ptomato commented Oct 19, 2020

Cookbook example to be written after the freeze and before Stage 3

@ptomato ptomato modified the milestones: Stable proposal, Stage 3 Oct 19, 2020
@ptomato
Copy link
Collaborator

ptomato commented Jan 13, 2021

On further reflection this isn't a requirement for Stage 3. To be done later.

@ptomato ptomato modified the milestones: Stage 3, Next Jan 13, 2021
@alippai
Copy link
Author

alippai commented May 18, 2021

Linking +1 related (and deferred) discussion: tc39/proposal-record-tuple#4

@ptomato
Copy link
Collaborator

ptomato commented May 18, 2021

I read that discussion, but I don't quite understand how it relates to this?

@alippai
Copy link
Author

alippai commented May 18, 2021

You are right that they might not be strongly connected. My understanding was having a stable binary representation and string / binary serialization might be a requirement for supporting Temporal in Records. This might be a wrong assumption.

@ptomato
Copy link
Collaborator

ptomato commented May 28, 2021

I asked around and it seems that this would not be a requirement. Temporal objects would be stored in a "Box" in a Record or Tuple, because although their state is immutable, the objects themselves aren't sealed or otherwise deeply immutable.

@ptomato ptomato modified the milestones: Next, Post Stage 4 Dec 8, 2022
@jcgertig
Copy link

@leeoniya thats hurtful it not that slow 🥲
but yeah since its based on bignum.js it's not blazing or anything. I could have updated it to use BigInt but at the time was watching this spec and keep hoping it will be released.
Will be nice to be able to put deprecated in favor of Temporal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Additions to documentation
Projects
None yet
Development

No branches or pull requests

5 participants