Thanks Tom.

The traits concept resonates with something very similar I had prototyped which 
you briefly describe under 'Traits and Type Tests'.
Specifically where you describe
var o = Trait.create(proto, trait, { implements: [ brand1, brand2, ... ] });


The object literal I had used was { 'private': { ... }, 'constructor': 
function() { ... }, 'privileged': { ... }, 'public': { ... }, 'actions': { ... 
}, 'init': function() { ... } }

By providing groupings in the form of a meta-model, type classification was 
greatly improved in the resulting object along with reflection capabilities 
and other advantages when a javascript meta-model is enabled. For example 
'private' would mean closures, 'actions' would mean the 
methods would be automating bound to Function.bind. One thing I did which may 
be worth considering is to make the 
'Trait' object extensible by allowing it to also be extended via composition. 
Although this is somewhat metacircular, it provides 
the ability to add new meta-data other than 'required' and have that meta-data 
handled within the extended Trait object.
For example, if you wanted to indicate whether a property should be documented 
you could do something like
{ a: Trait.document } where you would expand Trait to handle this new meta-data 
by doing something like 
Trait.compose(Trait, {'document': function() { ... }}). Match a new meta-data 
property with a Trait method of the same name 
would be one possible way of making Trait extensible in similar ways as java 
annotations. Given your expertise in this area,
would you view this meta-circular approach as a way to extend Trait into areas 
beyond composition where 
more semantic behavior could be injected given a new meta-data keyword? You may 
feel this distorts the simple semantics 
but I would be interested in hearing your views.

thx
kam



________________________________
From: Tom Van Cutsem <[email protected]>
To: Kam Kasravi <[email protected]>
Cc: es-discuss <[email protected]>
Sent: Wed, February 17, 2010 6:19:12 PM
Subject: Re: Traits library

As a follow-up to my earlier reply to Kam, I included a diagram at 
<http://code.google.com/p/es-lab/wiki/Traits#API> that helps to clarify what 
kinds of objects and operations are involved in using the library.


On Wed, Feb 17, 2010 at 4:54 PM, Tom Van Cutsem <[email protected]> wrote:

