Is nested function efficient?

后端 未结 5 1338
暖寄归人
暖寄归人 2021-02-12 21:48

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          


        
5条回答
  •  傲寒
    傲寒 (楼主)
    2021-02-12 22:40

    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.

提交回复
热议问题