Fwd: [Squeak-fr] Ruby et les Traits.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Fwd: [Squeak-fr] Ruby et les Traits.

stephane ducasse

> Quelques propos (récents) de matz (Yukihiro Matsumoto) à propos
> des Traits :
>
> - "Too bad I didn't know about traits when I designed Ruby."
>
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274227
>
> - "If I knew traits before designing Ruby, I'd have chosen traits over
> modules.  But that's the life."
>
> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274242

this is why I will try to find some times to polish traits in squeak

stef
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [Squeak-fr] Ruby et les Traits.

Andreas.Raab
Out of curiosity, what is the difference between Ruby's modules and
traits? They strike me as extremely similar, but not being the local
Ruby guru I might overlook some implications. As far as I understand it
both allow "grouping of methods" (aka: include statements) and both
disallow state (in Ruby's case simply because state access is always a
dynamic attribute lookup). So what's the difference?

Cheers,
   - Andreas

stephane ducasse wrote:

>
>> Quelques propos (récents) de matz (Yukihiro Matsumoto) à propos
>> des Traits :
>>
>> - "Too bad I didn't know about traits when I designed Ruby."
>>
>> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274227
>>
>> - "If I knew traits before designing Ruby, I'd have chosen traits over
>> modules.  But that's the life."
>>
>> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274242
>
> this is why I will try to find some times to polish traits in squeak
>
> stef
>


Reply | Threaded
Open this post in threaded view
|

RE: Fwd: [Squeak-fr] Ruby et les Traits.

Ramon Leon-5
> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On
> Behalf Of Andreas Raab
> Sent: Monday, October 22, 2007 1:37 PM
> To: The general-purpose Squeak developers list
> Subject: Re: Fwd: [Squeak-fr] Ruby et les Traits.
>
> Out of curiosity, what is the difference between Ruby's
> modules and traits? They strike me as extremely similar, but
> not being the local Ruby guru I might overlook some
> implications. As far as I understand it both allow "grouping
> of methods" (aka: include statements) and both disallow state
> (in Ruby's case simply because state access is always a
> dynamic attribute lookup). So what's the difference?
>
> Cheers,
>    - Andreas

Traits can be composed better because you can specify which methods you want
from conflicting traits explicitly.  Ruby's modules I believe don't allow
you to mix and match, but is based on inclusion order only.  Other than
that, I think they're the same.

Ramon Leon
http://onsmalltalk.com


Reply | Threaded
Open this post in threaded view
|

Re: Fwd: [Squeak-fr] Ruby et les Traits.

Andreas.Raab
Ramon Leon wrote:
> Traits can be composed better because you can specify which methods you want
> from conflicting traits explicitly.  Ruby's modules I believe don't allow
> you to mix and match, but is based on inclusion order only.

Do you have an example for this? I'm uncertain what a "conflicting
trait" is and how this would be resolved (in either implementation).

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

RE: Fwd: [Squeak-fr] Ruby et les Traits.

Ramon Leon-5
> -----Original Message-----
> From: [hidden email]
> [mailto:[hidden email]] On
> Behalf Of Andreas Raab
> Sent: Monday, October 22, 2007 2:04 PM
> To: The general-purpose Squeak developers list
> Subject: Re: Fwd: [Squeak-fr] Ruby et les Traits.
>
> Ramon Leon wrote:
> > Traits can be composed better because you can specify which methods
> > you want from conflicting traits explicitly.  Ruby's
> modules I believe
> > don't allow you to mix and match, but is based on inclusion
> order only.
>
> Do you have an example for this? I'm uncertain what a
> "conflicting trait" is and how this would be resolved (in
> either implementation).
>
> Cheers,
>    - Andreas

Well, should two traits both have methods of the same name, Traits lets you
pick and choose which one you want..

