Search code examples
scalatype-inferenceexpansionlanguage-specifications

What is a "Maximal Sub-expression" in Scala 2.8 specification §6.26.5 Eta Expansion?


In Scala 2.8 language specification, §6.26.5 Eta Expansion, it states that we need a maximal sub-expression, however, no definition of this can be found. Can someone clarify this?


Solution

  • Consider the following:

    def list1 = { println("1st list!"); List(1, 2, 3) }
    def list2 = { println("2nd list!"); List(4, 5) }
    def empty = { println("Empty string!"); "" }
    

    And then:

    scala> val foo = (list1 ++ list2).foldLeft(empty) _
    Empty string!
    1st list!
    2nd list!
    foo: ((String, Int) => String) => String = <function1>
    

    Here (list1 ++ list2).foldLeft(empty) is the expression of method type, and list1 ++ list2 and empty are its maximal sub-expressions, which are just literally its largest constituent expressions. We're using _ to force eta expansion, but in some contexts that wouldn't be necessary.

    It makes sense that we wouldn't want list1 ++ list2 to be evaluated every time we use the function foo, for example, and that's what the conversion described in §6.26.5 accomplishes—it makes sure that the sub-expressions are evaluated and saved once, before the function is created.

    If we'd started the REPL with -print, we'd have seen the following (reformatted for clarity):

    $read$$iw$$iw.this.foo = {
      <synthetic> val eta$0$1: String = $line5.$read$$iw$$iw.empty();
      <synthetic> val eta$1$1: List = $line3.$read$$iw$$iw.list1().++(
        $line4.$read$$iw$$iw.list2(),
        immutable.this.List.canBuildFrom()
      ).$asInstanceOf[List]();
      {
        (new anonymous class anonfun$1(eta$0$1, eta$1$1): Function1)
      }
    };
    

    If you're ever wondering what exactly constitutes a sub-expression in a given situation, this is an easy way to check—just look for the lines starting with <synthetic> val.