>Hi Kam,
>
>
>>>
>>One use case when using traits in this way is 
>>whether traits (either using Trait.create or Object.create) could be used to 
>>replace prototypical inheritance rather than 
>>classical inheritance. That is, can traits be used to compose different 
>>blocks from different instances rather than
>>different classes.
>
>
>Yes, the traits library enables this, because it allows instances to be 
>'lifted' into traits. Just like the library provides two ways to generate an 
>object from a property map (either use Object.create or Trait.create), the 
>library provides two ways to generate a property map from an object:
>- either use the Trait constructor: Trait(object) -> property-map
>- or use Object.getOwnProperties(object) -> property-map
>
>
>I didn't mention this on the wiki page, but the traits.js library actually 
>goes ahead and adds the "missing" 'getOwnProperties' utility method to Object 
>if it doesn't already exist, precisely because it's so useful in combination 
>with representing traits as property maps. getOwnProperties is a simple 
>utility method based on ES5's getOwnPropertyNames + getOwnPropertyDescriptor 
>built-in methods.
>
>
>Just like Trait.create is the "trait-aware" version of Object.create, the 
>Trait constructor is the "trait-aware" version of Object.getOwnProperties. The 
>Trait constructor will, for example, recognize properties bound to 
>Trait.required, whereas Object.getOwnProperties will not.
>
>
>That said, I envisaged the Trait constructor to be used in the absolute 
>majority of cases in conjunction with an in-line object literal, as in 
>Trait({...}). Generally, I don't think it makes a lot of sense to turn an 
>actual instance back into a trait (it's like turning an object into a class). 
>But the library doesn't stop you from using Trait or Object.getOwnProperties 
>on arbitrary instances if this is really what you want to do.
>
>
>Cheers,
>Tom
> 
>>>
>>
>>
>>kam
>>
>>
>>>>
________________________________
From: Tom Van Cutsem <[email protected]>
>>To: Kam Kasravi <[email protected]>
>>Cc: es-discuss <[email protected]>
>>Sent: Wed, February 17, 2010 2:49:43 PM
>>Subject: Re: Traits library
>>
>>
>>
>>Hi Kam,
>>
>>
>>Thanks for the clarification. As far as I can tell, what you are describing 
>>is an example that would require trait composition to be postponed until 
>>runtime (as it depends on runtime context). The way I see it, the traits 
>>library would not prevent that: since traits are not static entities but just 
>>property maps that are manipulated at runtime, I see no fundamental obstacle 
>>to writing a generic dispatching function that, given some context, returns 
>>the appropriate traits or trait composition making up a drawing editor.
>>
>>
>>However, I would like to point out that if this is your desired use case, 
>>then traits may not be the right building block. As you point out yourself, 
>>the example you're describing seems like a perfect match for multi-methods. I 
>>do not think that 'dynamic trait composition' is a good alternative for 
>>multi-methods. At least, that's not the use case for which traits have been 
>>designed. Traits are an alternative to composition by inheritance. As is the 
>>case in typical single/mixin/multiple-inheritance schemes, the relationship 
>>between the inheriting entities is usually known (and declared) statically 
>>and is immutable. I see traits more like a static building block that can be 
>>used to organize code (while enabling a higher reuse potential than that 
>>provided by classes+single-inheritance).
>>
>>
>>Some details:
>>
>>
>>It doesn't sound like traits would 
>>>enable this 'pattern' given different methods need to be mixed in
>>> with 
>>>appropriate context from the implementation and all methods are final. 
>>
>>
>>Methods are 'final' upon trait composition only when a property map is 
>>instantiated using "Trait.create". If "Object.create" is used, the 
>>instantiated object is a plain Javascript object with all of the malleability 
>>this implies.
>> 
>>>>>Passing attributes like 
>>>background, border in the property descriptor would seem to be an abuse 
>>>of the meta-data framework by passing data not meta-data.
>>
>>
>>I completely agree. When I proposed the use of attributes to store data in 
>>property descriptors in my earlier message, I thought you meant to store 
>>meta-data.
>>
>>
>>Cheers,
>>Tom
>>>>
>>
>> 
>>
>>>
>>>thx
>>>kam
>>>
>>>
>>>>>>
>>>
________________________________
From: Tom Van Cutsem <[email protected]>
>>>To: Kam Kasravi
>>> <[email protected]>
>>>Cc: es-discuss <[email protected]>
>>>Sent: Tue, February 16, 2010 7:18:48 PM
>>>Subject: Re: Traits library
>>>
>>>
>>>>>>Hi Kam,
>>>
>>>
>>>If I understand the implementation of traits, it provides a ES5 compatible 
>>>way of composing 'final' properties to an existing object's prototype.
>>>>Options provide the meta-data required to define the property descriptor 
>>>>such as required, etc. Do traits provide an ability to bind 
>>>>a 'context' to the property in the form of a closure so that the property 
>>>>may be provided with additional information?
>>>>Effectively a way to curry or export additional information required by the 
>>>>trait when it is called in the context of the object it was added to.
>>>
>>>
>>>I'm not entirely sure I understand the question. Do you have a particular 
>>>use case in mind or can you give an example to clarify things?
>>>As far as I can understand, if what you want is additional meta-data stored 
>>>in property descriptors, this can be done by adding additional attributes to 
>>>the descriptors. In effect, that's what the library already does for 
>>>'required' and 'conflicting' properties.
>>>
>>>
>>>Cheers,
>>>Tom
>>> 
>>>
>>>>
>>>>thx
>>>>kam
>>>>
>>>>
>>>>
>>>>
>>>>>>>>
>>>>
>>>>
________________________________
From: Tom Van Cutsem <[email protected]>
>>>>To: es-discuss <[email protected]>
>>>>Sent: Tue, February 16, 2010 2:55:50 PM
>>>>Subject: Traits library
>>>>
>>>>
>>>>>>>>Hi,
>>>>
>>>>
>>>>Mark Miller and I have been working on a small traits library for 
>>>>Javascript. It is documented here: 
>>>><http://code.google.com/p/es-lab/wiki/Traits>
>>>>
>>>>
>>>>Traits are reusable building blocks for classes, very similar to mixins, 
>>>>but with less gotchas. For example, traits support explicit conflict 
>>>>resolution upon name clashes and the order in which traits are composed is 
>>>>not significant.
>>>>
>>>>
>>>>In a nutshell:
>>>>- The library is designed for ES5, but backwards-compatible with existing 
>>>>ES3 implementations.
>>>>- Our library represents traits as ES5 property maps (objects mapping 
>>>>property names to property descriptors). The library exports:
>>>> - a convenient trait "constructor" to generate property maps from object 
>>>> literals.
>>>> - a number of "trait combinators" to compose property maps.
>>>> - a function that can "instantiate" such property maps into objects 
>>>> (analogous to the ES5 Object.create function, but with awareness about 
>>>> trait-specific property semantics).
>>>>
>>>>
>>>>The interesting thing about our choice of transparently representing traits 
>>>>as ES5 property maps is that our library can be used as a general-purpose 
>>>>library for manipulating property descriptors in addition to its use as a 
>>>>library to compose and instantiate traits.
>>>>
>>>>
>>>>A small expository example that uses the library:
>>>><http://code.google.com/p/es-lab/source/browse/trunk/src/traits/examples.js>
>>>>
>>>>
>>>>Mark and I were both surprised at how well Javascript accommodates a trait 
>>>>library with very little boilerplate. However, there is one catch to 
>>>>implementing traits as a library. Traits, like classes, are normally simply 
>>>>declared in the program text, but need not necessarily have a runtime 
>>>>representation. Trait composition is normally performed entirely at 
>>>>compile-time (in trait lingo this is called "flattening" the traits). At 
>>>>runtime, no trace of trait composition is left.
>>>>
>>>>
>>>>Because we use a library approach, traits are not declarative entities and 
>>>>must have a runtime representation. Thus, there is a runtime overhead 
>>>>associated with trait creation and composition. Moreover, because the 
>>>>implementation is oblivious to traits, multiple objects instantiated from 
>>>>the same trait "declaration" don't share structure. However, we did design 
>>>>the library such that, if traits are specified using object literals and 
>>>>property renaming depends only on string literals (which is the common 
>>>>case), a partial evaluator could in principle perform all trait composition 
>>>>statically, and replace calls to Trait.create with a specialized 
>>>>implementation that does support structural sharing between instances (just 
>>>>like an implementation that notices multiple calls to Object.create with 
>>>>the same property descriptor map can in principle arrange for the created 
>>>>objects to share structure).
>>>>
>>>>
>>>>Any feedback on our design is welcomed. In particular, it'd be interesting 
>>>>to hear how hard/easy it would be for an implementation to recognize the 
>>>>operations performed by our library in order to perform them statically.
>>>>
>>>>
>>>>Cheers,
>>>>Tom
>>>
>>
>
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to