Referring to following question in SO, what is the usefulness of passing Unit to a function instead of () or vice versa?
Functions without arguments, with unit as argument in scala
From what I can tell you would like to know what is the difference between these two method definitions, and why one would use Unit over () in the function parameter.
def func1(f:Unit=>String) = {
println(f)
}
def func2(f:()=>String) = {
println(f)
}
the difference can be highlighted by looking at the output of this code:
func1(Unit => "hello")
func2(() => "hello" )
you may be surprised to see this output:
<function1>
<function0>
Unit=>String is actually a function with 1 parameter. While ()=>String is a function with 0 parameters.
In Scala () could mean two things
it could be used for Unit e.g. val x:Unit = ()
it can be use to represent no parameters.
In func2, it is a function with no parameters.
"Unit" in func1 is actually the abstract class in the scala package (of which there is only one value "Unit" or "()"). So when the function Unit => String was defined, what we defined was a function that takes a parameter of type Unit as a parameter, and returns a value. Not a Function that takes no parameters.
A final tweak to the code to highlight the difference:
def func1(f:Unit=>String) = {
println(f(Unit))
}
def func2(f:()=>String) = {
println(f())
//println(f(Unit)) - does not compile
}
func1(Unit => "hello")
func2(() => "hello" )
Will output hello twice.
I'd suggest that func2 or () is generally what people want, and not func1 or "Unit"
Related
What is still unclear for is what's the advantage by-name parameters over anonymous functions in terms of lazy evaluation and other benefits if any:
def func1(a: => Int)
def func2(a: () => Int)
When should I use the first and when the second one?
This is not the copy of What's the difference between => , ()=>, and Unit=>
Laziness is the same in the both cases, but there are slight differences. Consider:
def generateInt(): Int = { ... }
def byFunc(a: () => Int) { ... }
def byName(a: => Int) { ... }
// you can pass method without
// generating additional anonymous function
byFunc(generateInt)
// but both of the below are the same
// i.e. additional anonymous function is generated
byName(generateInt)
byName(() => generateInt())
Functions with call-by-name however is useful for making DSLs. For instance:
def measured(block: ⇒ Unit): Long = {
val startTime = System.currentTimeMillis()
block
System.currentTimeMillis() - startTime
}
Long timeTaken = measured {
// any code here you like to measure
// written just as there were no "measured" around
}
def func1(a: => Int) {
val b = a // b is of type Int, and it`s value is the result of evaluation of a
}
def func2(a: () => Int) {
val b = a // b is of type Function0 (is a reference to function a)
}
An example might give a pretty thorough tour of the differences.
Consider that you wanted to write your own version of the veritable while loop in Scala. I know, I know... using while in Scala? But this isn't about functional programming, this is an example that demonstrates the topic well. So hang with me. We'll call our own version whyle. Furthermore, we want to implement it without using Scala's builtin while. To pull that off we can make our whyle construct recursive. Also, we'll add the #tailrec annotation to make sure that our implementation can be used as a real-world substitute for the built-in while. Here's a first go at it:
#scala.annotation.tailrec
def whyle(predicate: () => Boolean)(block: () => Unit): Unit = {
if (predicate()) {
block()
whyle(predicate)(block)
}
}
Let's see how this works. We can pass in parameterized code blocks to whyle. The first is the predicate parameterized function. The second is the block parameterized function. How would we use this?
What we want is for our end user to use the whyle just like you would the while control structure:
// Using the vanilla 'while'
var i = 0
while(i < args.length) {
println(args(i))
i += 1
}
But since our code blocks are parameterized, the end-user of our whyle loop must add some ugly syntactic sugar to get it to work:
// Ouch, our whyle is hideous
var i = 0
whyle( () => i < args.length) { () =>
println(args(i))
i += 1
}
So. It appears that if we want the end-user to be able to call our whyle loop in a more familiar, native looking style, we'll need to use parameterless functions. But then we have a really big problem. As soon as you use parameterless functions, you can no longer have your cake and eat it too. You can only eat your cake. Behold:
#scala.annotation.tailrec
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
if (predicate) {
block
whyle(predicate)(block) // !!! THIS DOESN'T WORK LIKE YOU THINK !!!
}
}
Wow. Now the user can call our whyle loop the way they expect... but our implementation doesn't make any sense. You have no way of both calling a parameterless function and passing the function itself around as a value. You can only call it. That's what I mean by only eating your cake. You can't have it, too. And therefore our recursive implementation now goes out the window. It only works with the parameterized functions which is unfortunately pretty ugly.
We might be tempted at this point to cheat. We could rewrite our whyle loop to use Scala's built-in while:
def whyle(pred: => Boolean)(block: => Unit): Unit = while(pred)(block)
Now we can use our whyle exactly like while, because we only needed to be able to eat our cake... we didn't need to have it, too.
var i = 0
whyle(i < args.length) {
println(args(i))
i += 1
}
But we cheated! Actually, here's a way to have our very own tail-optimized version of the while loop:
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
#tailrec
def whyle_internal(predicate2: () => Boolean)(block2: () => Unit): Unit = {
if (predicate2()) {
block2()
whyle_internal(predicate2)(block2)
}
}
whyle_internal(predicate _)(block _)
}
Can you figure out what we just did?? We have our original (but ugly) parameterized functions in the inner function here. We have it wrapped with a function that takes as arguments parameterless functions. It then calls the inner function and converts the parameterless functions into parameterized functions (by turning them into partially applied functions).
Let's try it out and see if it works:
var i = 0
whyle(i < args.length) {
println(args(i))
i += 1
}
And it does!
Thankfully, since in Scala we have closures we can clean this up big time:
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
#tailrec
def whyle_internal: Unit = {
if (predicate) {
block
whyle_internal
}
}
whyle_internal
}
Cool. Anyways, those are some really big differences between parameterless and parameterized functions. I hope this gives you some ideas!
The two formats are used interchangeably, but there are some cases where we can use only one of theme.
let's explain by example, suppose that we need to define a case class with two parameters :
{
.
.
.
type Action = () => Unit;
case class WorkItem(time : Int, action : Action);
.
.
.
}
as we can see, the second parametre of the WorkItem class has a type Action.
if we try to replace this parameter with the other format =>,
case class WorkItem1(time : Int, s : => Unit) the compiler will show a message error :
Multiple markers at this line:
`val' parameters may not be call-by-name Call-by-name parameter
creation: () ⇒
so as we have see the format ()=> is more generic and we can use it to define Type, as class field or method parameter, in the other side => format can used as method parameter but not as class field.
A by-name type, in which the empty parameter list, (), is left out, is only
allowed for parameters. There is no such thing as a by-name variable or a
by-name field.
You should use the first function definition if you want to pass as the argument an Int by name.
Use the second definition if you want the argument to be a parameterless function returning an Int.
I've found a Scala code snippet which declares a method <init> and puts () right below the invocation.
I have a question about line number 5. What does () mean here?
(() => {
final class $anon extends MutableProjection {
def <init>() = {
super.<init>();
()
};
...
};
new $anon()
})
Here is a code with full example.
Every Scala function has a return type. By convention (and highly encouraged by some language features), functions that don't need to return anything have a return type called Unit, which has a singleton value written as ().
The last expression in a function body is its return value. That author made this be () to cause the compiler to infer that the return type should be Unit. But it would have been more clear to just do that with a type annotation. If a function's return type is Unit, Scala will implicitly return () from the function no matter what the last statement in the body is. So this
def <init>() = {
super.<init>()
()
}
could be written equivalently as
def <init>(): Unit = super.<init>()
() can meean a few things, depending on context.
As a value, it is an empty tuple, or the singleton type. It's type is Unit.
It can denote a function or method that takes no parameters, such as:
def foo() = "Hello world"
Note that when writing an anonymous function, the () is by itself but still means a function with no parameters.
val x = () => 2
The type of x is () => Int, a function taking no parameters and returning an int.
As a source of infinite confusion, you can get examples like this:
val y = () => ()
The type of y here is () => Unit, a function of no parameters returning Unit, not Unit => Unit, which would be writen as val z = (x:Unit) => (), and called like z(())
The unit vs empty parameter distinction has been awkward for me in the past so hopefully that demystifies some of it.
I thought () was the only instance of Unit in Scala.
When I try to set a function to anonymous func variable, this works:
def some(a:Unit):Unit = {
println("Enigma")
}
val func:Unit => Unit = some
func()
But this does not:
def some():Unit = {
println("Enigma")
}
val func:Unit => Unit = some
An empty parameter list as in your second example is not the same as Unit which is a value that represents something like null. () doesn't always mean Unit in every context,
specifically the instance where your dealing with an argument list.
This is because your second example is a method without any arguments.
Take a look at the types that results:
some: (a: Unit)Unit
some: ()Unit
which would be written in a type assignment as
Unit => Unit
() => Unit
In the second case, the parens are not acting as Unit, but instead are merely the string representation of an argumentless function. () is only symbolic as Unit in the context of a method. In a type signature you use Unit, because () is expected to be a function with no arguments
def some(): Unit
The () here is not the instance of Unit, just no argument.
The normal usage of () is
def some(): Unit = ()
But if you enter Some() in Scala interpreter, you will get
scala> Some()
res0: Some[Unit] = Some(())
Well, it's strange, seems that Scala rewrites Some() to Some(()). Anyway, I will not write code like this, it makes things hard to understand.
I'm trying to write a simple converter that turns a java.util.Function into a scala.Function1:
def toScalaProducer[T](f: JavaFunction0[T]) : => T = => f()
Here is another variant that works well:
def toScalaFunction[T](f: JavaFunction0[T]) : () => T =
() => f.apply()
The problem is that I want to pass the converted function into an existing Scala API, but that API only accepts arguments of type => T, not of type () => T.
Is there a way to write the toScalaProducer function?
() => T is the type for a function that takes no arguments and returns something of type T
=> T is the type for a value T that is lazily evaluated. For instance:
def myFunc(t: => Int): Unit = {
// Do something with t
}
myFunc(reallyExpensiveFunctionProducingAnInt())
Here, reallyExpensiveFunctionProducingAnInt could take a long time to run, but will only be executed if the value t is used in myFunc. If you just use type Int instead of => Int it will have been called before myFunc is entered.
Have a look here for more information: Scala's lazy arguments: How do they work?
So if your toScalaProducer function simply executed the Java function and had a return value of T, it should work fine with the API. It will only be executed when needed, so in many ways will behave like passing a function.
A few times I saw a Scala code like that:
object Doer{
def doStuff(op: => Unit) {
op
}
}
Invoked in this way:
Doer.doStuff{
println("Done")
}
What is strange for me is how a function is passed to another function as just a block of code between curly braces. And there is even no parentheses that normally mark the beginning and end of argument list.
What is the name of this Scala syntax/feature? In what cases I can use it? Where is it documented?
This is called either a nullary function or a thunk, and is an example of call-by-name evaluation: http://www.scala-lang.org/old/node/138
You can use nullaries pretty much anywhere you have a parameter list. They are basically just syntactic sugar around zero-argument functions that make them look like ordinary values, and are invoked whenever they are referenced.
So
def doSomething(op: => Unit) {
op
}
doSomething {
println("Hello!")
}
is exactly the same as:
def doSomething(op: () => Unit) {
op()
}
doSomething(() => println("Hello!"))
The one thing to keep in mind with nullaries is they are invoked every time they are referenced, so something like:
def foo(op: => Int) = op + op
foo {
println("foo")
5
}
will print "foo" twice.
Edit: To expand on Randall's comment, one of the big ways that a nullary function differs from a zero-arg function is that nullaries are not first-class values. For example, you can have a List[() => Int] but you cannot have a List[=> Int]. And if you had something like:
def foo(i: => Int) = List(i)
you are not adding the nullary function to the list, only its return value.