[Tex/LaTex] Guidelines: when is LaTeX3 too much LaTeX3

expl3latex3package-writing

This morning I found myself writing a document where essentially the same text is repeated several times. Because I've been mucking around a lot recently learning LaTeX3, it took absolutely no thought and practically no time to write the following snippet.

\usepackage{xparse}
\ExplSyntaxOn
\newcommand{\tangentcount}[1]{
               \prg_case_int:nnn { #1 }
               {
                    { 2 } { exactly\ two }
                    { 1 } { exactly\ one }
               }
               { no }
}
\ExplSyntaxOff
\newcommand{\ietangents}[2]{%
    \tangentcount{#1} external and \tangentcount{#2} internal tangents.}

Granted, it would probably have been better to write:

\NewDocumentCommand{\tangentcount}{ m }
    {
               \prg_case_int:nnn { #1 }
               {
                    { 2 } { exactly\ two }
                    { 1 } { exactly\ one }
               }
               { no }
    }

It's also worth noting that I probably could have done something like

\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\tangentcount}{ m }
    {%
        \IfEqCase{#1}{%
            {2}{exactly two}%
            {1}{exactly one}%
        }[no]%
    }

And certainly, I could have done something at the TeX level. But to build a switch function in TeX? The code just doesn't come naturally or quickly enough—I could probably write the whole document in the time it would take me to figure out how to get the switch done in TeX.

Now this is definitely a private document that I will really only ever use for today's class on account of a tangential question last week, please excuse the pun. It's probably a document that will just get left there on my harddrive, soon forgotten and never referred to again. So on a certain level, how I do this really does not matter.

But the question does come to mind, what are good practices?

I'm not writing a package: at least not yet. But who knows? Maybe I'll decide in a couple months that I really do want to put together all these little pieces of code for something I'll post publically or even publish. All this raises questions about the suitability of the code for the task at hand and how much potential refactoring of my code will I have to do.

For now it seems, there will be times when using LaTeX2e (or even some TeX) might be unavoidable. Things such as glue, drawing rules, setting up fonts, formatting text, inputting files, creating boxes (or maybe that's what coffins are about) appear to be out of the current scope of LaTeX3. To the extent that I understand the philosophy of the LaTeX3 authors, there may never be an explicitly LaTeX3 command such as \markup_text_bf:n.

In the above examples, I prefer the LaTeX3 solution over using xstring; not because I don't like xstring, but because it seems silly to slurp in an entire package when I'm already using macros and environments which have invoked expl3. But is this good practice?

So what are some general guidelines for deciding when one should resort to TeX, LaTeX2e, or LaTeX3?

Best Answer

I believe it is good practice. There are hundreds of functions in the current LaTeX3 kernel that make a macro programmer's life easier.

I wouldn't use such a dramatic indentation as you do and surely I'd use \NewDocumentCommand:

\NewDocumentCommand{\tangentcount}{ m }
 {
  \int_case:nnn { #1 }
   {
    { 1 } { exactly ~ one }
    { 2 } { exactly ~ two }
   }
   { no }
 }

or, even better,

\NewDocumentCommand{\tangentcount}{ m }
 {
  \ellett_tangentcount:n { #1 }
 }
\cs_new:Npn \ellett_tangentcount:n #1
 {
  \int_case:nnn { #1 }
   {
    { 1 } { exactly ~ one }
    { 2 } { exactly ~ two }
   }
   { no }
 }

separating the user command from the inner function. This may be easily extended to any number of intersection points

\cs_new:Npn \ellett_tangentcount:n #1
 {
  \int_compare:nTF { #1 = 0 }
   { no }
   { exactly ~ \int_to_arabic:n { #1 } }
 }

Notice the use of ~ to denote a space in the output, to be preferred to "control space". One may add a check that the number is greater than zero.

Notice also that \prg_case_int:nnn is an obsolete name for the current \int_case:nnn function.

Why \cs_new:Npn? Because the \int_compare:nTF and \int_case:nnn functions are marked with a filled star in the documentation, so they are "fully expandable" and thus also \ellett_tangentcount:n can be used in a "pure expansion" context.