Arithmetics in LuaLaTeX

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).


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}