7

I have the following code.

\documentclass{article}
\usepackage{luacode} 
\begin{luacode}
function fact(n)
 if n == 0 then
          return 1
        else
           tex.sprint ( n * fact(n - 1) )
        end
      end
\end{luacode}
\newcommand\factorial[1]{\directlua{fact(#1)}}
\begin{document}
\factorial{5}
\end{document}

This throws the error that attempt to perform arithmetic on a nil value. Where is the problem?

  • Your lua function returns nothing if n!=0. So fact(n-1) is nil. – Alain Merigot Jul 18 at 11:21
9

With the code you posted, evaluating fact(5) causes the following expression to be evaluated by the Lua interpreter inside LuaTeX:

tex.sprint(5*fact(4))

which is

tex.sprint(
  5*tex.sprint(
    4*fact(3)))

which is

tex.sprint(
  5*tex.sprint(
    4*tex.sprint(
      3*fact(2))))

which is

tex.sprint(
  5*tex.sprint(
    4*tex.sprint(
      3*tex.sprint(
        2*fact(1)))))

which is

tex.sprint(
  5*tex.sprint(
    4*tex.sprint(
      3*tex.sprint(
        2*tex.sprint(
          1*fact(0))))))

which is

tex.sprint(
  5*tex.sprint(
    4*tex.sprint(
      3*tex.sprint(
        2*tex.sprint(
          1*1)))))

The first fact() call to return a value when the Lua interpreter evaluates fact(5) is thus fact(0). According to your definition of fact(), this evaluates to the Lua integer 1. Then 1*1 is evaluated, results in the Lua integer 1, and the next recursion level thus tries to evaluate 2*tex.sprint(1). This is where your code fails, since tex.sprint(1) evaluates to nil and 2*nil isn't a valid arithmetic expression (tex.sprint() prints contents to the DVI or PDF output, but as a Lua function, returns nil). Because of this error, the recursion stops.

You can fix the problem this way:

\documentclass{article}
\usepackage{luacode}

\begin{luacode}
function fact(n)
 if n == 0 then
    return 1
 else
    return n * fact(n - 1)
 end
end

function printfact(n)
  tex.sprint (fact(n))
end

\end{luacode}

\newcommand*{\factorial}[1]{\directlua{printfact(#1)}}

\begin{document}
\factorial{5}
\end{document}

which produces the following output (DVI or PDF):

enter image description here

In this code, the fact() function always returns a Lua number (not nil), while printfact() writes the corresponding number to the TeX output file (DVI or PDF).

4

Here's my recommendation: Move the tex.sprint directive to the definition of the \factorial macro, and use return, not tex.sprint, to return numbers from the fact function.

Note also that since there are no TeX-special characters (such as #, %, and \) in the setup of the Lua function fact, one can define it via a \directlua call, as is done in the code below. No need, in this case, to load the luacode package.

\documentclass{article}
\directlua{
function fact ( n )
   if n == 0 or n == 1 then
       return 1
   else
       return ( n * fact (n - 1) )
   end
end
}

\newcommand\factorial[1]{\directlua{tex.sprint(fact(#1))}}

\begin{document}
\factorial{5}
\end{document}
1
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function printfact(n)
  if n == 0 then n = 1 end
  for i=2, n-1 do n=n*i end
  tex.sprint(n)
end
\end{luacode}
\newcommand*\factorial[1]{\directlua{printfact(#1)}}

\begin{document}
    \factorial{5}
\end{document}

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.