I have a command, \Baz, that takes one optional argument which must be inline code. It relies on an external variable to store the default inline code (1). As standalone it works, but it does not meet the requirement of the project I am developing (2). That's where \Foo and a meta command to define it (3), enter the picture. Problem: when I try to define \Foo, I get the error: Defaults of '\Foo' have circular dependency.
Side notes: (1) The reason for keeping the default outside is to be able to modify \Baz that way. (2) Serialize calls to \Baz: information about the default is lost. (3) The tentative solution is borrowed from that of a post asking to create a lambda function.
\documentclass{report}
\usepackage{xparse}
\ExplSyntaxOn
\cs_set:Npn \__erw_baz_default:n #1{Hello, #1!}
\cs_set:Npn \__erw_baz_set:n #1
{
\cs_gset:Npn \__erw_baz:n ##1 {#1}
}
\DeclareDocumentCommand{\Baz}
{O{\__erw_baz_default:n{##1}}}
{
\__erw_baz_set:n {#1}
\__erw_baz:n{world}
}
\cs_set:Npn \__erw_foo_set:n #1
{
\cs_gset:Npn \__erw_foo:n ##1 {#1}
}
\cs_new_protected:Npn \__erw_make_Foo:n
#1
{
\use:x
{
\exp_not:n{\DeclareDocumentCommand{\Foo}}
{O{#1}}
}
{
\__erw_foo_set:n{##1}
\__erw_foo:n{world}
}
}
\__erw_make_Foo:n{Hello, ##1!}
\NewDocumentCommand{\Test}
{}
{
\noindent
\Baz[Jello,~##1!]\\
\Baz\\
\Foo[Jello,~##1!]\\
%\Foo
% Expected: % Hello, world!
% Actual: % LaTeX3 Error: Defaults of '\Foo' have circular dependency
}
\ExplSyntaxOff
\begin{document}
\Test
\end{document}

\Foolike\DeclareDocumentCommand{\Foo}{O{Hello,~#1}}{...}, then if the argument#1is not given, the default value of#1will depend on the value of#1... That doesn't make much sense (or more precisely, it loops, as you can see). Perhaps try\__erw_make_Foo:n{Hello, ####1!}... – Phelype Oleinik Mar 16 '20 at 21:18\__erw_make_Foo:n{Hello, ##1!}would makeHello, ##1!the default for#1in\Foo's argument specification. – Erwann Mar 16 '20 at 21:23\__erw_make_Foo:n{Hello, ####1!}worked. – Erwann Mar 16 '20 at 21:29