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

Obtaining Emacs style time lists #25

Open
psionic-k opened this issue Nov 19, 2023 · 7 comments
Open

Obtaining Emacs style time lists #25

psionic-k opened this issue Nov 19, 2023 · 7 comments

Comments

@psionic-k
Copy link

I want to adopt this into the guts of chamagne

Looks like we have to call seconds-to-time on the ts-unix result. IMO ts-emacs would tighten up the API. Did I miss something?

Some more readers would also be helpful, for plugging into interactive forms to avoid using the various string conversions in diary-lib etc. I can maybe upstream some champagne work if you agree that these are needed, although it grows the maintenance surface, I think in a very good way.

Lemme kno

@alphapapa
Copy link
Owner

Please see ts-internal.

Some more readers would also be helpful, for plugging into interactive forms to avoid using the various string conversions in diary-lib etc. I can maybe upstream some champagne work if you agree that these are needed, although it grows the maintenance surface, I think in a very good way.

Feel free to make an issue and we can talk about them.

Thanks.

@psionic-k
Copy link
Author

Thanks.

@psionic-k
Copy link
Author

I came to the conclusion that ts-internal is less useful than ts-unix, but I don't like the reason, the use of encode-time and decode-time instead of seconds-to-time. I wanted to run this by you because I started to point this out as a type path to avoid when working with Emacs scalar times and ts:

*** ts-internal ⚠️
*Not recommended*. We can also connect ~ts~ records through the =ts-internal= slot,
albeit with some precision loss.  (It uses ~encode-time~ and ~decode-time~ in the
implementation, which lose precision.)
- ~ts-internal~
- ~ts-apply~
#+begin_src elisp
  ;; With `ts-unix', what precision existed in the floating point time is preserved
  (current-time)                       ; (25947 5165 316794 285000)
  (seconds-to-time (ts-unix (ts-now))) ; (25947 7258 894400 119781)

  ;; Note loss of precision when using `ts-internal'
  (ts-internal (ts-now))               ; (25947 5458)
  ;; make a `ts' record from `current-time'
  (ts-apply 'internal (current-time) (ts-now)) ;; #s(ts nil nil nil nil nil nil nil nil nil nil nil ...)
  ;; Updating a time `ts-internal' slot does also not preserve the precision
  (let ((created-from-current (ts-apply 'internal (current-time) (ts-now)))
        (ts-internal created-from-current))) ; (25947 5563)
#+end_src

Sorry if I missed something about why it's this way, but I think it's still correct to avoid that slot for now unless it were changed to use seconds-to-time.

My other complaint, if being picky, is not producing a (TICKS . PHZ) form using time-convert and seconds-to-time. The manual states that the four-member list style is going away. I'm sure you're aware, just repeating. If there's contradicting info about this change in another channel, sorry in advance.

@psionic-k psionic-k reopened this Nov 20, 2023
@alphapapa
Copy link
Owner

seconds-to-time is not documented in the Elisp manual for some reason, so it might be better to avoid using it. AFAICT time-convert is the newly designated function for this purpose, so maybe we should use it.

I don't object to using the TICKS . HZ format; as far as I'm concerned, the ts-internal accessor is supposed to return an Elisp timestamp value, but not a specific one of the documented formats, so any downstream users should be prepared for any valid value--so we might as well use the future-oriented one.

What do you think?

@psionic-k
Copy link
Author

time-convert indeed looks sufficient and proper.

Anywhere that people are setting current-time-list to nil, the change has already occurred. Any package maintainer erroneously relying on the (HIGH LOW) form is seeing bugs for a subset of users.

(let ((current-time-list t))
    (time-convert (float-time))) ; (25947 63661 25096 178054)
    
(let ((current-time-list nil))
    (time-convert (float-time))) ; (7132524043151968 . 4194304)    

Times without sub-second precision are only useful for conversion into timestamps or logical time, so my expectation is that the slot is not being used in a manner similar to champagne where fractional seconds are obtained by reading the 3rd element of (HIGH LOW MICRO PICO)

Champagne was mishandling some times, but it was mostly covered up by the flexibility of time-add and run-at-time etc. The destination functions for Emacs scalar times will usually be these functions, and they presently handle both forms.

The benefit of unifying the type graph and avoiding precision loss has very good karma. If there is one thing I really would want as a consumer of the library, it's smoothly inter-operating with Emacs scalar times.

@alphapapa
Copy link
Owner

Forgive my pedantry, but there is so much jargon in this context, that it's helpful to me if we use only the official, "blessed" Emacs terms for these things, so that I know exactly what you mean. For example, there are no "scalar times" in Emacs (the word "scalar" isn't even found in the Elisp manual, even though its meaning in CS terms may apply somewhere).

According to the Elisp manual section 42.5, there are "Lisp timestamps" in three forms: integer, (TICKS . HZ), and (HIGH LOW MICRO PICO).

Then there are the various arguments that various time/date-related functions accept, such as decode-time's (SECONDS MINUTES HOUR DAY MONTH YEAR DOW DST UTCOFF). And, as section 42.7 says, "Alternatively, you can use the ‘calendar’ and ‘time-date’ libraries."

In ts (this library), there is the ts struct, which has the various slots, one of which is the internal slot, which is intended to be an Emacs "Lisp timestamp" value, and which we should be able to change to one of the other 3 forms without breaking anything. (Ideally, perhaps, a future version of ts would operate more on those Lisp timestamp values rather than Unix timestamps, since that could offer increased precision; OTOH Unix timestamps format naturally to an almost human-recognizable form, which has some benefit.)

Does that all make sense to you and seem reasonable?

@psionic-k
Copy link
Author

psionic-k commented Nov 21, 2023

And, as section 42.7 says, "Alternatively, you can use the ‘calendar’ and ‘time-date’ libraries."

If these use structures different than what decode-time outputs, I hadn't noticed, and let me know so I can give them some attention

In ts (this library), there is the ts struct, which has the various slots, one of which is the internal slot, which is intended to be an Emacs "Lisp timestamp" value, and which we should be able to change to one of the other 3 forms without breaking anything. (Ideally, perhaps, a future version of ts would operate more on those Lisp timestamp values rather than Unix timestamps, since that could offer increased precision; OTOH Unix timestamps format naturally to an almost human-recognizable form, which has some benefit.)

Yep, except let's add that ts should adopt (TICKS . HZ) straight away, as obtained from (time-convert (float-time) t) since the jist of my argument is that nobody uses the current low-precision value from the internal slot in a way that will break from the proposed change

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

No branches or pull requests

2 participants