5

I have two codes for evaluating number. First of it for evaluating floating point number:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\evaluate}{m}
 { \fp_set:Nn \l_myvar_fp {#1}
   \fp_eval:n { \l_myvar_fp }

 }
\ExplSyntaxOff
\begin{document}

\evaluate{2+3}

\end{document}

It is well done and I get correct answer.

Then of it for evaluating integer number:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\evaluate}{m}
 { \int_set:Nn \l_myvar_int {#1}
   \int_eval:n { \l_myvar_int }

 }
\ExplSyntaxOff
\begin{document}

\evaluate{2+3}

\end{document}

In the second example I just change fp to int, but I get an error in the second case:

Undefined control sequence

But if I directly use \int_eval:n without using an intermediate variable \l_myvar_int it is well done.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\evaluate}{m}
 { \int_eval:n { #1 }

 }
\ExplSyntaxOff
\begin{document}

\evaluate{2+3}

\end{document}

Only after definition variable via \int_new:N \l_myvar_int it is successfully compiled.

Why in first case code well done without definition of a new variable, but it the second case does not?

  • 1
    Well, either it is a bug or a design flaw. \int_set:Nn does not define the variable, whereas \fp_set:Nn does – user31729 May 28 '17 at 18:05
  • \int_set:Nn does not define, but \fp_set:Nn does. Well, this is not obvious and confusing. – sergiokapone May 28 '17 at 18:09
  • BTW, not quite sure what you are up to here but you would normally either use \<thing>_eval:n directly or set a variable then \<thing>_use:N it. – Joseph Wright May 28 '17 at 18:25
  • @JosephWright Thanks, I know about using \<thing>_eval:n directly. But when I introduced an intermediate variable I got an error and ask here. Is the \<thing>_use:N a synonym of \<thing>_eval:N in my case? – sergiokapone May 28 '17 at 18:36
  • @ChristianHupfer This is neither a bug nor a design flaw. It is a consequence of the fact that fps are just macros whereas ints are count registers. A count register has to be allocated before writing, macros can always be overwritten. Adding a check for fps is unnecessary overhead. – Henri Menke May 29 '17 at 1:42
8

You've not declared your variables. Due to the underlying implementation detail, some variable types may allow you to set them without declaration. However, this is not something that is supported (as in we reserve the right to change things). You can force expl3 to check declarations, thus

\documentclass{article}
\usepackage[check-declarations]{expl3}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\evaluate}{m}
 { \fp_set:Nn \l_myvar_fp {#1}
   \fp_eval:n { \l_myvar_fp }

 }
\ExplSyntaxOff
\begin{document}

\evaluate{2+3}

\end{document}

will yield

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! LaTeX error: "check/non-declared-variable"
! 
! The variable \l_myvar_fp has not been declared on line 14.
! 
! See the LaTeX3 documentation for further information.
! 
! For immediate help type H <return>.
!...............................................  

Checking is not active as-standard largely for performance reasons: for data types implemented as macros, checking needs extra macro code.

For development work, using

\usepackage[check-declarations]{expl3}

during testing is recommended, though in 'production' code one would normally omit the option.

| improve this answer | |

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.