6

I want to deal with this question by my method. The example below is some codes from interface3.pdf; But throws the error:

 ! LaTeX3 Error: Variant form 'VV' deprecated for base form '\tl_if_eq:NNTF'.

\documentclass{article}
\usepackage{expl3}

\begin{document}
\ExplSyntaxOn
\tl_set:Nn \l_tmpa_tl { abc }
\tl_set:Nx \l_tmpb_tl { \tl_to_str:n { abc } }
\cs_generate_variant:Nn \tl_if_eq:NNTF { VV } % without this line, the result is falue, I want to get true with this line.
\tl_if_eq:VVTF \l_tmpa_tl \l_tmpb_tl { true } { false }
\ExplSyntaxOff
\end{document}
  • But the two token lists aren't equal. One is a token list abc, and the other is a string abc. – Phelype Oleinik Oct 22 '19 at 11:15
  • @Oleinik thanks. but why there is a bug with this code. – Brooks Oct 22 '19 at 11:16
8

You have two issues. The first is that a V argument doesn't really make sense as variant for an N argument (that's why it's deprecated). When you get the Value of a variable, the result will not necessarily be a single token, so the N argument will fail. That's why you can only make V variants of n arguments.

The second is that one token list contains the letter tokens abc (\tl_analysis_show:N \l_tmpa_tl shows):

The token list \l_tmpa_tl contains the tokens:
>  a (the letter a)
>  b (the letter b)
>  c (the letter c)

while the second token list contains the character tokens abc (\tl_analysis_show:N \l_tmpb_tl):

The token list \l_tmpb_tl contains the tokens:
>  a (the character a)
>  b (the character b)
>  c (the character c)

so they are not equal when doing a token list comparison. You need a string comparison here:

\str_set:Nn \l_tmpa_str { abc }
\str_set:Nx \l_tmpb_str { \tl_to_str:n { abc } }
\str_if_eq:VVTF \l_tmpa_str \l_tmpb_str { true } { false }

Note that \str_set:Nx \l_tmpb_str { \tl_to_str:n { abc } } is redundant. The argument of \str_set:Nx (and other str functions) is already passed through \tl_to_str:n.

  • 1
    shouldn't the first n be N? – Ulrike Fischer Oct 22 '19 at 11:29
  • 1
    thanks, I read interface3 more carefully after reading your nice answer. – Brooks Oct 22 '19 at 11:29
  • @UlrikeFischer Oops ;-) – Phelype Oleinik Oct 22 '19 at 12:25
8

There is no reason to define variants (besides being wrong to begin with, in this case):

\tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl {true} {false}

is already the thing to do (and yields false in your case).

You might think to do a comparison between an explicit token list and (the contents of) a token list variable, defining variants of \tl_if_eq:nnTF.

You can do

\prg_generate_conditional_variant:Nnn \tl_if_eq:nn {Vn,nV} { T,F,TF }

and now something like

\tl_if_eq:nVTF {abc} \l_tmpb_tl {true} {false}
\tl_if_eq:VnTF \l_tmpa_tl {abc} {true} {false}

will work (in your case the former yields false, the latter yields true).

The function \prg_generate_conditional_variant:Nnn is a wrapper around \cs_generate_variant:Nn that's meant to define variants for conditional functions (signature ending in TF, T or F); it avoids having to apply several times the basic function.

With the code above you define all variants

\tl_if_eq:nVTF
\tl_if_eq:nVT
\tl_if_eq:nVF
\tl_if_eq:VnTF
\tl_if_eq:VnT
\tl_if_eq:VnF

at once. Note that defining \tl_if_eq:VVTF is useless, because it would be the same as \tl_if_eq:NNTF, just slower and not fully expandable.

  • thanks for your answer. – Brooks Oct 22 '19 at 12:20
  • \tl_if_eq:NNTF would not be the same as \tl_if_eq:VVTF. The former is expandable, while the latter, being based on \tl_if_eq:nnTF would not be. – Phelype Oleinik Oct 22 '19 at 12:30
  • 1
    @PhelypeOleinik Right, I'll add it. – egreg Oct 22 '19 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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