Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is " : Unit = " added when defining a method in Scala?

Guys I'm trying to learn Scala, and I use IntelliJ IDEA to do it, the thing is I'm seeing a code on internet where methods are defined as below :

def move(dx: Int, dy: Int, dz: Int) {}

but when I try to define methods in IntelliJ IDEA, it keeps adding automatically before the curly brackets this : "Unit =" and I don't know what does it means ? like this :

 def move(dx: Int, dy: Int, dz: Int): Unit ={}

thank you for your help

like image 496
Ait Zaid Avatar asked Dec 19 '22 00:12

Ait Zaid


2 Answers

The procedure syntax

def methodName(arg1: Type1, ..., argN: TypeN) {
  /* method body */
}

is merely syntactic sugar for methods with return type Unit. It is equivalent to

def methodName(arg1: Type1, ..., argN: TypeN): Unit = {
  /* method body */
}

The type Unit contains a single value: the empty tuple (). So, unless the method exits abnormally by throwing an exception or error, it returns the nullary tuple (). This in turn means that the return value of the method does not really matter, because it contains no meaningful information beyond the fact that the method terminated. It is therefore usually used for methods that are executed solely for their side effects.

As Emre Sevinç has rightly pointed out, the procedure syntax should no longer be used, it helps you to avoid typing six characters, but makes the syntax less consistent as a whole, so it's not really worth it.


This is less an answer, more an attempt to sort out the confusion about Unit vs void.

While on the first glance Unit seems to be used in the same way void is used in languages like C, it is actually quite different, because Unit actually does have a value, whereas there are usually (confusingly) no values of type void in C-like languages. This makes it possible to construct more complex values from Unit. For example,

List( (), (), (), (), () )

is a value of type List[Unit], that can represent natural numbers. Similarly,

Left( () ); Right( () )

are values of type Either[Unit, Unit], that can represent Boolean values. These two examples are obviously contrived. A more substantial and practical example is provided in "Functional Programming in Scala" (P. Chiusano, R. Bjarnason), where () comes in handy when deriving map from map2 in the Applicative[F[_]] typeclass:

def map[B](fa: F[A])(f: A => B): F[B] =
  map2(fa, point( () ))((a, _) => f(a))

//                ^
//                | 
//                Here is it 

(This is not supposed to be comprehensible without context: I just want to provide a concrete example that () can be useful to define very fundamental methods in very general frameworks)

From a high-level perspective, it is a Really Good Thing to have the type Unit in the language, because it makes the category of types and functions cartesian closed (it's the "terminal object" from the first part of definition). This makes the language much more consistent and symmetrical as a whole.

like image 137
Andrey Tyukin Avatar answered Dec 27 '22 14:12

Andrey Tyukin


According to Scala Style Guide's procedure syntax:

Avoid the procedure syntax, as it tends to be confusing for very little gain in brevity.

// don't do this
def printBar(bar: Baz) {
  println(bar)
}

// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}
like image 27
Emre Sevinç Avatar answered Dec 27 '22 14:12

Emre Sevinç