Search code examples
scalascala-3

What is the difference between "with" and "new" for context parameters in scala?


Is there a difference if I define a given value for a context parameter using the keyword with or using new?

for example is there a difference between human and cat givens?

 trait Talker:
  def talk:String

given human:Talker with
  def talk:String = "I am human"

given cat:Talker = new:
  def talk:String = "I am cat, meow"

def run(using t:Talker):Unit =
  println(t.talk)

Solution

  • There is a clear difference on compiled class level when using new vs with.

    When using with, there is a dedicated class created, we can see it in the de-compiled code. Here is how it looks in Java

    public final class Talker$package {
       public static final class human$ implements Talker, Serializable {
          public static final Talker$package.human$ MODULE$ = new Talker$package.human$();
    
          private Object writeReplace() {
             return new ModuleSerializationProxy(Talker$package.human$.class);
          }
    
          public String talk() {
             return "I am human";
          }
       }
    }
    

    It has a dedicated class human$ that extends Talker.

    And on the other hand when using new for cat, we have an anonymous class.

    public final class Talker$package {
       public static Talker cat() {
          return Talker$package$.MODULE$.cat();
       }
    }
    

    where MODULE$.cat() eventually points to following

    Talker var5 = new Talker() {
        public String talk() {
           return "I am cat, meow";
        }
    };