Subject: Re: bug#55635: `make-decoded-time' incorrectly sets DST to nil, it should be -1 (guess)

From: Maxim Nikulin <[email-masked]>
Date: Tue, 31 May 2022 19:25:25 +0700

On 30/05/2022 05:04, Paul Eggert wrote:
> diff --git a/lisp/simple.el b/lisp/simple.el
> index a254ee2251..d6b7045432 100644
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -10519,6 +10519,14 @@ capitalize-dwim
>  the number of seconds east of Greenwich.")
>    )
>  
> +;; Document that decoded-time-dst is problematic on 6-element lists.
> +;; It should return -1 indicating unknown DST, but currently returns
> +;; nil indicating standard time.
> +(put 'decoded-time-dst 'function-documentation
> +     (append (get 'decoded-time-dst 'function-documentation)
> +             "As a special case, `decoded-time-dst' returns an unspecified
> +value when given a list too short to have a dst element."))
> +

Paul, thank you for your efforts to fix the issues.

I have never used `cl-defstruct' before (and frankly speaking I am 
rather confused that the `decoded-time' struct and its constructor 
`make-decoded-time' are defined in different files and even directories 
are not the same), so my question may be naïve. Why did not you just add 
this new sentence to the :documentation property of the DST slot a bit 
above?

By the way, after updating of `make-decoded-time', default value for DST 
should be updated in `cl-defstruct' as well, otherwise
     (describe-symbol 'decoded-time)
reports that the default is nil.

It may be reasonable to cross-link `decoded-time' and 
`make-decoded-time' in docstrings.

Concerning timestamp vs. interval, first of all, I do not request 
immediate changes. I raised the question to make developers aware that 
the problem exist and it should be taken into account during further 
modifications or implementation of new features.

Lars Ingebrigtsen, Sun, 29 May 2022 15:10:19 +0200.
> If somebody wants to do
> interval calculations and passes in a DST to make-decoded-time, that's a
> classic "well, don't do that" situation.

DST slot with -1 (default) value is rather confusing for intervals but 
it safer for timestamps. Certainly it possible to do anything with bytes 
in memory, but direction of programming languages and libraries 
development is to allow users to clearly express intentions code and to 
add some measures that prevents bugs. That is why I mentioned tagged 
structure for interval type to distinguish it from timestamps.

Eli Zaretskii, Sat, 28 May 2022 19:53:47 +0300. >> From: Maxim Nikulin 
Date: Sat, 28 May 2022 23:31:43 +0700
>>
>> I think, it is confusing that `make-decoded-time' is used to create 
>> timestamps *and* time intervals. They are different types, for example 
>> sum of intervals is meaningful (despite may be ambiguous) while there is 
>> no point to add timestamps.
> 
> But this situation already exists with time units anyway.  You can add
> an hour to some other time, but there's also a valid time stamp that
> expresses 1 hour past the epoch UTC, and their values are exactly
> identical.

Certainly timestamps are actually intervals with various reference 
points. Encoded time is counted from 1970, decoded time from 0 a.d., so 
trying to add the same timestamps you will get result depending on their 
representation. Decoded time in some cases is more convenient since 1 
day may be not the same as 24 hours, not to mention varying duration of 
1 month.

The problem is that `decoded-time' time have field that are alien for 
intervals (timezone). Using the same constructor for both types makes 
code more obscure, it is impossible to enforce particular type of 
function argument to catch a programming error.

It is possible to use the same type for timestamps and intervals 
further, I am trying to dispute that it is the best design choice.