\cs_new:Npn causa un error de unidad o medida ilegal mientras que \let no

\cs_new:Npn causa un error de unidad o medida ilegal mientras que \let no

En el MWE:

\documentclass{article}
\setlength{\fboxsep}{0pt}
\begin{document}

\ExplSyntaxOn
\cs_new:Npn \foo:nn #1#2
  {
    \makebox[#1][s]{#2}
  }
% \cs_new:Npn \bar:nn #1#2 { \foo:nn #1#2 }
\let \bar:nn \foo:nn
\fbox{\foo:nn {3cm} {a~b~c~d}}\par
\fbox{\bar:nn {3cm} {a~b~c~d}}
\ExplSyntaxOff

\end{document}

Si uso \cs_new:Npnen lugar de \let, arrojará un error de "unidad de medida ilegal". ¿Por qué? ¿Cómo puedo arreglar esto?

Respuesta1

Es un problema de sintaxis TeX:

\cs_new:Npn \foo:nn #1#2 { ... }

te muestrodefinir \foo:nn. Pero cuando tullamareso, tienes que hacerlo

\foo:nn {<argument 1>}{<argument 2>}

y las llaves se pueden omitir si el argumento consta de un solo token.

En tu intento, de \bar:nn {3cm}{abcd}ti obtienes

\foo:nn 3cmabcd

así #1es 3y #2es c, resultando en

\makebox[3][s]{c}mabcd

que definitivamente no es lo que quieres. Con

\cs_new:Npn \bar:nn #1#2 { \foo:nn {#1}{#2} }

obtienes lo deseado.

Observé que \letno se debe usar dónde \cs_new_eq:NNestá la llamada correcta, comparemos las siguientes llamadas:

  1. \cs_new:Npn \bar:nn #1#2 { \foo:nn {#1}{#2} }
  2. \cs_new_eq:NN \bar:nn \foo:nn

¿Hay alguna diferencia? Infinidad. Con la primera llamada, \bar:nnse utilizará el significado \foo:nnactual en el momento de la llamada; con la segunda llamada, \bar:nnutilizará el significado de \foo:nnactual en el momento de la definición. Entonces necesitas saberpor quéhaces esa definición y haces la elección adecuada. Si estás seguro de que \foo:nnnunca cambia de significado, las dos llamadas son casi equivalentes: no completamente iguales, porque con 1 \bar:nnrequiere un paso de expansión más que con 2.

Nota.Descarté algunos aspectos que no son relevantes para el tema, pero son importantes.

  1. Intente seguir las expl3convenciones de nomenclatura: ambos \foo:nny \bar:nnson malos nombres.

  2. Funciones que emplean funciones/macros no expandibles, como las que \makeboxdeberían estar “protegidas”:

    \cs_new_protected:Npn \stephen_foo:nn #1#2 { \makebox[#1][s]{#2} }
    

    seria mejor.

información relacionada