• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Encapsulation and Scala

 
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
pie sneak
Posts: 4727
Mac VI Editor Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Any thoughts on this?

[ August 11, 2008: Message edited by: Marc Peabody ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Marc Peabody
pie sneak
Posts: 4727
Mac VI Editor Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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 ]
 
Marc Peabody
pie sneak
Posts: 4727
Mac VI Editor Ruby
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Garrett Rowe:
You have to use my StackDelegator (and the amended ConsoleLoggingStack trait), its not as useless as it looks.


I had my post window open a long time and your Delegate post slipped in before I finished so it looks like I was ignoring yours. Oops.

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.

The Delegator seems to do the trick just fine. I'll play around with it some tonight and challenge myself to one-up you on the neato factor.
 
Ranch Hand
Posts: 376
Scala Monad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Marc Peabody:

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

[Actually, is more like: cast "this" to the type defined.
http://www.scala-lang.org/intro/selfrefs.html ]
[ August 13, 2008: Message edited by: Gabriel Claramunt ]
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Looking through Scala libraries last night I learned that what I really did was rediscover the Proxy (pattern?). A more idiomatic version would be:

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Garrett, Look up "Abstract Algebraic Data Types". The use of an abstract ADT will resolve your issue.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic