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

1

7

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?

Canaanite answered 7/1, 2014 at 10:52 Comment(0)
M
4

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.

Mimir answered 7/1, 2014 at 19:41 Comment(4)
"which are just literally its largest constituent expressions." still a bit vague I think. Is it correct to say that, if we had pure FP, this would correspond to foldLeft(list1 ++ list2)(empty) _ , hence, ++(list1,list2) is the maximal expression depending on 2 smaller subexpressions (list1 and list2)?Canaanite
Also, is it completely off to say that this will most often simply be the argument expressions in their entireties?Canaanite
The idea of "method types" that don't exist as types of values (and "expressions of method types" that require this kind of conversion to be used as values) is pretty far from pure FP in the first place. In your pure FP example, foldLeft is already a function, and there's no need for this kind of conversion. In general the maximal sub-expressions are going to be the expression that the method is called on together with any arguments in other parameter lists.Mimir
That last bit helps :) +1 for the -print tip!Canaanite

© 2022 - 2024 — McMap. All rights reserved.