Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 296569
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T06:33:38+00:00 2026-05-12T06:33:38+00:00

I am fairly new to to Scala and am still trying to develop a

  • 0

I am fairly new to to Scala and am still trying to develop a feel for which approaches are efficient and which might contain hidden performance costs.

If I define a (non-tail) recursive function which contains an inner function. Are multiple copies of the inner function’s functional object instantiated for each recursive call?

For example in the following:

def sumDoubles(n: Int): Int = {
    def dbl(a: Int) = 2 * a;
    if(n > 0)
        dbl(n) + sumDoubles(n - 1)
    else
        0               
}

…how many copies of the dbl object exist on the stack for a call to sumDoubles(15)?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T06:33:38+00:00Added an answer on May 12, 2026 at 6:33 am

    At the bytecode level

    def sumDoubles(n: Int): Int = {
      def dbl(a: Int) = 2 * a;
      if(n > 0)
        dbl(n) + sumDoubles(n - 1)
      else
        0               
    }
    

    is exactly the same as

    private[this] def dbl(a: Int) = 2 * a;
    
    def sumDoubles(n: Int): Int = {
      if(n > 0)
        dbl(n) + sumDoubles(n - 1)
      else
        0               
    }
    

    But don’t take my word for it

    ~/test$ javap -private -c Foo
    Compiled from "test.scala"
    public class Foo extends java.lang.Object implements scala.ScalaObject{
    public Foo();
      Code:
       0:   aload_0
       1:   invokespecial   #10; //Method java/lang/Object."":()V
       4:   return
    
    private final int dbl$1(int);
      Code:
       0:   iconst_2
       1:   iload_1
       2:   imul
       3:   ireturn
    
    public int sumDoubles(int);
      Code:
       0:   iload_1
       1:   iconst_0
       2:   if_icmple   21
       5:   aload_0
       6:   iload_1
       7:   invokespecial   #22; //Method dbl$1:(I)I
       10:  aload_0
       11:  iload_1
       12:  iconst_1
       13:  isub
       14:  invokevirtual   #24; //Method sumDoubles:(I)I
       17:  iadd
       18:  goto    22
       21:  iconst_0
       22:  ireturn
    
    }
    

    If an inner function captures an immutable variable then there’s a translation. This code

    def foo(n: Int): Int = {
      def dbl(a: Int) = a * n;
        if(n > 0)
          dbl(n) + foo(n - 1)
        else
          0               
    }
    

    Gets translated into

    private[this] def dbl(a: Int, n: Int) = a * n;
    
    def foo(n: Int): Int = {
      if(n > 0)
        dbl(n, n) + foo(n - 1)
      else
        0               
    }
    

    Again, the tools are there for you

    ~/test$ javap -private -c Foo
    Compiled from "test.scala"
    public class Foo extends java.lang.Object implements scala.ScalaObject{
    public Foo();
      Code:
       0:   aload_0
       1:   invokespecial   #10; //Method java/lang/Object."":()V
       4:   return
    
    private final int dbl$1(int, int);
      Code:
       0:   iload_1
       1:   iload_2
       2:   imul
       3:   ireturn
    
    public int foo(int);
      Code:
       0:   iload_1
       1:   iconst_0
       2:   if_icmple   22
       5:   aload_0
       6:   iload_1
       7:   iload_1
       8:   invokespecial   #23; //Method dbl$1:(II)I
       11:  aload_0
       12:  iload_1
       13:  iconst_1
       14:  isub
       15:  invokevirtual   #25; //Method foo:(I)I
       18:  iadd
       19:  goto    23
       22:  iconst_0
       23:  ireturn
    
    }
    

    If mutable variable is captured then it has to be boxed which can be more expensive.

    def bar(_n : Int) : Int = {
       var n = _n
       def subtract() = n = n - 1
    
       if (n > 0) {
          subtract
          n
       }
       else
          0
    }
    

    Gets translated into something like

    private[this] def subtract(n : IntRef]) = n.value = n.value - 1
    
    def bar(_n : Int) : Int = {
       var n = _n
       if (n > 0) {
          val nRef = IntRef(n)
          subtract(nRef)
          n = nRef.get()
          n
       }
       else
          0
    }
    
    ~/test$ javap -private -c Foo
    Compiled from "test.scala"
    public class Foo extends java.lang.Object implements scala.ScalaObject{
    public Foo();
      Code:
       0:   aload_0
       1:   invokespecial   #10; //Method java/lang/Object."":()V
       4:   return
    
    private final void subtract$1(scala.runtime.IntRef);
      Code:
       0:   aload_1
       1:   aload_1
       2:   getfield    #18; //Field scala/runtime/IntRef.elem:I
       5:   iconst_1
       6:   isub
       7:   putfield    #18; //Field scala/runtime/IntRef.elem:I
       10:  return
    
    public int bar(int);
      Code:
       0:   new #14; //class scala/runtime/IntRef
       3:   dup
       4:   iload_1
       5:   invokespecial   #23; //Method scala/runtime/IntRef."":(I)V
       8:   astore_2
       9:   aload_2
       10:  getfield    #18; //Field scala/runtime/IntRef.elem:I
       13:  iconst_0
       14:  if_icmple   29
       17:  aload_0
       18:  aload_2
       19:  invokespecial   #27; //Method subtract$1:(Lscala/runtime/IntRef;)V
       22:  aload_2
       23:  getfield    #18; //Field scala/runtime/IntRef.elem:I
       26:  goto    30
       29:  iconst_0
       30:  ireturn
    
    }
    

    Edit: adding first class functions

    To get object allocations you need to use functions in a more first class manner

    def sumWithFunction(n : Int, f : Int => Int) : Int = {
      if(n > 0)
        f(n) + sumWithFunction(n - 1, f)
      else
        0               
    }  
    
    def sumDoubles(n: Int) : Int = {
      def dbl(a: Int) = 2 * a
      sumWithFunction(n, dbl)
    }
    

    That desugars into something a bit like

    def sumWithFunction(n : Int, f : Int => Int) : Int = {
      if(n > 0)
        f(n) + sumWithFunction(n - 1, f)
      else
        0               
    }  
    
    private[this] def dbl(a: Int) = 2 * a
    
    def sumDoubles(n: Int) : Int = {
      sumWithFunction(n, new Function0[Int,Int] {
        def apply(x : Int) = dbl(x)
      })
    }
    

    Here’s the byte code

    ~/test$ javap -private -c Foo
    Compiled from "test.scala"
    public class Foo extends java.lang.Object implements scala.ScalaObject{
    public Foo();
      Code:
       0:   aload_0
       1:   invokespecial   #10; //Method java/lang/Object."":()V
       4:   return
    
    public final int dbl$1(int);
      Code:
       0:   iconst_2
       1:   iload_1
       2:   imul
       3:   ireturn
    
    public int sumDoubles(int);
      Code:
       0:   aload_0
       1:   iload_1
       2:   new #20; //class Foo$$anonfun$sumDoubles$1
       5:   dup
       6:   aload_0
       7:   invokespecial   #23; //Method Foo$$anonfun$sumDoubles$1."":(LFoo;)V
       10:  invokevirtual   #29; //Method sumWithFunction:(ILscala/Function1;)I
       13:  ireturn
    
    public int sumWithFunction(int, scala.Function1);
      Code:
       0:   iload_1
       1:   iconst_0
       2:   if_icmple   30
       5:   aload_2
       6:   iload_1
       7:   invokestatic    #36; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
       10:  invokeinterface #42,  2; //InterfaceMethod scala/Function1.apply:(Ljava/lang/Object;)Ljava/lang/Object;
       15:  invokestatic    #46; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
       18:  aload_0
       19:  iload_1
       20:  iconst_1
       21:  isub
       22:  aload_2
       23:  invokevirtual   #29; //Method sumWithFunction:(ILscala/Function1;)I
       26:  iadd
       27:  goto    31
       30:  iconst_0
       31:  ireturn
    
    }
    
    ~/test$ javap -private -c "Foo\$\$anonfun\$sumDoubles\$1"
    Compiled from "test.scala"
    public final class Foo$$anonfun$sumDoubles$1 extends java.lang.Object implements scala.Function1,scala.ScalaObject,java.io.Serializable{
    private final Foo $outer;
    
    public Foo$$anonfun$sumDoubles$1(Foo);
      Code:
       0:   aload_1
       1:   ifnonnull   12
       4:   new #10; //class java/lang/NullPointerException
       7:   dup
       8:   invokespecial   #13; //Method java/lang/NullPointerException."":()V
       11:  athrow
       12:  aload_0
       13:  aload_1
       14:  putfield    #17; //Field $outer:LFoo;
       17:  aload_0
       18:  invokespecial   #20; //Method java/lang/Object."":()V
       21:  aload_0
       22:  invokestatic    #26; //Method scala/Function1$class.$init$:(Lscala/Function1;)V
       25:  return
    
    public final java.lang.Object apply(java.lang.Object);
      Code:
       0:   aload_0
       1:   getfield    #17; //Field $outer:LFoo;
       4:   astore_2
       5:   aload_0
       6:   aload_1
       7:   invokestatic    #37; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
       10:  invokevirtual   #40; //Method apply:(I)I
       13:  invokestatic    #44; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
       16:  areturn
    
    public final int apply(int);
      Code:
       0:   aload_0
       1:   getfield    #17; //Field $outer:LFoo;
       4:   astore_2
       5:   aload_0
       6:   getfield    #17; //Field $outer:LFoo;
       9:   iload_1
       10:  invokevirtual   #51; //Method Foo.dbl$1:(I)I
       13:  ireturn
    
    public scala.Function1 andThen(scala.Function1);
      Code:
       0:   aload_0
       1:   aload_1
       2:   invokestatic    #56; //Method scala/Function1$class.andThen:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
       5:   areturn
    
    public scala.Function1 compose(scala.Function1);
      Code:
       0:   aload_0
       1:   aload_1
       2:   invokestatic    #60; //Method scala/Function1$class.compose:(Lscala/Function1;Lscala/Function1;)Lscala/Function1;
       5:   areturn
    
    public java.lang.String toString();
      Code:
       0:   aload_0
       1:   invokestatic    #65; //Method scala/Function1$class.toString:(Lscala/Function1;)Ljava/lang/String;
       4:   areturn
    
    }
    

    The anonymous class gets a lot of code copied in from the Function1 trait. That does have a cost in terms of class loading overhead, but doesn’t affect the cost of allocating the object or executing the code. The other cost is the boxing and unboxing of the integer. There’s hope that that cost will go away with 2.8’s @specialized annotation.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm still fairly new to Scala, and I'm discovering new and interesting ways for
I fairly new to JQuery and perhaps trying to achieve something that might be
I'm fairly new to Scala, and am writing an API library and trying to
I am fairly new to Scala. I am trying to understand how/if scala does
I am fairly new to Scala and am trying to understand the collections hierarchy.
I fairly new to YII and still trying to understand it all. However from
I'm fairly new to Lift/Scala but like the ideas of less code writing and
Fairly new to Objective C and trying to work within Storyboards given it's the
I am fairly new to scala and I have the need to convert a
Fairly new to jquery so I might be making a simple mistake but I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.