Object subclass: #CustomHero
        uses: SupermanTrait - {#run. #fly. #think} + FlashTrait - {#heal.
#think} + BatmanTrait -{#heal. #run}
        instanceVariableNames: ''
        classVariableNames: ''
        poolDictionaries: ''
        category: 'SomeCategory'

So you can manually mix and match Traits to get the desired implementation,
in this case a Hero that's like Superman but can't fly, is still
invulnerable, runs as fast as the Flash and is as smart as Batman.   Or you
want to compose a new Trait by mixing and matching methods from several
other traits.  

More realistically say you have an Enumerable Trait that only requires you
implement #do: in your class... You may not want to provide everything the
module provides, so you selectively remove #select:, #detect: while allowing
the rest.  

Ruby's modules don't allow this level of control.  Given modules with
conflicting methods, you either get all from one or all from the other
depending on the order you include them.  That is my understanding anyway.

Ramon Leon
http://onsmalltalk.com


Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

Colin Putney

On Oct 22, 2007, at 2:44 PM, Ramon Leon wrote:

Ruby's modules don't allow this level of control.  Given modules with

conflicting methods, you either get all from one or all from the other

depending on the order you include them.  That is my understanding anyway.


Ramon is basically correct - the difference is in the way the conflicts are resolved. If a method is defined in more than one place, which one is used?

Ruby's modules work by inserting the module into the superclass chain. The order that modules are included is the order they're inserted, so by including module later in the sequence you can override earlier modules the same way a subclass can override a superclass. For example, the following script prints "a A":

module Uppercase
def alpha
'A'
end
end

module Lowercase
  def alpha
    'a'
  end
end


class Upperfirst
  include Uppercase
  include Lowercase
end

class Uppersecond
  include Lowercase
  include Uppercase
end

first = Upperfirst.new
second = Uppersecond.new

puts "#{first.alpha} #{second.alpha}"

Traits, on the other hand works by adding the methods directly into the class's method dictionary. It can't rely on inheritance to resolve conflicts, so it provides ways of explicitly resolving conflicts, as Ramon explained.

Colin


Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

Jason Johnson-5
But since these two systems are so similar what places are modules
used in Ruby to the best effect?  I always used Haskell as my
comparison, but it turns out this isn't a good idea because Haskell
isn't an OO language, so the applicability is different.

In my conversations with Andreas, I always used Magnitude as the prime
"obvious use case" example for Traits, but that turns out this
actually doesn't work very well for the reasons laid out here:
http://lists.squeakfoundation.org/pipermail/squeak-dev/2007-September/120256.html

Stephane, you might consider the things in that mail when you write
the tools, i.e. make some tools with the idea that making objects can
consist largely of dropping traits or even trait composition
"templates" onto a class to define it.

Andreas, you mentioned a lot of extra complexity created by Traits (in
Proto and so).  Is this due to the implementation of Traits themselves
or a place where someone tried to show "value" with some refactorings
that made things worse?

If it is the latter, then I had a plan of removing these refactoring
and restarting with the goals defined in the email above.  My plate is
full and overflowing, but I could farm this task out.

On 10/23/07, Colin Putney <[hidden email]> wrote:

>
>
> On Oct 22, 2007, at 2:44 PM, Ramon Leon wrote:
>
>
> Ruby's modules don't allow this level of control.  Given modules with
>
> conflicting methods, you either get all from one or all from the other
>
> depending on the order you include them.  That is my understanding anyway.
> Ramon is basically correct - the difference is in the way the conflicts are
> resolved. If a method is defined in more than one place, which one is used?
>
> Ruby's modules work by inserting the module into the superclass chain. The
> order that modules are included is the order they're inserted, so by
> including module later in the sequence you can override earlier modules the
> same way a subclass can override a superclass. For example, the following
> script prints "a A":
>
> module Uppercase
>  def alpha
>  'A'
>  end
> end
>
> module Lowercase
>   def alpha
>     'a'
>   end
> end
>
>
> class Upperfirst
>   include Uppercase
>   include Lowercase
> end
>
> class Uppersecond
>   include Lowercase
>   include Uppercase
> end
>
> first = Upperfirst.new
> second = Uppersecond.new
>
> puts "#{first.alpha} #{second.alpha}"
>
> Traits, on the other hand works by adding the methods directly into the
> class's method dictionary. It can't rely on inheritance to resolve
> conflicts, so it provides ways of explicitly resolving conflicts, as Ramon
> explained.
>
> Colin
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

Giovanni Corriga
Il giorno mar, 23/10/2007 alle 07.02 +0200, Jason Johnson ha scritto:
> But since these two systems are so similar what places are modules
> used in Ruby to the best effect?  I always used Haskell as my
> comparison, but it turns out this isn't a good idea because Haskell
> isn't an OO language, so the applicability is different.

An example of module use in the Ruby standard library is the collections
system. Ruby doesn't have an abstract Collection class that acts as the
superclass for all collection classes, but it has an Enumerable module
that implements methods such as #select, #collect, #inject, etc. All
these methods depend on the including class implementing #each (#each is
the Ruby equivalent of #do: ). All the concrete collection classes have
an #each method and include Enumerable in order to support the complete
collection protocol.

        Giovanni


Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

stephane ducasse
In reply to this post by Andreas.Raab
sorry I'm travelling.
The key difference between mixin like approaches and traits is that  
with traits the composer is in control.
There is an automatic conflict resolution but it is explicit in  
traits. With mixin the linearisation is implicit and often out
of control. For state we choose that to avoid merging of attributes  
having the same names, but this is not essential.

Some thoughts about our recent research:
We worked on stateful traits but I do not like what we did. I would  
like to revisit that soon with something much simpler. Roel is  
presenting freezable traits (to control early bindness of methods),  
but the semantics is too complex may be a ruby one is better.After  
done all that I realized that freezable traits is far too complex. So  
we learned something: traits version 1 are cool.
Traits have alias (to give a different name to a method) but may be  
deep renaming (as in Eiffel) would be better (but implementation
would be more complex).

Stef

On 22 oct. 07, at 22:37, Andreas Raab wrote:

> Out of curiosity, what is the difference between Ruby's modules and  
> traits? They strike me as extremely similar, but not being the  
> local Ruby guru I might overlook some implications. As far as I  
> understand it both allow "grouping of methods" (aka: include  
> statements) and both disallow state (in Ruby's case simply because  
> state access is always a dynamic attribute lookup). So what's the  
> difference?
>
> Cheers,
>   - Andreas
>
> stephane ducasse wrote:
>>> Quelques propos (récents) de matz (Yukihiro Matsumoto) à propos
>>> des Traits :
>>>
>>> - "Too bad I didn't know about traits when I designed Ruby."
>>>
>>> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274227
>>>
>>> - "If I knew traits before designing Ruby, I'd have chosen traits  
>>> over
>>> modules.  But that's the life."
>>>
>>> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274242
>> this is why I will try to find some times to polish traits in squeak
>> stef
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

stephane ducasse
In reply to this post by Colin Putney
> Traits, on the other hand works by adding the methods directly into  
> the class's method dictionary. It can't rely on inheritance to  
> resolve conflicts, so it provides ways of explicitly resolving  
> conflicts, as Ramon explained.

The way conflicts are resolved in not an accident in traits but a  
decision to give to the composer the control.
This is why we did not wanted linearisation as an implicit way to  
solve conflicts (I programmed with mixin in CLOS during my PhD
and there it was also linearisation based).

Stef

Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

stephane ducasse
In reply to this post by Jason Johnson-5
Hi jason

I'm not connected (just in a slooooow train lost in the country side  
of the Alps)

