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

