>
> 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.
>Now I see what you're getting at. Interesting! If you think of traits.js as a general-purpose property descriptor map manipulation library, then this seems to be a very nice-to-have feature. If you think of traits.js as a trait composition library, then it probably does introduce too much distraction, especially if the meta-data is not related to trait composition at all. One possibility would be to fork traits.js into two libraries, such that the traits-specific composition library is a specialization of a more general-purpose property map combinator library. I don't know whether it's worth doing that. I would need to have a better idea of what other useful specializations one could construct out of a more general-purpose library, but perhaps we should have that discussion offline (or at least fork it off of the traits-oriented discussion thread). Cheers, Tom > > 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

