This page is no longer maintained — Please continue to the home page at www.scala-lang.org

"Non-Complementary" Methods in Traits?

18 replies
Daniel Hinojosa
Joined: 2011-03-26,
User offline. Last seen 42 years 45 weeks ago.
I am beginning to think that traits should rarely have concrete methods unless it complements something abstract.  For example, in Programming In Scala:
trait Rectangular {   def topLeft: Point   def bottomRight: Point   def left = topLeft.x   def right = bottomRight.x   def width = right - left   // and many more geometric methods...}
topLeft and bottomRight are abstract, left right, and width are not, but they are complementary to the abstract methods since they make use of them.
In the Scala Website:
trait Similarity {  def isSimilar(x: Any): Boolean  def isNotSimilar(x: Any): Boolean = !isSimilar(x)}
isNotSimilar of course is complementary to isSimilar.
Is it everyone's experience to always use traits in this way and never put an uncomplementary method in a trait? or am I being to broad-brushed?
Philippe Lhoste
Joined: 2010-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

On 06/04/2011 07:54, Daniel Hinojosa wrote:
> Is it everyone's experience to always use traits in this way and never put an
> uncomplementary method in a trait? or am I being to broad-brushed?

Have you an example of "uncomplementary method"?
If I look at the source of some traits in Scala source code, like SeqLike.scala [1], it
seems there are lot of method definitions, but they necessarily refers to abstract
methods, no? (or not-so-abstract methods that do refer to abstract methods).

[1]
https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/src/...

Ben Hutchison 3
Joined: 2009-11-02,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

On Wed, Apr 6, 2011 at 3:54 PM, Daniel Hinojosa
wrote:
> I am beginning to think that traits should rarely have concrete methods
> unless it complements something abstract.
>
> Is it everyone's experience to always use traits in this way and never put
> an uncomplementary method in a trait?

Essentially, yes, (for me at least).

Note that if traits took constructor params (they might in future),
they'd have something else than abstract members to operate on.

-Ben

Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

I wouldn't agree as traits may define values or variables which can be
operated upon by the trait.
Logging comes to mind where mixing in a Logger trait gives you
automatic access to methods like
debug, info, trace etc... that operate on a logger defined in the trait.

-Stefan

2011/4/6 Ben Hutchison :
> On Wed, Apr 6, 2011 at 3:54 PM, Daniel Hinojosa
> wrote:
>> I am beginning to think that traits should rarely have concrete methods
>> unless it complements something abstract.
>>
>> Is it everyone's experience to always use traits in this way and never put
>> an uncomplementary method in a trait?
>
> Essentially, yes, (for me at least).
>
> Note that if traits took constructor params (they might in future),
> they'd have something else than abstract members to operate on.
>
> -Ben
>

Lex
Joined: 2010-02-28,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

Remember, you can extend only one class and as many traits are you
want. When using traits to bring in the desired functionality you are
not forcing the users of your class into a limited class hierarchy.

On Wed, Apr 6, 2011 at 1:54 AM, Daniel Hinojosa
wrote:
> I am beginning to think that traits should rarely have concrete methods
> unless it complements something abstract.  For example, in Programming In
> Scala:
> trait Rectangular {
>    def topLeft: Point
>    def bottomRight: Point
>    def left = topLeft.x
>    def right = bottomRight.x
>    def width = right - left
>    // and many more geometric methods...
> }
> topLeft and bottomRight are abstract, left right, and width are not, but
> they are complementary to the abstract methods since they make use of them.
> In the Scala Website:
> trait Similarity {
>   def isSimilar(x: Any): Boolean
>   def isNotSimilar(x: Any): Boolean = !isSimilar(x)
> }
> isNotSimilar of course is complementary to isSimilar.
> Is it everyone's experience to always use traits in this way and never put
> an uncomplementary method in a trait? or am I being to broad-brushed?

Daniel Hinojosa
Joined: 2011-03-26,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?
Yes, that's another example where concrete methods use abstract methods.  Doesn't seem there are concrete methods that don't use abstract methods.  So I am considering that this maybe a good "rule" for myself.
Daniel Hinojosa
Joined: 2011-03-26,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?
Hmm, sounds scary to have constructors for traits, I an unable to see ahead on that one, but I am open to persuasion.
Daniel Hinojosa
Joined: 2011-03-26,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?
While initially I thought at first that you were just stating the obvious, I kept thinking about your response.   It is valuable for things like Cake Pattern to have this, but it seems for other code, especially production code,  there is room for a lot of abuse.  The abuse seems it comes from making a trait for everything, especially on items that doesn't follow an "is-a" relationship. 

So having a Logger trait that does logging for example seems like a good idea, but doesn't really make sense from a design point for example in

class BankAccount extends Logger

since a BankAccount is not a Logger of any sort it's a BankAccount, and it seems that this would be more confusing. So I may opt to maintain 'prefer delegation over inheritance' when it comes to Scala and traits, just as I have done in Java.  Good idea, bad idea?
Tomygun
Joined: 2008-11-27,
User offline. Last seen 3 years 48 weeks ago.
Re: "Non-Complementary" Methods in Traits?
Change the name Logger to "Loggable" or "Logged" and problem solved :)

