In programming languages like Scala or Lua, we can define nested functions such as
function factorial(n)
function _fac(n, acc)
if n == 0 then
return
The answer depends on the language of course.
What happens in Scala in particular is that inner functions are compiled as they were standing outside of the scope of the function within which they are defined.
In this way the language only allows you to invoke them from the lexical scope where they are defined in, but does not actually instantiate the function multiple times.
We can easily test this by compiling two variants of the
The first one is a fairly faithful port of your Lua code:
class Function1 {
def factorial(n: Int): Int = {
def _fac(n: Int, acc: Int): Int =
if (n == 0)
acc
else
_fac(n-1, acc * n)
_fac(n, 1)
}
}
The second one is more or less the same, but the tail recursive function is defined outside of the scope of factorial
:
class Function2 {
def factorial(n: Int): Int = _fac(n, 1)
private final def _fac(n: Int, acc: Int): Int =
if (n == 0)
acc
else
_fac(n-1, acc * n)
}
We can now compile these two classes with scalac
and then use javap
to have a look at the compiler output:
javap -p Function*.scala
which will yield the following output
Compiled from "Function1.scala"
public class Function1 {
public int factorial(int);
private final int _fac$1(int, int);
public Function1();
}
Compiled from "Function2.scala"
public class Function2 {
public int factorial(int);
private final int _fac(int, int);
public Function2();
}
I added the private final
keywords to minimize the difference between the two, but the main thing to notice is that in both cases the definitions appear at the class level, with inner functions automatically defined as private
and final
and with a small decoration to ensure no name class (e.g. if you define a loop
inner function inside two different ones).
Not sure about Lua or other languages, but I can expect at least most compiled languages to adopt a similar approach.