tags:

views:

76

answers:

2

In chapter 10, on page 198 of "Programming in Scala", the definition of Element defines a function/method "above" that returns a new ArrayElement. But ArrayElement extends Element.

In trying type in the examples, I actually get what I expected... a complaint about the circular dependency of these definitions.

What am I missing?

+1  A: 

I believe you're expected to have the ArrayElement definition from page 196 already in effect.

Randall Schulz
Tried that ;-) I put both the ArrayElement and the Element in the same file and then loaded them via :load xxx.scala The problem is that ArrayElement extends Element (which is abstract), so you can't define ArrayElement, but Element uses ArrayElement in it's definition, so you can't define that first either. Ugh.
Langley
I was looking at the wrong code, for one thing. The code may just be erroneous or it may be that there's a proper combination of all the various snippets that works. I don't really know.
Randall Schulz
+4  A: 

Circular definitions are not a problem in this case, as the return type is not circular, and the implementation can be resolved in a second pass after the types are resolved.

For example--and note that I'm wrapping everything in an object so that the REPL will consider it all at once:

object Example {
  abstract class E {
    def a: Int
    def e: E = new AE(2)
  }
  class AE(val a: Int) extends E { }
}

and this works as expected:

scala> val ae = new Example.AE(0)
ae: Example.AE = Example$AE@57240e

scala> ae.a
res1: Int = 0

scala> ae.e.a
res2: Int = 2

My guess is that while you're typing it in, you're trying to get the REPL to accept only part of the circular definition, or you're leaving out something that allows the circularity to be resolved in types (e.g. if you type the return as AbstractElement not Element, that would be confusing!).

Anyway, the code as-is looks okay to me.

Rex Kerr