On Wed, Apr 6, 2011 at 4:23 PM, Daniel Hinojosa <dh [dot] evolutionnext [at] gmail [dot] com> wrote:
While initially I thought at first that you were just stating the obvious, I kept thinking about your response.   It is valuable for things like Cake Pattern to have this, but it seems for other code, especially production code,  there is room for a lot of abuse.  The abuse seems it comes from making a trait for everything, especially on items that doesn't follow an "is-a" relationship. 

So having a Logger trait that does logging for example seems like a good idea, but doesn't really make sense from a design point for example in

class BankAccount extends Logger

since a BankAccount is not a Logger of any sort it's a BankAccount, and it seems that this would be more confusing. So I may opt to maintain 'prefer delegation over inheritance' when it comes to Scala and traits, just as I have done in Java.  Good idea, bad idea?

Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

You are confusing inheritance with roles. With
class BankAccount extends Logger does not mean this is inhertiance as
a BankAccount is clearly not a Logger. In this context it actually
means Role. So better is to read BankAccount takes on the Role of a
Logger.

I think using traits to form relationships that are not "is-a" is
actually a strong point especially when you consider that traits can
be mixed in at creation time giving you the ability to dynamically set
the role of an object and make its behaviour transparent to the actual
user.
So if I had a transaction system and I would like the BankAccount to
act as a sink for audit logs I could simply setup my transaction
system to expect something which has the role of the logger and now I
can pass in the BankAccount I can even make it a Logger just for the
one call to my transaction system.
e.g.
transactionSystem.injectLogger(new BankAccount() with Logger)
or in the static way
transactionSystem.injectLogger(bankAccount)

I find this a very valuable and powerful way of abstracting on roles
rather then on instances.

-Stefan

2011/4/6 Daniel Hinojosa :
> While initially I thought at first that you were just stating the obvious, I
> kept thinking about your response.   It is valuable for things like Cake
> Pattern to have this, but it seems for other code, especially production
> code,  there is room for a lot of abuse.  The abuse seems it comes from
> making a trait for everything, especially on items that doesn't follow an
> "is-a" relationship.
>
> So having a Logger trait that does logging for example seems like a good
> idea, but doesn't really make sense from a design point for example in
>
> class BankAccount extends Logger
>
> since a BankAccount is not a Logger of any sort it's a BankAccount, and it
> seems that this would be more confusing. So I may opt to maintain 'prefer
> delegation over inheritance' when it comes to Scala and traits, just as I
> have done in Java.  Good idea, bad idea?
>

Daniel Hinojosa
Joined: 2011-03-26,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?


On Thursday, April 7, 2011 5:09:59 AM UTC-6, Stefan Langer wrote:
You are confusing inheritance with roles. With
class BankAccount extends Logger does not mean this is inhertiance as
a BankAccount is clearly not a Logger. In this context it actually
means Role. So better is to read BankAccount takes on the Role of a
Logger.

