Trait
From APIDesign
Line 6: | Line 6: | ||
However later I realized that the take on [[OOP]] is really targeted to [[OOP]] languages of the past. In modern languages, like [[Scala]] one can keep encapsulation and still be as effective as the old plain good [[C]]. As Martin Odersky once put it: there used to be a time when people were arguing whether we need '''goto''' statement to effectively find a particular number in a matrix. Those days are gone - we can focus on new problems. The same applies to effective and encapsulated list problem. I am not a [[Scala]] expert, but I knew its type system is powerful enough. It took me few hours to re-learn [[Scala]], but finally I created the code... | However later I realized that the take on [[OOP]] is really targeted to [[OOP]] languages of the past. In modern languages, like [[Scala]] one can keep encapsulation and still be as effective as the old plain good [[C]]. As Martin Odersky once put it: there used to be a time when people were arguing whether we need '''goto''' statement to effectively find a particular number in a matrix. Those days are gone - we can focus on new problems. The same applies to effective and encapsulated list problem. I am not a [[Scala]] expert, but I knew its type system is powerful enough. It took me few hours to re-learn [[Scala]], but finally I created the code... | ||
+ | |||
+ | == Encapsulated List == | ||
+ | |||
+ | To create as effective list as presented in [[C]] in the [http://www.250bpm.com/blog:8 article] one needs an orchestration between the list class and its elements. Fine, let's achieve that with [[trait]]s. First of all define the '''prev''' and '''next''' pointers each type willing to participate in a list needs to provide: | ||
+ | |||
+ | <source lang="scala" snippet="effectivelist.item"/> | ||
+ | |||
+ | Then we can create a list that operates on top of such items: | ||
+ | |||
+ | <source lang="scala" snippet="effectivelist.list"/> | ||
+ | |||
+ | Please note that the definition of item is using '''private''' access modifiers giving access only to the list implementation. So the encapsulation is guaranteed (so [[OOP]] principles are kept). Of course, given the implementation is a one-to-one copy of the [[C]] list, it is going to be as effective as the [[C]] one. Here is a sample usage: | ||
+ | |||
+ | <source lang="scala" snippet="effectivelist.person"/> | ||
+ | |||
+ | Please note that there is no cast, everything is typed correctly, thanks to [[Scala]]'s flexible type system. [[Good]] achievement, [[Scala]] guys! Of course some may say that it is ugly every class that one wants to use in the effective list needs to inherit from the '''Listable''' [[trait]]. What should one do when the type has been written by somebody else and does not inherit from '''Listable'''? Can one put following class into a list? | ||
+ | |||
+ | <source lang="scala" snippet="effectivelist.point"/> | ||
+ | |||
+ | In fact, it is more than easy thanks to [[Scala]]'s implicit conversion methods. One can create a subtype that mixes in the ''Point'' as well as ''Listable'' and define an implicit method that converts from ''Point'' to ''ListablePoint''. Then one can basically store ''Point''s in a list: | ||
+ | |||
+ | <source lang="scala" snippet="effectivelist.convert"/> | ||
+ | |||
+ | This is a nice example showing how much the [[OOP]] technology progressed during last two decades. Thanks [[Scala]] for moving the [[OOP]] further. | ||
+ | |||
+ | == Can this be done in [[C++]]? == | ||
+ | |||
+ | One question remains: Can this be emulated in [[C++]]? Mixins are inherently present in [[C++]] as the language supports multiple inheritance. Implicit conversions are indeed there, so the only question is whether one can type this correctly without using casts. My early 90ties knowledge of [[C++]] would suggest, one needs casts, but maybye the [[C++]] changed meanwhile with a hope to keep with progress of [[OOP]] made meanwhile. Anyone knows? |
Revision as of 19:57, 2 September 2012
Trait is a delta - a difference - that you can mix-in when using modern OOP languages when creating your own class. Traits are frequently present in Scala.
Is C better than C++?
Recently I've noticed an interesting article describing why C is more effective than C++ and in general most of OOP languages. The article is well written and for a while I was nodding in an agreement. The claim that by using OOP and insisting on encapsulation one cannot implement linked list as effectively as in C is very good one!
However later I realized that the take on OOP is really targeted to OOP languages of the past. In modern languages, like Scala one can keep encapsulation and still be as effective as the old plain good C. As Martin Odersky once put it: there used to be a time when people were arguing whether we need goto statement to effectively find a particular number in a matrix. Those days are gone - we can focus on new problems. The same applies to effective and encapsulated list problem. I am not a Scala expert, but I knew its type system is powerful enough. It took me few hours to re-learn Scala, but finally I created the code...
Encapsulated List
To create as effective list as presented in C in the article one needs an orchestration between the list class and its elements. Fine, let's achieve that with traits. First of all define the prev and next pointers each type willing to participate in a list needs to provide:
does not exists: effectivelist.item
Then we can create a list that operates on top of such items:
does not exists: effectivelist.list
Please note that the definition of item is using private access modifiers giving access only to the list implementation. So the encapsulation is guaranteed (so OOP principles are kept). Of course, given the implementation is a one-to-one copy of the C list, it is going to be as effective as the C one. Here is a sample usage:
does not exists: effectivelist.person
Please note that there is no cast, everything is typed correctly, thanks to Scala's flexible type system. Good achievement, Scala guys! Of course some may say that it is ugly every class that one wants to use in the effective list needs to inherit from the Listable trait. What should one do when the type has been written by somebody else and does not inherit from Listable? Can one put following class into a list?
does not exists: effectivelist.point
In fact, it is more than easy thanks to Scala's implicit conversion methods. One can create a subtype that mixes in the Point as well as Listable and define an implicit method that converts from Point to ListablePoint. Then one can basically store Points in a list:
does not exists: effectivelist.convert
This is a nice example showing how much the OOP technology progressed during last two decades. Thanks Scala for moving the OOP further.
Can this be done in C++?
One question remains: Can this be emulated in C++? Mixins are inherently present in C++ as the language supports multiple inheritance. Implicit conversions are indeed there, so the only question is whether one can type this correctly without using casts. My early 90ties knowledge of C++ would suggest, one needs casts, but maybye the C++ changed meanwhile with a hope to keep with progress of OOP made meanwhile. Anyone knows?