> In my conversations with Andreas, I always used Magnitude as the prime
> "obvious use case" example for Traits, but that turns out this
> actually doesn't work very well for the reasons laid out here:
> http://lists.squeakfoundation.org/pipermail/squeak-dev/2007- 
> September/120256.html
>
> Stephane, you might consider the things in that mail when you write
> the tools, i.e. make some tools with the idea that making objects can
> consist largely of dropping traits or even trait composition
> "templates" onto a class to define it.

Yes this would be interesting.

> Andreas, you mentioned a lot of extra complexity created by Traits (in
> Proto and so).  Is this due to the implementation of Traits themselves
> or a place where someone tried to show "value" with some refactorings
> that made things worse?

I think that the kernel is not worse (but tools are lacking to  
navigate).
This is due to:
        - the fact that we could not change totally the class (for example  
you cannot change Behavior).
        - the tools does not help navigating the code (this is difficult to  
introduce another navigation axe).
        - this was difficult to identify traits in existing code (because  
sometimes the code is not that nicely organized).

I think that Nile is a good example of using traits (after we can  
discuss if ReadWriteStream and ReadStream suck or not)
Traits are like first class protocol that can be shared and we do not  
get a nice way to navigate them.


> If it is the latter, then I had a plan of removing these refactoring
> and restarting with the goals defined in the email above.  My plate is
> full and overflowing, but I could farm this task out.