Hmm, the idea of a role would be a small mental leap for me. 

I think using traits to form relationships that are not "is-a" is
actually a strong point especially when you consider that traits can
be mixed in at creation time giving you the ability to dynamically set
the role of an object and make its behaviour transparent to the actual
user.

After I posted I realized that since I use ScalaTest extensively it uses it as you specified:
class MyTest extends WordSpec with MustMatchers

So if I had a transaction system and I would like the BankAccount to
act as a sink for audit logs I could simply setup my transaction
system to expect something which has the role of the logger and now I
can pass in the BankAccount I can even make it a Logger just for the
one call to my transaction system.
e.g.
transactionSystem.injectLogger(new BankAccount() with Logger)
or in the static way
 transactionSystem.injectLogger(bankAccount)

I find this a very valuable and powerful way of abstracting on roles
rather then on instances.

True, I guess the mental issue is with BankAccount extends Logger and that extends still gives me a mental issue. I wish I could do:
class BankAccount with Logger 
Visually that would make sense, but unfortunately that will not compile. 

Thanks Stefan.

-Stefan

2011/4/6 Daniel Hinojosa <dh [dot] evolu [dot] [dot] [dot] [at] gmail [dot] com>:
> While initially I thought at first that you were just stating the obvious, I
> kept thinking about your response.   It is valuable for things like Cake
> Pattern to have this, but it seems for other code, especially production
> code,  there is room for a lot of abuse.  The abuse seems it comes from
> making a trait for everything, especially on items that doesn't follow an
> "is-a" relationship.
>
> So having a Logger trait that does logging for example seems like a good
> idea, but doesn't really make sense from a design point for example in
>
> class BankAccount extends Logger
>
> since a BankAccount is not a Logger of any sort it's a BankAccount, and it
> seems that this would be more confusing. So I may opt to maintain 'prefer
> delegation over inheritance' when it comes to Scala and traits, just as I
> have done in Java.  Good idea, bad idea?
>

bmaso
Joined: 2009-10-04,
User offline. Last seen 2 years 40 weeks ago.
Re: "Non-Complementary" Methods in Traits?
On Thu, Apr 7, 2011 at 1:17 PM, Daniel Hinojosa <dh [dot] evolutionnext [at] gmail [dot] com> wrote:


On Thursday, April 7, 2011 5:09:59 AM UTC-6, Stefan Langer wrote:
You are confusing inheritance with roles. With
class BankAccount extends Logger does not mean this is inhertiance as
a BankAccount is clearly not a Logger. In this context it actually
means Role. So better is to read BankAccount takes on the Role of a
Logger.

Hmm, the idea of a role would be a small mental leap for me. 

I think using traits to form relationships that are not "is-a" is
actually a strong point especially when you consider that traits can
be mixed in at creation time giving you the ability to dynamically set
the role of an object and make its behaviour transparent to the actual
user.

After I posted I realized that since I use ScalaTest extensively it uses it as you specified:
class MyTest extends WordSpec with MustMatchers

So if I had a transaction system and I would like the BankAccount to
act as a sink for audit logs I could simply setup my transaction
system to expect something which has the role of the logger and now I
can pass in the BankAccount I can even make it a Logger just for the
one call to my transaction system.
e.g.
transactionSystem.injectLogger(new BankAccount() with Logger)
or in the static way
 transactionSystem.injectLogger(bankAccount)

I find this a very valuable and powerful way of abstracting on roles
rather then on instances.

True, I guess the mental issue is with BankAccount extends Logger and that extends still gives me a mental issue. I wish I could do:
class BankAccount with Logger 

I tend to use

class BankAccount extends Object with Logger

specifically to avoid my classes appearing to extend the trait directly. Plus I would probably not use an active noun as the trait name -- a noun whose name is "verb-er", such as "Manager", "QueueListener", etc. Active nouns tend to indicate the role of an object within a system, while traits I use typically augment an object with extra capabilities, which is very different.

