Note that there are some explanatory texts on larger screens.

plurals
  1. PODo mixins solve fragile base class issues?
    primarykey
    data
    text
    <p>In a class on programming languages, my professor quotes mixins as one of the solutions to the fragile base class problem. Wikipedia also used to list (Ruby) mixins as a solution for the fragile base class problem, but some time ago <a href="http://en.wikipedia.org/w/index.php?title=Fragile_base_class&amp;diff=451336813&amp;oldid=446645464" rel="nofollow">someone removed</a> the reference to mixins. I still suspect that they might somehow have an advantage over inheritance with regards to the fragile base class problem. Otherwise, why would a professor say that they help?</p> <p>I'll give an example of a possible problem. This is a simple Scala implementation of the (Java) problem that the professor gave us to illustrate the problem.</p> <p>Consider the following base class. Assume that this is some very efficient special implementation of a list, and that more operations are defined on it.</p> <pre class="lang-scala prettyprint-override"><code>class MyList[T] { private var list : List[T] = List.empty def add(el:T) = { list = el::list } def addAll(toAdd:List[T]) : Unit = { if (!toAdd.isEmpty) { add(toAdd.head) addAll(toAdd.tail) } } } </code></pre> <p>Also consider the following trait, which is supposed to add <code>size</code> to the list above.</p> <pre class="lang-scala prettyprint-override"><code>trait CountingSet[T] extends MyList[T] { private var count : Int = 0; override def add(el:T) = { count = count + 1 super.add(el) } override def addAll(toAdd:List[T]) = { count = count + toAdd.size; super.addAll(toAdd); } def size : Int = { count } } </code></pre> <p>The problem is that whether or not the trait will work depends on how we implement <code>addAll</code> in the base class, i.e. the functionality provided by the base class is 'fragile', just as would be the case with a regular <code>extends</code> in Java or any other programming language.</p> <p>For example, if we run the following code with <code>MyList</code> and <code>CountingSet</code> as defined above, we get back <code>5</code>, whereas we would expect to get <code>2</code>.</p> <pre class="lang-scala prettyprint-override"><code>object Main { def main(args:Array[String]) : Unit = { val myCountingSet = new MyList[Int] with CountingSet[Int] myCountingSet.addAll(List(1,2)) println(myCountingSet.size) // Prints 5 } } </code></pre> <p>If we change <code>addAll</code> in the base class (!) as follows, the trait <code>CountingSet</code> works as expected.</p> <pre class="lang-scala prettyprint-override"><code>class MyList[T] { private var list : List[T] = List.empty def add(el:T) = { list = el::list } def addAll(toAdd:List[T]) : Unit = { var t = toAdd; while(!t.isEmpty) { list = t.head::list t = t.tail } } } </code></pre> <p>Keep in mind that I am anything but a Scala expert!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload