# Expand condition functions in LaTeX3

How to make \foo_bar: expand to code a?

\bool_new:N \foo_bool
\bool_set_true:N \foo_bool

\cs_new:Nn \foo_bar:
{
\bool_if:NTF \foo_bool
{ code~ a } { code~ b }
}


update:

% test.pdf is in the current directory.
\cs_new:Nn \foo_bar:
{
\file_if_exist:nTF { test.pdf }
{ code~ a } { code~ b }
}


(Complete question can be found in Expand condition functions in xeCJK)

• Could you 'expand' your fragment into a compilable document first, please ;-), but it should be \cs_new_nopar:Nn \foo_bar: rather. But it expands to a for me – user31729 Jul 13 '17 at 17:16
• Use \cs_new:Nx (or define a variant \cs_new:Nf) – egreg Jul 13 '17 at 17:17
• Sorry, changing the question and piling up new requests is not the way to react to answers ;- – user31729 Jul 13 '17 at 17:39
• Sorry for that... But the second one is actually what I need to do and I think both questions are interesting. – stone-zeng Jul 13 '17 at 17:45
• \file_if_exist:nTF is not expandable. – Bruno Le Floch Jul 13 '17 at 19:02

If the conditional value of \foo_bool should be frozen (expanded) in the definition of the macro, \cs_new:Nx is one possibility, if the macro should 'react' on the current value of \foo_bool, use \cs_new:Nn here.

I've changed the names to 'proper' expl3 naming conventions.

\documentclass{book}

\usepackage{xparse}

\ExplSyntaxOn

\bool_new:N \l_stone_foo_bool
\bool_set_false:N \l_stone_foo_bool% Set to false, although false by def.

\cs_new:Nn \foo_bar_current:
{
\bool_if:NTF \l_stone_foo_bool
{ code~ a } { code~ b }
}

\cs_new:Nx \foo_bar_expanded:
{
\bool_if:NTF \l_stone_foo_bool
{ code~ a } { code~ b }
}

\NewDocumentCommand{\foo}{}{%
\foo_bar_expanded:
}

\NewDocumentCommand{\foobar}{}{%
\foo_bar_current:
}

\bool_set_true:N \l_stone_foo_bool% For testing
\ExplSyntaxOff
\begin{document}
\foo\ and \foobar

\end{document}


\foo will expand to code b and \foobar will expand to code a, since setting the bool variable to true in the meantime, after defining \foobar.

• FYI, we've moved away from encouraging _nopar use for argument-less macros because it adds things to think about with no benefit. In the core expl3 the only _nopar macros are user-facing ones or those that have to be compared to token lists. – Bruno Le Floch Jul 13 '17 at 19:01
• @BrunoLeFloch: Eh, since which date you're encouraging users away from this? I was scolded two years ago, starting with expl3, for not using _nopar :-( – user31729 Jul 13 '17 at 19:02
• Sorry, we learn from experience. I have no idea when we changed. – Bruno Le Floch Jul 13 '17 at 19:04
• @ChristianHupfer As Bruno says, we realised a while ago that other than for setting up xparse and for some limited internal place, using nopar didn't really help. (For document-level interfaces it's different.) So it's not wrong to use nopar, it's just that we wouldn't do it now. As Bruno says, this is the 'experimental' part of expl3: there are changes as new ideas come forward. – Joseph Wright Jul 14 '17 at 5:26
• @JosephWright: Removed the _nopar 'modifier'... – user31729 Jul 17 '17 at 20:51

I guess you are defining a function that depends on some runtime options. The solution is to use \cs_new:Nx (which internally uses \edef).

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn

\bool_new:N \l_stonezeng_foo_bool

% true branch
\bool_set_true:N \l_stonezeng_foo_bool

\cs_new:Nx \stonezeng_foo_t:
{
\bool_if:NTF \l_stonezeng_foo_bool
{
\exp_not:n { code~a }
}
{
\exp_not:n { code~b }
}
}

% false branch
\bool_set_false:N \l_stonezeng_foo_bool

\cs_new:Nx \stonezeng_foo_f:
{
\bool_if:NTF \l_stonezeng_foo_bool
{
\exp_not:n { code~a }
}
{
\exp_not:n { code~b }
}
}

\cs_show:N \stonezeng_foo_t:
\cs_show:N \stonezeng_foo_f:

\stop


This will show on the terminal

> \stonezeng_foo_t:=\long macro:->code a.

> \stonezeng_foo_f:=\long macro:->code b.


Note \exp_not:n, so the inner code will not be expanded at definition time, but only upon usage.

Remember to use proper naming of variables and functions.