Brian Maso
 

Visually that would make sense, but unfortunately that will not compile. 

Thanks Stefan.

-Stefan

2011/4/6 Daniel Hinojosa <dh [dot] evolu [dot] [dot] [dot] [at] gmail [dot] com>:


> While initially I thought at first that you were just stating the obvious, I
> kept thinking about your response.   It is valuable for things like Cake
> Pattern to have this, but it seems for other code, especially production
> code,  there is room for a lot of abuse.  The abuse seems it comes from
> making a trait for everything, especially on items that doesn't follow an
> "is-a" relationship.
>
> So having a Logger trait that does logging for example seems like a good
> idea, but doesn't really make sense from a design point for example in
>
> class BankAccount extends Logger
>
> since a BankAccount is not a Logger of any sort it's a BankAccount, and it
> seems that this would be more confusing. So I may opt to maintain 'prefer
> delegation over inheritance' when it comes to Scala and traits, just as I
> have done in Java.  Good idea, bad idea?
>




--
Best regards,
Brian Maso
(949) 395-8551
brian [at] blumenfeld-maso [dot] com

Daniel Hinojosa
Joined: 2011-03-26,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?
Great Solution! Thanks
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: "Non-Complementary" Methods in Traits?


On 7 April 2011 12:09, Stefan Langer <mailtolanger [at] googlemail [dot] com> wrote:
You are confusing inheritance with roles. With
class BankAccount extends Logger does not mean this is inhertiance as
a BankAccount is clearly not a Logger. In this context it actually
means Role. So better is to read BankAccount takes on the Role of a
Logger.



I think this is a classic case of poor naming. Most implementations of logging that I've seen do little more than add a log member to classes, so a better name might be 'HasLogger'.  It then becomes a lot more obvious that BankAccount is a subclass of things that have loggers, and that logging is not merely bolted on as a role.
A role, as I understand it, is an optional characteristic that can be used to extend a class.  For example, a bank account might take on the role of being a source or target for the purpose of transferring funds, contrast this to the property of "having a logger", which is a permanent intrinsic trait of all bank accounts in any sane system.
 
I think using traits to form relationships that are not "is-a" is
actually a strong point especially when you consider that traits can
be mixed in at creation time giving you the ability to dynamically set
the role of an object and make its behaviour transparent to the actual
user.
So if I had a transaction system and I would like the BankAccount to
act as a sink for audit logs I could simply setup my transaction
system to expect something which has the role of the logger and now I
can pass in the BankAccount I can even make it a Logger just for the
one call to my transaction system.
e.g.
transactionSystem.injectLogger(new BankAccount() with Logger)
or in the static way
 transactionSystem.injectLogger(bankAccount)

I find this a very valuable and powerful way of abstracting on roles
rather then on instances.


"is-a" and "has-are" are both useful approaches for understanding an architecture, but you seem to be mixing them both up with "can-be-a".  It's an easy and very understandable source of confusion, especially when coming from Java and facing the difficulties that that language has in making such distinctions.  It's a subject that I've grappled with at some depth, especially after having studied the DCI pattern, and is ultimately what first inspired me to attempt eh autoproxy plugin.
 
-Stefan

2011/4/6 Daniel Hinojosa <dh [dot] evolutionnext [at] gmail [dot] com>:
> While initially I thought at first that you were just stating the obvious, I
> kept thinking about your response.   It is valuable for things like Cake
> Pattern to have this, but it seems for other code, especially production
> code,  there is room for a lot of abuse.  The abuse seems it comes from
> making a trait for everything, especially on items that doesn't follow an
> "is-a" relationship.
>
> So having a Logger trait that does logging for example seems like a good
> idea, but doesn't really make sense from a design point for example in
>
> class BankAccount extends Logger
>
> since a BankAccount is not a Logger of any sort it's a BankAccount, and it
> seems that this would be more confusing. So I may opt to maintain 'prefer
> delegation over inheritance' when it comes to Scala and traits, just as I
> have done in Java.  Good idea, bad idea?
>



