Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I explicitly return Unit?

What is the proper way to explicitly return the Unit type from a method, using () or Unit? It appears to me that both work in all cases I've tried myself.

For context, this often occurs if I'm writing a method with side effects and returns Unit that calls another method, which also performs side effects but returns some value instead of Unit. e.g.

def effectAndReturn(): String = {
  val msg = "Hello, SO"
  println(msg)
  msg
}

def doEffect(): Unit = {
  val _ = effectAndReturn()
  () // `Unit` also works here
}

From my understanding () is the only value of type Unit that exists. Returning the token Unit in doEffect() is referencing the Unit companion object; I'm confused how this would return a value as there's not even an apply method defined on it. Returning the companion object for a given abstract class's type isn't valid as a return value as far as I know.

Plugging these into a Scala REPL is also interesting

scala> val parenUnit = ()
parenUnit: Unit = ()

scala> parenUnit
// Returns blank line

scala> val wordUnit = Unit
wordUnit: Unit.type = object scala.Unit

scala> wordUnit
res1: Unit.type = object scala.Unit

scala> res1
res2: Unit.type = object scala.Unit

() is simply a Unit value, whereas Unit gives back a type, which doesn't make sense to me as no other companion objects do this as far as I can tell. My guess is that the compiler handles Unit in a particular and unique way compared to any other type, but how exactly?

like image 711
Alan Thomas Avatar asked Nov 21 '18 15:11

Alan Thomas


People also ask

What is return type Unit?

If a function does not return any useful value, its return type is Unit. Unit is a type with only one value — Unit.VALUE. This value does not have to be returned explicitly: fun printHello(name : String?) : Unit { if (name != null) print("Hello, $name!")

Does Scala has void return type?

In Scala we use the Unit return type to indicate "no return value." This is a "void" function.

What is Scala Unit?

The Unit is Scala is analogous to the void in Java, which is utilized as a return type of a functions that is used with a function when the stated function does not returns anything.


2 Answers

So, we have:

  • The Unit type
  • The unit value, i.e. () which is of type Unit
  • The Unit companion object which causes the confusion. It is not of type Unit. It is of type Unit.type (its own singleton type). However... Scala automatically implicitly converts everything to Unit and that's why you can use it where Unit type is expected.

TLDR: Use ()

like image 175
ghik Avatar answered Oct 13 '22 11:10

ghik


Suppose we have two methods in a class called TestUnit:

class TestUnit {
  def foo(): Unit = 2217
  def bar(): Int = 1478
}

Let's look at its bytecode:

  // access flags 0x1
  public foo()V
   L0
    LINENUMBER 4 L0
    SIPUSH 2217
    POP
    RETURN // returns void
   L1
    LOCALVARIABLE this Lunit/TestUnit; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public bar()I
   L0
    LINENUMBER 5 L0
    SIPUSH 1478
    IRETURN // returns integer because it is declared in method
   L1
    LOCALVARIABLE this Lunit/TestUnit; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

My assumption is - the Scala compiler just put RETURN instruction (which returns void) in every method where Unit is declared as returning type. (you can look listings here)

So you can return any type in doEffect(). But as @ghik said, it's better to use ().

like image 28
Duelist Avatar answered Oct 13 '22 13:10

Duelist