I seems to me that the Scala encourages a programmer to expose implementation details that would be more tightly encapsulated in Java.
Consider a basic Stack trait:
It is very natural to write an implementation of this trait backed by an immutable Scala list:
However my issue is that now the api exposes the fact that the Stack is packed by a List, it would be nicer if the List could be private, but then it couldn't be overridden when constructing a new Stack. I see a couple of workarounds each with their own problems.
Here the List is implicitly private, however by moving the List to the constructor, its explicitly exposed by the API. However, there can be no dependencies on the List. I think this is currently my favorite style.
Another way is to hide the implementation altogether and only expose the Stack through a factory method:
The problem with this method is that the implementation cannot now be mixed in with other traits to add additional functionality
Is there a way to mimic the encapsulation I'm used to with Java or is this really just much ado about nothing?
Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
[ August 11, 2008: Message edited by: Marc Peabody ]
A good workman is known by his tools.
Joined: Jan 17, 2006
Is that an instanceOf check? <gollum-voice>It burns us.. NOOOO</gollum-voice>. I did come up with a hack that works though.
That doesn't look to useful on its surface, but using it allows us to mixin traits into a Stack after the point of instantiation. So now we can modify the ConsoleLoggingStack trait to return a ConsoleLoggingStack backed by the original Stack that it is mixed in with.
And we can mixin the Stack created from the factory method with the ConsoleLoggingStack just as easily
There may be a better way to do this but I haven't figureed it out yet. The only downside I see is the boilerplate code that is needed to create the *Delegate trait. [ August 13, 2008: Message edited by: Garrett Rowe ]
After looking through the Stairway book, I think declaring your elements List in the primary constructor (which is the class declaration) is the most accepted method.
(I added an alternate constructor for more flexibility.)
I've played around with how in the world to conveniently mixin the ConsoleLoggingStack but without success. [ August 13, 2008: Message edited by: Marc Peabody ]
Joined: Jan 17, 2006
Originally posted by Marc Peabody: After looking through the Stairway book, I think declaring your elements List in the primary constructor (which is the class declaration) is the most accepted method.
I figured that was true. It seems to be the most natural way to go.
I've played around with how in the world to conveniently mixin the ConsoleLoggingStack but without success.
You have to use my StackDelegator (and the amended ConsoleLoggingStack trait), its not as useless as it looks.
[ August 13, 2008: Message edited by: Garrett Rowe ]
I can't tell you how much I cringed using isInstanceOf but something had to be done to allow the returned object to be of the same type.
IIRC, Scala has something called "self types", where you can write and roughly translates to " use my current type as Stack[T] type". I've used it successfully to implement a generic graph type (Playing with Scala 4: Abstract types and Self-types) but I must confess that some details are still fuzzy for me