--
Kevin Wright

gtalk / msn : kev [dot] lee [dot] wright [at] gmail [dot] comkev [dot] lee [dot] wright [at] gmail [dot] commail: kevin [dot] wright [at] scalatechnology [dot] com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

On 08/04/11 11:42, Kevin Wright wrote:
> I think this is a classic case of poor naming. Most implementations of
> logging that I've seen do little more than add a log member to
> classes, so a better name might be 'HasLogger'.
See the Writer data structure, with its very useful Monad.

In brief:

case class Writer[W, A](w: W, a: A)

implicit def WriterMonad[W](implicit m: Monoid[W]): Monad[({type λ[α]=
Writer[W, α]})#λ] =
new Monad[({type λ[α]= Writer[W, α]})#λ] {
def pure[A](a: A): Writer[W, A] = Writer(m.zero, a)
def flatMap[A, B](f: A => Writer[W, B], a: Writer[W, A]): Writer[A,
B] = {
val Writer(ww, b) = f(a)
Writer(m.append(w, ww), b)
}
} // unchecked -- hope this compiles

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: "Non-Complementary" Methods in Traits?


On 8 April 2011 05:02, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
On 08/04/11 11:42, Kevin Wright wrote:
> I think this is a classic case of poor naming. Most implementations of
> logging that I've seen do little more than add a log member to
> classes, so a better name might be 'HasLogger'.
See the Writer data structure, with its very useful Monad.


Although interesting and, indeed, useful... I fail to see how this relates to the broader discussion on the nature of relationships between entities in a type hierarchy.
 
In brief:

case class Writer[W, A](w: W, a: A)

implicit def WriterMonad[W](implicit m: Monoid[W]): Monad[({type λ[α]=
Writer[W, α]})#λ] =
 new Monad[({type λ[α]= Writer[W, α]})#λ] {
   def pure[A](a: A): Writer[W, A] = Writer(m.zero, a)
   def flatMap[A, B](f: A => Writer[W, B], a: Writer[W, A]): Writer[A,
B] = {
       val Writer(ww, b) = f(a)
       Writer(m.append(w, ww), b)
   }
} // unchecked -- hope this compiles

--
Tony Morris
http://tmorris.net/





--
Kevin Wright

gtalk / msn : kev [dot] lee [dot] wright [at] gmail [dot] comkev [dot] lee [dot] wright [at] gmail [dot] commail: kevin [dot] wright [at] scalatechnology [dot] com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

On 08/04/11 14:53, Kevin Wright wrote:
>
> Although interesting and, indeed, useful... I fail to see how this
> relates to the broader discussion on the nature of relationships
> between entities in a type hierarchy.
How can I help?

Stefan Langer
Joined: 2009-10-23,
User offline. Last seen 42 years 45 weeks ago.
Re: "Non-Complementary" Methods in Traits?

What you are talking about is actually composition and not
inheritance. What Logger or HasLogger actually does is compose a
logger into the actual class. To talk about a inheritance relationship
is more even more confusing in my eyes.

Granted logger is not a good example to use when explaining the
purpose of Roles as meant in the DCI Pattern and when I think about it
the Logger actually does use a "abstract" function as it works on the
class name of the class it is mixed into. Since this method is always
there (its defined in AnyRef which basically goes to Object when run
in the JVM) it must not be defined in the trait.
So I would say in essence Daniel Hinjosana is right that traits should
always compelement existing methods in the objects they are mixed into
or else a Mixin wouldn't make much sense would it?

the only exception I can think about is true multiple inheritance
since this can't be realized without mixing in traits. But this is
rare and most of the times a code smell.

-Stefan

2011/4/8 Kevin Wright :
>
>
> On 7 April 2011 12:09, Stefan Langer wrote:
>>
>> You are confusing inheritance with roles. With
>> class BankAccount extends Logger does not mean this is inhertiance as
>> a BankAccount is clearly not a Logger. In this context it actually
>> means Role. So better is to read BankAccount takes on the Role of a
>> Logger.
>>
>
>
> I think this is a classic case of poor naming. Most implementations of
> logging that I've seen do little more than add a log member to classes, so a
> better name might be 'HasLogger'.  It then becomes a lot more obvious that
> BankAccount is a subclass of things that have loggers, and that logging is
> not merely bolted on as a role.
> A role, as I understand it, is an optional characteristic that can be used
> to extend a class.  For example, a bank account might take on the role of
> being a source or target for the purpose of transferring funds, contrast
> this to the property of "having a logger", which is a permanent intrinsic
> trait of all bank accounts in any sane system.
>
>>
>> I think using traits to form relationships that are not "is-a" is
>> actually a strong point especially when you consider that traits can
>> be mixed in at creation time giving you the ability to dynamically set
>> the role of an object and make its behaviour transparent to the actual
>> user.
>> So if I had a transaction system and I would like the BankAccount to
>> act as a sink for audit logs I could simply setup my transaction
>> system to expect something which has the role of the logger and now I
>> can pass in the BankAccount I can even make it a Logger just for the
>> one call to my transaction system.
>> e.g.
>> transactionSystem.injectLogger(new BankAccount() with Logger)
>> or in the static way
>>  transactionSystem.injectLogger(bankAccount)
>>
>> I find this a very valuable and powerful way of abstracting on roles
>> rather then on instances.
>>
>
> "is-a" and "has-are" are both useful approaches for understanding an
> architecture, but you seem to be mixing them both up with "can-be-a".  It's
> an easy and very understandable source of confusion, especially when coming
> from Java and facing the difficulties that that language has in making such
> distinctions.  It's a subject that I've grappled with at some depth,
> especially after having studied the DCI pattern, and is ultimately what
> first inspired me to attempt eh autoproxy plugin.
>
>>
>> -Stefan
>>
>> 2011/4/6 Daniel Hinojosa :
>> > While initially I thought at first that you were just stating the
>> > obvious, I
>> > kept thinking about your response.   It is valuable for things like Cake
>> > Pattern to have this, but it seems for other code, especially production
>> > code,  there is room for a lot of abuse.  The abuse seems it comes from
>> > making a trait for everything, especially on items that doesn't follow
>> > an
>> > "is-a" relationship.
>> >
>> > So having a Logger trait that does logging for example seems like a good
>> > idea, but doesn't really make sense from a design point for example in
>> >
>> > class BankAccount extends Logger
>> >
>> > since a BankAccount is not a Logger of any sort it's a BankAccount, and
>> > it
>> > seems that this would be more confusing. So I may opt to maintain
>> > 'prefer
>> > delegation over inheritance' when it comes to Scala and traits, just as
>> > I
>> > have done in Java.  Good idea, bad idea?
>> >
>
>
>
> --
> Kevin Wright
>
> gtalk / msn : kev [dot] lee [dot] wright [at] gmail [dot] com
> mail: kevin [dot] wright [at] scalatechnology [dot] com
> vibe / skype: kev.lee.wright
> quora: http://www.quora.com/Kevin-Wright
> twitter: @thecoda
>
> "My point today is that, if we wish to count lines of code, we should not
> regard them as "lines produced" but as "lines spent": the current
> conventional wisdom is so foolish as to book that count on the wrong side of
> the ledger" ~ Dijkstra
>

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: "Non-Complementary" Methods in Traits?

On 8 April 2011 06:28, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
On 08/04/11 14:53, Kevin Wright wrote:
>
> Although interesting and, indeed, useful... I fail to see how this
> relates to the broader discussion on the nature of relationships
> between entities in a type hierarchy.
How can I help?


You've got lots of relevant material here :)  Type classes are the most blindingly obvious thing to mention, or the equivalence between a subclass relationship and an implicit conversion.
 
--
Tony Morris
http://tmorris.net/





--
Kevin Wright

gtalk / msn : kev [dot] lee [dot] wright [at] gmail [dot] comkev [dot] lee [dot] wright [at] gmail [dot] commail: kevin [dot] wright [at] scalatechnology [dot] com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland