I've also investigated the issue a little bit further and wrote and
email with my conclusions about the same time Max wrote his. I comment
inline about a few of your thoughts:

> For `defcustom' autoload generates no more than
>
>     (defvar org-capture-templates nil "...")
>
> It seems, behavior depends on whether `org-capture-templates' has the :set
> attribute.

Not really, all defcustoms have a :set attribute, be it passed
explicitly as a parameter or the default value, set-default. This issue
happens with all autoload functions that use a custom variable: if they
are called inside a let form binding that variable and the feature was
not loaded yet, the let-binding will have no effect.

> The setter receives nil instead of the let-bound value. I can not say
> I understand the tricks with bypassing lexical binding in `defcustom' and some
> checks in `custom-declare-variable'. Since emacs-26 something has changed:

> I am unsure that the setter of `defcustom' should get let-bound value in the
> case of autoloading since it might lead to fragile behavior.

See my other email where I explain what I think that defcustom of a
variable is doing when called inside a let-binding of that variable.

>> https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=6309131349
>>> -  ;; Use defvar to set the docstring as well as the special-variable-p 
>>> flag.
>>> -  ;; FIXME: We should reproduce more of `defvar's behavior, such as the 
>>> warning
>>> -  ;; when the var is currently let-bound.
>>> -  (if (not (default-boundp symbol))

But the conclusion is that right now it does not work, so I think that warning
is needed.

> It looks like the setter on org-capture-template is used to do some
> form of conversion on the template specification to force a new
> format. Not sure how long that has been there or whether it is
> actually still required. Could be that this setter was added to aid in
> transition to a new template format which could/should be removed at
> some point.

That is right, it seems it was added for backwards compatibility when a
new template format was added. However, it's not actually needed, since
org-capture-select-template also calls that function to ensure they are
in the new format. It needs to do so in order to allow
setting org-capture-templates also with setq, or let-binding
org-capture-templates as I do. That's not the problem anyway, as I
explained above.

> However, this behaviour seems like it may be the tip of a much bigger
> issue outside of org-mode and potential source of bugs for Emacs.

> Bottom line is I don't think any function should behave differently
> depending on when autoload runs

> Regardless, I don't think having the situation where the programmer must
> know (guess) whether autoload will/could execute during the evaluation
> of code they write is tenable and am beginning to suspect it may be an
> Emacs bug OR a subtle bug in org-mode as a result to the transition to
> lexical binding as the default. My recommendation would be to come up
> with a non-org specific example which reproduces the behaviour and then
> ask on emacs-devel, using the example to demonstrate the issue.

I agree. I'm on it.

>> Reading the code I noticed `org-capture-templates-contexts' so I wonder if it
>> might help for the original use case.
>
> I thought about that as well. However, from re-reading the OP's posts, I
> suspect not. org-capture-templates-contexts seems to be useful when you
> want to restrict access to some templates based on context. However,
> from reading the OP's posts, I get the impression that what they want is
> for templates to be different based on context i.e. they still want the
> template associated with 'd', but want its definition to be different.
>
> It is possible org-capture-template-contexts might provide an
> alternative solution where you don't need to dynamically modify/add
> templates in this manner. For example, you could have all your templates
> defined, but only offer those relevant based on context. However, I
> guess this would mean having to have different template keys, which
> might be an issue.

If I recall correctly template contexts allow to redefine the template
key, so that would not be an issue. And yes, using template contexts
could probably be a solution to my use case, as it would be having an
org-capture version with template parameter. But don't worry too much
about my use case, since a simple (require 'org-capture) is enough to
keep doing what I was doing.

Reply via email to