Skip to content

Instantly share code, notes, and snippets.

@kevinmeredith
Created July 6, 2016 02:19
Show Gist options
  • Select an option

  • Save kevinmeredith/1bb943c9342d09eff25e6cf35b162f31 to your computer and use it in GitHub Desktop.

Select an option

Save kevinmeredith/1bb943c9342d09eff25e6cf35b162f31 to your computer and use it in GitHub Desktop.
Type out example from Programming in Scala, 3rd edition - `Queue` in Listing 19.4

After pasting Listing 19.4 (trait Queue):

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait Queue[T] {
def head: T
def tail: Queue[T]
def enqueue(x: T): Queue[T]
}
object Queue {
def apply[T](xs: T*): Queue[T] =
new QueueImpl[T](xs.toList, Nil)
private class QueueImpl[T](
private val leading: List[T],
private val trailing: List[T]
) extends Queue[T] {
def mirror =
if (leading.isEmpty)
new QueueImpl(trailing.reverse, Nil)
else
this
def head: T = mirror.leading.head
def tail: QueueImpl[T] = {
val q = mirror
new QueueImpl(q.leading.tail, q.trailing)
}
def enqueue(x: T) =
new QueueImpl(leading, x :: trailing)
}
}

// Exiting paste mode, now interpreting.

defined trait Queue
defined object Queue

I then typed out the StrangeIntQueue example:

scala> class StrangeIntQueue extends Queue[Int] {
     |   override def enqueue(x: Int) = {
     |     println(math.sqrt(x))
     |     super.enqueue(x)
     |   }
     | }
<console>:16: error: method enqueue in trait Queue is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'
           super.enqueue(x)
                 ^

scala> :paste
// Entering paste mode (ctrl-D to finish)

class StrangeIntQueue extends Queue[Int] {
override def enqueue(x: Int) = {
println(math.sqrt(x))
super.enqueue(x)
}
}

// Exiting paste mode, now interpreting.

<console>:16: error: method enqueue in trait Queue is accessed from super. 
            It may not be abstract unless it is overridden by a member declared `abstract' and `override'
       super.enqueue(x)
             ^

But I saw the above compile-time error. If I understand correctly, super.enqueue cannot be called from StrangeIntQueue since its parent, i.e. Queue, is abstract.

Please let me know how to fix this compile-time error per your book's example.

@bvenners

bvenners commented Jul 6, 2016

Copy link
Copy Markdown

Actually that is intended to not compile, but for a different reason. It was a thought-experiment to show that mutation isn't required for a covariant type to get you into soundness problems, just the type parameter appearing as the type of a value parameter in a method. The way to get the compiler error we were getting at would be to use an earlier version of Queue that was concrete. The Queue class shown before the refactor to trait Queue would probably do the trick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment