1

\int_compare fails with an argument generated from an expression, the expansion of which (3==3==3) is seemingly suitable. Why, and is there a solution?

\documentclass{l3doc}
\usepackage{expl3}

\ExplSyntaxOn

\cs_set:Npn \erw_split:nnn #1 #2 #3
{
    \tl_head:n{#1}
    \use:c{exp_args:#3}  \tl_map_inline:nn 
    {
        \tl_tail:n
        {
            #1
        }
    }{#2##1}    
}


\ExplSyntaxOff
\begin{document}
\ExplSyntaxOn

\erw_split:nnn
{
    {3}{3}{3}
}{==}{Nf} % prints as '3==3==3' as expected

\\

\exp_last_unbraced:Nf \tl_if_eq:nnTF{{
    \erw_split:nnn
    {
        {3}{3}{3}
    }{==}{Nf}
}{3==3==3}{T}{F}} % F, why?

\\

\int_compare:nTF{3==3==3}{T}{F} % 'T', as expected

\\

%\exp_args:Nf
%\int_compare:nTF
%{
%   \erw_split:nnn
%   {
%       {3}{3}{3}
%   }{==}{Nf}
%}
%% Haven't found an inner/outer exp_args signature that works. 
%% For example, Nf/Nf yields this error:
%% ! Undefined control sequence.
%%<argument> \LaTeX3 error: 
%%                           Relation '\tex_global:D ' unknown: use =, <, >, =...

\ExplSyntaxOff
\end{document}
13
  • Try \tl_set:Nf \l_tmpa_tl { \erw_split:nnn { {3}{3}{3} }{==}{Nf} } \tl_show:N \l_tmpa_tl
    – cfr
    Jun 19, 2018 at 1:03
  • This is what is shows: > \l_tmpa_tl=3\use:c {exp_args:Nf}\tl_map_inline:nn {\tl_tail:n {{3}{3}{3}}}{==##1}. <recently read> }
    – Erwann
    Jun 19, 2018 at 1:05
  • 1
    Which does not equal 3==3==3.
    – cfr
    Jun 19, 2018 at 1:07
  • Note that it isn't testing whether the two token lists will typeset the same thing, but whether the two token lists are identical. At least, that's how I understand it.
    – cfr
    Jun 19, 2018 at 1:09
  • 3
    Why not use \tl_count:N?
    – cfr
    Jun 19, 2018 at 1:27

1 Answer 1

2

Let's see what happens with the call

\erw_split:nnn{{3}{3}{3}}{==}{Nf}

This becomes

\tl_head:n{{3}{3}{3}} \exp_args:Nf \tl_map_inline:nn { \tl_tail:n {{3}{3}{3}} } {==##1}

and then

3\tl_map_inline:nn{{3}{3}}{==##1}

which prints “3==3==3”, but is not usable in the context of \int_compare:nTF, because \tl_map_inline:nn is not expandable (it has no star or hollow star in its description).

Defining \erw_split:nnn with \cs_new:Npn or \cs_set:Npn doesn't make it fully expandable, if what's defined with is not fully expandable as well.

5
  • How does \cs_new vs \cs_set enter the picture?
    – Erwann
    Jun 21, 2018 at 20:44
  • @Erwann The difference between \cs_new and \cs_set are that the former checks for definedness and performs a global definition.
    – egreg
    Jun 21, 2018 at 21:06
  • I take it from your last answer that I surmised wrong that using \cs_newrather than \cs_set could have had something to do with 'not fully expandable'.
    – Erwann
    Jun 21, 2018 at 21:13
  • 1
    @Erwann Yes, it's not relevant to that purpose whether you use one or the other.
    – egreg
    Jun 21, 2018 at 21:14
  • You may find a follow up this post in Listing 8 and Listing 15. github.com/er-cpp/erw-l3/blob/…
    – Erwann
    Jun 23, 2018 at 2:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .