What does () mean in Scala? - scala

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.

Related

Why _ (underscore) of type Unit and () treated differently?

I have a method which returns Future[Unit], so when I call whenReady
These two options work: whenReady(doItAsync())(_ => {}) and whenReady(doItAsync()) { _ => }
but this doesn't: whenReady(doItAsync())(() => {})
Are not _ of type Unit and empty params list equivalent in this case?
Although type Unit is similar to void from other languages it is not exactly the same.
This particular trouble comes from a limitation in Java (and thus Scala) generics implementation: they are implemented using type erasure. Particularly it means that generic method can't change the number of arguments. Now what happens when type parameter is Unit? We still must have the same number of arguments and also can't magically change return type to return nothing (void) because this will be a different signature. So the answer is to use some fake type with only fakes values: scala.runtime.BoxedUnit. And thus Unit might represent actual parameter that you don't need but has to be there. And so type signature () => {} doesn't match that because it takes no parameters.
Note also that in Java itself there is the same issue and thus there is a similar thing called java.lang.Void
Update:
To make the point more clear consider following generic vs. non-generic code:
def foo(f: () => String) = println(f())
def fooGeneric[T](arg: T, f: (T) => String) = println(f(arg))
foo(() => "Non-generic")
fooGeneric[Unit]((), (_) => "generic")
Note that also logically fooGeneric[Unit] is the same as foo, you still have to pass first argument and pass function that accept an (useless) argument as the second parameter.
Are not _ of type Unit and empty params list equivalent in this case?
No. _ => {} defines a function with single parameter (which happens in this context to have type Unit), () => {} defines a function with no parameters. Their types are Unit => Unit and () => Unit, or without syntactic sugar Function1[Unit, Unit] and Function0[Unit]. These types aren't actually related: neither of them is a subtype of the other.
You can write a single-argument anonymous function taking Unit with () using pattern-matching: { case () => ... }. But there is no point to doing that.

What is the purpose of passing `Unit` to a function in Scala

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"

Usage of () vs Unit when creating a function to call a parameterless constructor

I came across a situation recently where I needed to create a function to call a parameterless constructor. The following code demonstrates
class NoNumber() {}
val create : Unit => NoNumber = Unit => new NoNumber()
val nn = create()
This code compiles and creates a new instance of NoNumber and assigns it to nn as expected. However, there are a couple of things I wasn't expecting.
my first attempt (which doesn't compile), was as follows
val create : Unit => NoNumber = () => new NoNumber()
Why is it that Unit works and () does not work in the above example? I was under the impression that () was the one and only instance of Unit and as such the () seems to make the most sense.
Secondly I see the following warning when compiling the code
Warning:(3, 22) Adaptation of argument list by inserting () has been
deprecated: this is unlikely to be what you want. signature:
Function1.apply(v1: T1): R given arguments: after
adaptation: Function1((): Unit) lazy val nn = create()
What does this mean and how should the code be changed to remove the warning?
Thanks
Unit => A and () => A are not the same thing.
Unit => A is syntactic sugar for Function1[Unit, A], a function with a single argument of Unit that returns A. You're confusing the type Unit with the value () that has type Unit. i.e., you cannot say:
scala> val a: () = ()
<console>:1: error: '=>' expected but '=' found.
val a: () = ()
^
() => A is syntactic sugar for Function0[A], a parameter-less function that returns A. They are similar, but not quite the same.
As for the warning with this:
val create : Unit => NoNumber = Unit => new NoNumber()
If you were to have val nn = create, then nn would actually be a function, Unit => NoNumber. When you have:
val nn = create()
You are actually are doing:
val nn = create.apply(())
Confusing, yes? Hence, the deprecation warning. The former is simply passing () to a Function1[Unit, NoNumber], but it looks awfully like a Function0. What you probably want is:
val create : () => NoNumber = () => new NoNumber()

What is difference between Unit and ()?

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.

What is the difference between () => Int and Unit => Int? What on earth is the type of "()" in Scala?

I think I still have not fully understood what type () represent during function definition. So I can't come up concrete example of each case: () => Int; Unit=> Int.
Can someone give me an easy example of function literal with type () => Int and type Unit=>Int respectively? After that, I think I can learn what () is exactly is.
Thanks
*EDIT: * destin says they are same. But the following test seems to indicate otherwise: () can't be used in place expecting Unit.
scala> def inCase[A] ( b :Boolean, ifTrue : Unit => A, ifFalse : Unit => A ) : A =
| b match {
| case True => ifTrue()
| case _ => ifFalse()
| }
inCase: [A](b: Boolean, ifTrue: Unit => A, ifFalse: Unit => A)A
scala> inCase( True, () => 1, () => -1 )
<console>:11: error: type mismatch;
found : () => Int
required: Unit => ?
inCase( True, () => 1, () => -1 )
() in a function type is not a type at all, nor is it a value. () => is simply syntax to indicate a function that takes zero arguments. See the BNF notation in section 3.2.9 of the Scala specification.
When you see (Type1, Type2, Type3) => Type4, the () surrounds all of the argument types that the function takes. (Type1, Type2, Type3) is not a tuple type here -- the parentheses are just syntax. So when you see () => Type4, you have an argument list that takes zero parameters. Single argument functions are special, in that you can omit the parentheses.
Functions with no arguments, specified without the (), simply => Type4 are by-name parameters (which look like values, but are implemented as functions that get called implicitly when you try to evaluate their value.) They're defined in section 4.6.1 of the spec.
Parentheses can mean a bunch of other things in other contexts.
Parentheses in a function type declaration anywhere other than right before the => indicate a tuple type, and these can't be empty. (Section 3.2.5)
Empty parentheses () are the return value of functions whose return type is Unit. (Section 12.2.3) This actually becomes a real value in certain contexts, for example println(println("foo")) will print
foo <--- the argument to the inner println
() <--- the argument to the outer println
Parentheses are also syntax for function arguments when you make a function call, something that you're probably already aware of. These can be empty. They're defined in section 6.6 of the spec.
Parentheses are also syntax for function arguments when you define a method using def. These are described in section 4.6 of the spec.
Parentheses are also the syntax for creating tuple values (Section 6.9). If they're not empty, you get a TupleN where N is the number of values inside of the parentheses. If they are empty, the type of this expression is Unit. (Sections 6.9, 12.2.3)
I changed your example, to have both notations (and to use the more popular Boolean):
def inCase[A] (b:Boolean, ifTrue: ()=> A, ifFalse: Unit => A): A = b match {
case true => ifTrue ()
case _ => ifFalse ()
}
inCase (true, () => 1, (Unit) => -1)
Then I have to use the same notation on the calling site.
() is the only instance of the type Unit.
So () => Int as signature of a partial function means: takes the Unit object, does something and gives an Int.
Unit => Int means: takes any Unit object, does something and gives an Int.
Edit
"Scala’s Unit type roughly corresponds to void in Java; it is used whenever a function does not return an interesting result. In fact, because Scala is an expressionoriented language, every function returns some result. If no explicit return expression is given, the value (), which is pronounced “unit”, is assumed. This value is
of type Unit. Unit-returning functions are also called procedures. Here’s a more
“expression-oriented” formulation of the swap function in the first implementation
of quicksort, which makes this explicit:
def swap(i: Int, j: Int): Unit = {
val t = xs(i); xs(i) = xs(j); xs(j) = t
()
}
The result value of this function is simply its last expression – a return keyword is
not necessary. Note that functions returning an explicit value always need an “=”
before their body or defining expression."
Source: Programming in Scala - Martin Odersky (Page 14)