Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I don't understand what difference of existance and being free means. Consider this example:

\documentclass{article}
\usepackage{expl3}

\begin{document}

\ExplSyntaxOn

\cs_new:Npn \my_cs: {}

\verb=\my_cs:= ~ does ~ \cs_if_exist:NF \my_cs: { not ~ } exist \\ % exists
\verb=\my_cs:= ~ is ~ \cs_if_free:NF \my_cs: { not } ~ free \\ % not free

\tl_new:N \l_my_tl

\verb=\l_my_tl= ~ does ~ \cs_if_exist:NF \l_my_tl { not ~ } exist \\ % exists
\verb=\l_my_tl= ~ is ~ \cs_if_free:NF \l_my_tl { not } ~ free % not free

\verb=\l_tmpa_tl=~does~\cs_if_exist:NF \l_tmpa_tl { not ~ } exist \\ % exists
\verb=\l_tmpa_tl=~is~\cs_if_free:NF \l_tmpa_tl { not } ~ free % not free

\ExplSyntaxOff

\end{document}

Can a cs exist and be free? Or is the difference more a semantic one?

share|improve this question
add comment

3 Answers

up vote 7 down vote accepted

I show the output of \cs_show:N \cs_if_free:NTF and of \cs_show:N \cs_if_exist:NTF (formatted for better readability)

\cs_show:N \cs_if_free:NTF

> \cs_if_free:NTF=\long macro:
#1->\if_meaning:w #1\scan_stop:
      \prg_return_true:
    \else:
      \if_cs_exist:N #1
        \prg_return_false:
      \else:
        \prg_return_true:
      \fi:
    \fi:
  \c_zero .

\cs_show:N \cs_if_exist:NTF

> \cs_if_exist:NTF=\long macro:
#1->\if_meaning:w #1\scan_stop:
      \prg_return_false:
    \else:
      \if_cs_exist:N #1
        \prg_return_true:
      \else:
        \prg_return_false:
      \fi:
    \fi:
  \c_zero .

If the meaning of #1 is \relax (aka \scan_stop:), the former returns true and the latter returns false, so \relax is free and does not exist. Otherwise the tests use \if_cs_exist:N, that is, \ifdefined, and the results are likewise opposite.

I think it's only a matter of convenience to have two tests that are, in fact, equivalent up to switching the arguments.

According to Joseph Wright, the two tests might have not been reverse of each other at some point in time, but they are nowadays.

share|improve this answer
    
Hmm... this means every existing command is not free and every free command does not exist. For me this sounds like the same thing with a different name. \cs_if_exist:NT is the same as \cs_if_free:NF and vice versa. –  cgnieder Feb 9 '12 at 22:02
    
Oh. I overread that you stated that in your answer as well :) –  cgnieder Feb 9 '12 at 22:04
    
Yes and no. :) Try and see their meaning: \cs_if_free:NF seems to be slightly more efficient than \cs_if_exist:NT (and conversely, switching F and T). –  egreg Feb 9 '12 at 22:07
    
I'm afraid I am not really able to tell what efficiency means in this context. Will the one be faster than the other? (Can't be much on a scale observable by human beings, anyway ;) ) –  cgnieder Feb 9 '12 at 22:20
1  
As coded now in expl3, the F conditionals are slightly faster than the T conditionals. Really, I optimized the TF conditionals, and then the F conditionals come by just adding {}, while the T conditionals need \use:n \use_none:n to go from the TF logic to the T logic. This is true of all conditionals in expl3. I try very hard not to take that into account when writing code because it may change (but as I'm perpetually striving for speed, that's difficult to forget). –  Bruno Le Floch Feb 9 '12 at 22:37
show 3 more comments

As egreg describes, the two conditionals can be used interchangeably in all cases (up to exchanging the <true> and <false> branches, of course).

The only difference is semantic. For instance,

\tl_new:N \l_foo_tl

starts with

\cs_if_free:NF \l_foo_tl { <error> }

but

\tl_use:N \l_foo_tl

contains roughly

\cs_if_exist:NF \l_foo_tl { <error> }

In both cases, we are trying to assert that a given condition holds: either check that the token list variable is free to define, or check that the token list is defined and won't trigger an error when used.

share|improve this answer
add comment

These commands were purposefully defined as a pair but their behaviour was not always symmetric. The original intention was to have a loose definition along the lines of:

\cs_if_free:NTF — is it allowable to create a new cs with this name?
\cs_if_exist:NTF — has the cs been created?

For quite a while, \cs_if_free had some extra branches to sanity check its input. E.g., only the kernel should define commands with :D suffixes, so return false. Actually that might have been the only difference :). You could imagine a few other such checks according to the conventions of the expl3 naming scheme.

As some point we decided that all this was overkill and simplified the behaviour, and at that point the two commands became logically symmetric. But I'd still recommend as a point of style to use them in your code according to the definitions above.

If we were to start again, I think it would be better to only have a single command name.

share|improve this answer
    
Thanks! This finally clears the reasoning behind those two. –  cgnieder May 22 '12 at 9:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.