Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the advantages of having a trait behind an object?

Tags:

scala

In Scala 2.11 standard library, we see:

object StdIn extends StdIn

What advantages does it bring? There is no other class extending this trait. Is it to pass the trait in function calls? What is the need when there is singleton object?

like image 526
Dragonborn Avatar asked Jan 15 '16 04:01

Dragonborn


People also ask

What are some benefits of object inheritance?

Advantages of InheritanceNo changes to be done in all base classes; just do changes in parent class only. Inheritance is used to generate more dominant objects. Inheritance avoids duplicity and data redundancy. Inheritance is used to avoid space complexity and time complexity.

What is the main advantage of object oriented?

OOP language allows to break the program into the bit-sized problems that can be solved easily (one object at a time). The new technology promises greater programmer productivity, better quality of software and lesser maintenance cost. OOP systems can be easily upgraded from small to large systems.


2 Answers

It's called selfless trait pattern.

You implement the selfless trait pattern simply by providing a companion object for a trait that itself mixes in the trait.

trait Friendly {
  def greet() { println("hi there") }
}

object Friendly extends Friendly

Trait Friendly in this example has one method, greet. It also has a companion object, named Friendly, which mixes in trait Friendly. Given this friendly design, client programmers of this library can access the services of Friendly either via mix in composition, like this (imports and uses of Friendly are in bold):

object MixinExample extends Application with Friendly {
  greet()
}

Or by importing the members of the Friendly companion object, like this:

import Friendly._

object ImportExample extends Application {
  greet()
}
like image 86
slouc Avatar answered Oct 02 '22 15:10

slouc


First of all having an object that extends a trait does not limit us from creating more instances of that trait. In a hypothetical situation there could be another version/implementation that superceeds StdIn and we could declare previous object to be obsolete keeping the same interface. However, that's not the intention in case of StdIn according to the scaladoc:

/** private[scala] because this is not functionality we should be providing
 *  in the standard library, at least not in this idiosyncractic form.
 *  Factored into trait because it is better code structure regardless.
 */
private[scala] trait StdIn {

A trait defines a type and an interface for the object. This is useful for referring to that type. Consider the situation where there is no trait, it would be awkward and limiting to use:

scala> object A { val id = 1 }
defined object A

scala> def f(v: A.type) = v.id
f: (v: A.type)Int

scala> f(A)
res1: Int = 1

scala> def f(v: A) = v.id
<console>:10: error: not found: type A
       def f(v: A) = v.id

Have to resort to structural typing:

scala> def g(v: { def id: Int }) = v.id
g: (v: AnyRef{def id: Int})Int

scala> object B { val id = 2 }
defined object B

scala> g(B)
res5: Int = 2

scala> g(A)
res6: Int = 1

scala> f(B)
<console>:17: error: type mismatch;
 found   : B.type
 required: A.type
       f(B)
         ^

However, we can't use the StdIn trait since it's private:

scala> import scala.io._
import scala.io._

scala> val b: StdIn = ???
<console>:13: error: trait StdIn in package io cannot be accessed in package io
       val b: StdIn = ???
              ^

Thus your question is very well justified, and the only benefit I see is more code clarity: abstract implementation is separate from instance/scope management.

like image 21
yǝsʞǝla Avatar answered Oct 02 '22 16:10

yǝsʞǝla