Subject: Re: bug#23926: defcustom with STANDARD=<non-pure-expression> gives confusing results

From: Eli Zaretskii <[email-masked]>
Date: Mon, 11 Jul 2016 21:52:15 +0300

> Date: Sun, 10 Jul 2016 10:18:29 -0700 (PDT)
> From: Drew Adams <[email-masked]>
> Cc: [email-masked], [email-masked]
> 
> > > The option value was changed?  I don't think so.
> > 
> > Yes, it was changed, because the value returned by the function
> > changes each time it's called.
> 
> What function?

current-time-string, of course.

> And what occurrence of calling it do you think is responsible for
> this characterization of the value having been changed outside
> Customize?

The second one.

> The fact is that the user did NOT change the value outside
> customize.

The message doesn't say it was the user.  Emacs doesn't know who
changed the value.

> And in fact, the value has NOT been changed.

Of course, it has changed.  Every time current-time-string is called
it returns a different value.  A defcustom's value is evaluated at
least twice, and in this case the second call yields a different
value.  That's why you see the note about changing.

> It is what it was when the defcustom was evaluated.
> 
> The responsible code is `custom-variable-state', specifically
> this part:
> 
> (setq tmp (get symbol 'standard-value))
> (if (condition-case nil
>         (and (equal value (eval (car tmp))) (equal comment nil))
>       (error nil))
>     'standard
>   'changed)
> 
> That tests whether the current value (var VALUE here), which
> in this case came from (default-value 'time), is equal to
> the result of RE-evaluating the defining defcustom sexp,
> (current-time).  And of course it is not equal, because
> time passes...
> 
> The reason it is not unequal is NOT because something has
> changed the option value outside Customize.  The option
> value has not been changed at all.  What "changes" here is
> the result of evaluating the initial sexp.
> 
> IOW, the "changed-outside-Customize" test used is too simplistic.  

No, it isn't.  It does its job.  If you want to avoid the note, if the
note annoys you, don't write such code.

> The code blithely assumes that evaluating what `custom-get'
> returns represents the original value, whereas what it returns
> is the result of RE-evaluating the original sexp.  That is
> precisely the point of this bug.

There's no bug.  This is how this stuff is supposed to work.  I'm not
going to endorse any significant changes there because of such
marginal use cases.