How to use \cs_generate_variant:Nn to compare token lists?

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.


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.