So I’ve been trying to puzzle through the various ways you can define stuff in Scala, complicated by my lack of understanding of the way {} blocks are treated:
object NewMain extends Thing{
def f1 = 10
def f2 {10}
def f3 = {10}
def f4() = 10
def f5() {10}
def f6() = {10}
def f7 = () => 10
def f8 = () => {10}
def f9 = {() => {10}}
def main(args: Array[String]){
println(f1) // 10
println(f2) // ()
println(f3) // 10
println(f4) // 10
println(f4()) // 10
println(f5) // ()
println(f5()) // ()
println(f6) // 10
println(f6()) // 10
println(f7) // <function0>
println(f7()) // 10
println(f8) // <function0>
println(f8()) // 10
println(f9) // <function0>
println(f9()) // 10
}
}
Presumably some of these are equivalent, some of these are syntactic sugar for others, and some are things I should not use, but I can’t for the life of me figure it out. My specific questions are:
-
How is it that
println(f2)andprintln(f5())givesunit? Isn’t the last item in the block10? How is it different fromprintln(f3()), which gives10? -
If
println(f5)givesunit, shouldn’tprintln(f5())be invalid, sinceunitis not a function? The same applies toprintln(f6)andprintln(f6()) -
Of all the ones which print 10:
f1,f3,f4,f4(),f6,f6(),f7(),f8(),f9(),
is there any functional difference between them (in terms of what it does) or usage differences (in terms of when I should use which)? Or are they all equivalent?
To answer your questions in order:
f2andf5()returnUnitbecause scala takes anydefwithout an “=” to be a function that returnsUnit, regardless of what the last item in a block is. This is a good thing, since otherwise it would not be rather verbose to define a function that does not return anything.println(f5())is valid, even though it returnsUnitbecause in scalaUnitis a valid object, though admittedly not one you can instantiate.Unit.toString()is a valid, if not generally useful, statement, for example.10are the same. Most importantly,f7,f8, andf9are actually functions that return functions that return10, rather than returning10directly. When you declaredef f8 = () => {10}, you are declaring a functionf8that takes no arguments and returns a function that takes no arguments and returns a single integer. When you invokeprintln(f8)thenf8dilligently returns that function to you. When you callprintln(f8())it returns the function, then immediately invokes it.f1,f3,f4, andf6are all essentially equivalent in terms of what they do, they vary only in terms of style.As “user unknown” indicates, the braces are only important for scoping purposes and do not make any difference in your use case here.