4

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

2
  • So Unit is a type ? like void ? Commented Apr 6, 2018 at 10:11
  • Yes. It is a type. You will find where you might find void in other languages. Unlike void the type Unit has a single member: () Commented Apr 6, 2018 at 13:22

6 Answers 6

7

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you for taking this time to explain Void vs Unit, but just to be sure that I have understood : if I have two methodes, So both of this methodes have a type Unit then, So those two methodes have two different values ? , or it is the same value for both of them ? thank you;
@AitZaid For the single value () it holds: () == (), so if two methods have return type Unit, then they return equal values. I'm not sure whether one can instantiate a second instance u of type Unit through some reflection or classloader trickery, such that !( () eq u). It seems rather difficult to do, because Unit is final abstract and has no constructors... So, for all practical purposes you can safely assume that there is only one single value () of type Unit.
4

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) } 

1 Comment

thanks you , the think that I'd like to understand is what Unit means then I understand to add it is a best practice but what does it means ?
1

First I'd Like to thank you all for helping me!

I found this in this tutorial: https://docs.scala-lang.org/tour/basics.html

"The return type of the method greet is Unit, which says there’s nothing meaningful to return. It’s used similarly to void in Java and C. (A difference is that because every Scala expression must have some value, there is actually a singleton value of type Unit, written (). It carries no information.)"

which I believe Sum up what @AndreyTyukin said in his explanation.

Comments

0

This is usually added for public methods, since IntelliJ wants them to have an explicit type signature.

Generally, it is best practice to add these type signatures, although it is automatically inferred if you leave it out. It makes very explicit that the function returns nothing. It implies that it has a side-effect (or is useless in the first place ;))

Writing def foo(){} is just syntactic sugar, one could argue about if it is really reasonable that it exists.

2 Comments

It doesn't return "nothing" (and definitely not Nothing, to exclude this possibility for confusion). If a function declares that it has return type Unit, then it returns the only value of type Unit, namely ().
You are entirely right, I wasn't precise enough. What I wanted to say is that it returns nothing but a constant value what in pure functional programming generally signals it is replaceable (referential transparency) by that constant. So either this or there is a side-effect. Thanks for you hint.
0

If you are familiar to programming languages, "Unit" means "Void". So "Unit" means the function does not return any value e.g. Int, Boolean...

":Unit=" can be optional, depends on the context, that's why sometimes you'll see functions with it or without it.

1 Comment

Unit does not mean Void for any wide-spread definition of Void. Unit is the unit of the cartesian product operation. Unlike Void, there is a value of type Unit, namely the empty tuple (). Methods with return type Unit return the empty tuple () (unless they exit with an exception).
0

The reason is that IntellJ sometimes help to have a better coding style. For example if the return type is not defined for a method (defined using def), the IntellJ provides the return type. This is because it is good to have a clear method signature (signature consists of name, input parameters, body, and their types and the return type). Also please note that, Scala is also a functional programming language as well as object oriented; so types are very important and therefore part of the coding style.

A piece of advice here is; whenever you are not sure the underlying library, use hold ctrl key and click on it. For example, if I click on Unit I will get the following:

/** `Unit` is a subtype of [[scala.AnyVal]]. There is only one value of type * `Unit`, `()`, and it is not represented by any object in the underlying * runtime system. A method with return type `Unit` is analogous to a Java * method which is declared `void`. */ 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.