Have a look at Nile and comment it. I would like to redo the same  
with the collections.
restarting test first from scratch.

Stef

>
> On 10/23/07, Colin Putney <[hidden email]> wrote:
>>
>>
>> On Oct 22, 2007, at 2:44 PM, Ramon Leon wrote:
>>
>>
>> Ruby's modules don't allow this level of control.  Given modules with
>>
>> conflicting methods, you either get all from one or all from the  
>> other
>>
>> depending on the order you include them.  That is my understanding  
>> anyway.
>> Ramon is basically correct - the difference is in the way the  
>> conflicts are
>> resolved. If a method is defined in more than one place, which one  
>> is used?
>>
>> Ruby's modules work by inserting the module into the superclass  
>> chain. The
>> order that modules are included is the order they're inserted, so by
>> including module later in the sequence you can override earlier  
>> modules the
>> same way a subclass can override a superclass. For example, the  
>> following
>> script prints "a A":
>>
>> module Uppercase
>>  def alpha
>>  'A'
>>  end
>> end
>>
>> module Lowercase
>>   def alpha
>>     'a'
>>   end
>> end
>>
>>
>> class Upperfirst
>>   include Uppercase
>>   include Lowercase
>> end
>>
>> class Uppersecond
>>   include Lowercase
>>   include Uppercase
>> end
>>
>> first = Upperfirst.new
>> second = Uppersecond.new
>>
>> puts "#{first.alpha} #{second.alpha}"
>>
>> Traits, on the other hand works by adding the methods directly  
>> into the
>> class's method dictionary. It can't rely on inheritance to resolve
>> conflicts, so it provides ways of explicitly resolving conflicts,  
>> as Ramon
>> explained.
>>
>> Colin
>>
>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

stephane ducasse
In reply to this post by Giovanni Corriga
thanks for the pointer!
I should look at that.

Stef

On 23 oct. 07, at 10:01, Giovanni Corriga wrote:

> Il giorno mar, 23/10/2007 alle 07.02 +0200, Jason Johnson ha scritto:
>> But since these two systems are so similar what places are modules
>> used in Ruby to the best effect?  I always used Haskell as my
>> comparison, but it turns out this isn't a good idea because Haskell
>> isn't an OO language, so the applicability is different.
>
> An example of module use in the Ruby standard library is the  
> collections
> system. Ruby doesn't have an abstract Collection class that acts as  
> the
> superclass for all collection classes, but it has an Enumerable module
> that implements methods such as #select, #collect, #inject, etc. All
> these methods depend on the including class implementing #each  
> (#each is
> the Ruby equivalent of #do: ). All the concrete collection classes  
> have
> an #each method and include Enumerable in order to support the  
> complete
> collection protocol.
>
> Giovanni
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [Squeak-fr] Ruby et les Traits.

Bergel, Alexandre
In reply to this post by Andreas.Raab
Hi Andreas,

Ruby modules are mixins. The only way to compose mixins is inheritance.
With traits, you have different operators to do some fine tuning.

Cheers,
Alexandre


On 22 Oct 2007, at 16:37, Andreas Raab wrote:

> Out of curiosity, what is the difference between Ruby's modules and  
> traits? They strike me as extremely similar, but not being the  
> local Ruby guru I might overlook some implications. As far as I  
> understand it both allow "grouping of methods" (aka: include  
> statements) and both disallow state (in Ruby's case simply because  
> state access is always a dynamic attribute lookup). So what's the  
> difference?
>
> Cheers,
>   - Andreas
>
> stephane ducasse wrote:
>>> Quelques propos (récents) de matz (Yukihiro Matsumoto) à propos
>>> des Traits :
>>>
>>> - "Too bad I didn't know about traits when I designed Ruby."
>>>
>>> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274227
>>>
>>> - "If I knew traits before designing Ruby, I'd have chosen traits  
>>> over
>>> modules.  But that's the life."
>>>
>>> http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/274242
>> this is why I will try to find some times to polish traits in squeak
>> stef
>
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.