I was writing a matrix class in Scala, and I thought the best way to implement a transpose operation would be to just return an interface with all the operations "transposed." So if matrix.apply(i, j)
returns the (i, j)th element, then matrix.transpose returns an interface (but not a copy of the data) that contains an apply method that returns matrix(j, i). And I wrote that interface sort of like this (what I really wrote is much messier):
abstract class Matrix {
def apply(i : Int, j : Int) : Double
//other matrixy operations
private def outer = this //so the inner can see the enclosing instance
object TransposedInterface extends Matrix {
def apply(i :Int, j : Int) = outer(j, i)
}
}
Which is cute, I guess, but now TransposedInterface
also has an object inside it called TransposedInterface
, and so on, recursively, and where does it all end?
I tried the following in the interpreter:
class Outer(val i : Int) {
object Inner extends Outer(i + 1)
}
val o = new Outer(1)
o.Inner.Inner.Inner.Inner.i
Which runs and evaluates to 5, like it should, I guess.
So what's actually going on? Is the inner object evaluated lazily? Is it garbage collect when it's not immediately being used, then instantiated again next time outer.Inner is called? Is it some voodoo that I haven't thought of?