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?
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
.
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 © 2022 - 2024 — McMap. All rights reserved.