def foo(x: Int, f: Unit => Int) = println(f()) foo(2, { Unit => 3 + 4 }) // case 1 def loop: Int = 7 foo(2, loop) // does not compile changing loop to // case 2 def loop(): Int = 7 foo(2, loop) // does not compile changing loop to // case 3 def loop(x: Unit): Int = 7 // changing according to Don's Comments foo(2, loop) // compiles and works fine
Shouldn't case 1
and case 2
also work? Why are they not working?
Defining foo as
def foo(x: Int, y: () => Int)
then case 2
works but not case 1
.
Arent they all supposed to work, defining the functions either way?
Also I think () => Int
in foo is a bad style, y:=> Int
does not work. Comments?
Functions do not have declared return types. A function without an explicit return statement returns None . In the case of no arguments and no return value, the definition is very simple. Calling the function is performed by using the call operator () after the name of the function.
to answer your question concerning calling functions without their parameters. it's possible for functions where default values for all parameters are set e.g.: def foo(bar = "default string"): print(bar) print(foo()) # prints: default string print(foo("hello world!")) # prints: hello world!
A nullary or niladic function.
A parameterless method is a function that does not take parameters, defined by the absence of any empty parenthesis. Invocation of a paramaterless function should be done without parenthesis. This enables the change of def to val without any change in the client code which is a part of uniform access principle.
Scala distinguishes between the following things:
None of these are equivalent, although as a convenience Scala allows you to elide empty parameter lists. (Incidentally, two empty parameter lists are also not the same.)
So, even though Unit
is written ()
, this is not the same as the function argument parens ()
for a function or method. Instead, think of ()
as a Tuple0
.
So, if you say f: Unit => Int
, what you mean is "f takes one parameter, but it's a really boring parameter because it is Unit
, which must always be the same boring Tuple0
value ()
". What you're writing is really short for f: (Unit) => Int
.
If you say f: () => Int
, then you mean that "f takes no parameters and produces an Int
".
If you say f: => Int
, then you mean that "delay the execution of whatever statement produces an Int
value until we use it in this code (and re-evaluate it each time)". Functionally, this ends up being basically the same as f: () => Int
(and internally is converted into the same Function0
class), but it has a different usage, presumably to allow for a more compact form of closures (you always omit the =>
in the calling code).
()=>Int is Function0[Int] while Unit=>Int is Function1[Unit,Int]
scala> val function0: () => Int = () => 5 function0: () => Int = <function0> scala> val function1: Unit => Int = u => 5 function1: (Unit) => Int = <function1> scala> function0() res0: Int = 5 scala> function1("anything") res1: Int = 5 scala> function1(100) res2: Int = 5 scala>
Also note that () is an object of Unit
scala> function1(()) res11: Int = 5 scala> function1 () res12: Int = 5 scala> function1() res13: Int = 5 scala> val unit = () unit: Unit = () scala> function1(unit) res15: Int = 5 scala> function1 apply unit res16: Int = 5 scala>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With