updated API with Trait and the extra argument: https://github.com/WebReflection/object-mixin#api
how does the code look like now: https://github.com/WebReflection/object-mixin/blob/master/src/object-mixin.js is your browser passing all tests? (if green, yes) http://webreflection.github.io/object-mixin/test/ Best Regards On Sun, Apr 14, 2013 at 10:23 PM, Andrea Giammarchi < andrea.giammar...@gmail.com> wrote: > not sure changing name is a thing to promote, it makes method name > clashing easier but it can be achieved simply attaching properties to a > specific object and then pass that as mixin ... > > Object.mixin(target, { > on: source.addEventListener, > off: source.removeEventListener, > has: source.hasEventListener, > trigger: source.dispatchEvent > }); > > As you see there's no need to make the signature more complex with > aliases, it's straight forward to do the same, of course if those > descriptor are meant to be (enumer|configur|writ)able: true) > > Agreed on Trait naming convention, but these can be represented only via > Functions in JS. > > However, describing them as "not exactly common function" would result in > a better understanding. > > So here the API, and the name I am afraid has always been abused in JS but > is known as "mixin" > > // basic signature > Object.mixin( > target:Object, > source:Object > ):target > > // one overload > Object.mixin( > target:Object, > source:Trait > [,args:Array|Arguments] > ):target > > This is probably even better than needed/horrible slice call and > arguments.length check per each mixin invocation with Traits ... so, what > do you think ? > > > > > > > On Sun, Apr 14, 2013 at 8:56 PM, Peter Seliger < > peter.seli...@googlemail.com> wrote: > >> Hi, maybe one should discuss terminology first. >> >> What has been rediscovered within the last decade every now and again by >> JavaScript programming individuals, this languages capability for >> "functional or function based mixins", might deserve a closer look, before >> running into what I would call a meta programming temptation trap. >> >> We already have everything we need in order to create modular collections >> of behavior and also in order to provide and apply them to objects. >> >> "Mixin" might be a Ruby influenced term and does not completely cover >> what can be achieved by functions/closures [call] and [apply]. I'd rather >> tend to use Perl 6 "Roles" as a generic term. >> >> The smallest thinkable Role was a function body that implements a single >> method in a stateless way. Thus being a "Trait" if one follows the findings >> of the "Software Composition Group" at Bern University [ >> http://scg.unibe.ch/research/traits]. Any implementation that gets >> injected mutable state or does create mutable state on its own in oder to >> solve its task(s) then, from my point of view, should be referred to as >> "Mixin". >> >> > It seems that Mixins Are Awesome and this can take most advantages from >> being a function and not only an object: >> > http://webreflection.blogspot.ie/2013/04/flight-mixins-are-awesome.html >> > >> > AFAIK, all interfaces described in W3C such EventTarget and others >> could be also covered by this proposal ... so ... what do you think ? >> >> Andrea, you are right, but all it needs in my opinion are a module >> pattern, a module library of your choice, a naming convention for your >> Trait/Mixin-module Implementation (adjectives/adverbes, no nouns, first >> uppercase letter?) and again [call] or [apply]. >> >> For your given example of W3C interfaces, [EventTarget] should be >> implemented and internally referred to as [EventTargetMixin], but the >> module should expose [EventTargetMixin] as [Observable]. >> >> - example gist for Observable [https://gist.github.com/petsel/5385218]. >> - example gist for a Trait [https://gist.github.com/petsel/5385163]. >> >> There is another point that makes pure straightforward functional >> Trait/Mixin composition unique in JavaScript - passing additional data at >> apply time. One could write e.g. implementations that at apply time can >> adapt the naming of their functional API without changing the underlying >> implementation itself. [Observable] from the above provided gist example >> enables configuration of the default API method names by an optionally >> passed config object making it >> possible to serve all those weird observable API dialects. >> >> var obj_01 = {}; >> var obj_02 = {}; >> >> Observable.call(obj_01); /* does add the default api methods >> [addEventListener], [removeEventListener], [hasEventListener] and >> [dispatchEvent] */ >> >> Observable.call(obj_02, { >> addEventListener: "on", >> removeEventListener: "off", >> hasEventListener: "hasObserver", >> dispatchEvent: "trigger" >> }); /* obj_02 does feature the custom api names [on], [off], >> [hasObserver] and [trigger] - the underlying methods are the same as of >> obj_01 */ >> >> With meta programming approaches this advantage, one gets for free now, >> might get lost or if implemented less understandable. >> >> I discarded every single approach I made within the last 5 years for >> Trait/Mixin libraries, that tried to be smarter than what the languages >> core already provides except the last one that just sticks to a module >> library. >> >> >> >> >> On Sun, Apr 14, 2013 at 11:48 PM, Andrea Giammarchi < >> andrea.giammar...@gmail.com> wrote: >> >>> somebody already raised the concern "what if I want to mixin the >>> function as object, not as callable" >>> >>> I think being [[Call]] not possible to mixin as object functionality, >>> and being functions all by default having ownProperties such ["arguments", >>> "name", "length", "caller"] .. that would simply clash so function as >>> argument, for this purpose, is never ambiguous, but of course a function >>> could be the target object, if needed >>> >>> var withMoar = Object.mixin(function(){}, mixinFunction); >>> // same as mixinFunction.call(function(){}); >>> >>> >>> >>> >>> >>> >>> >>> On Sun, Apr 14, 2013 at 2:24 PM, Angus Croll <anguscr...@gmail.com>wrote: >>> >>>> yeah that's better - I was having a senior moment - most constructor >>>> functions will normally reside in the prototype of course >>>> >>>> >>>> On Sun, Apr 14, 2013 at 1:59 PM, Andrea Giammarchi < >>>> andrea.giammar...@gmail.com> wrote: >>>> >>>>> My previous version was doing that in a probably too smart way so I've >>>>> simplified the proposal simply accepting, in that example >>>>> >>>>> Object.mixin(Thung.prototype, Thing.proottype); >>>>> Object.mixin(Thung.prototype, Thang.proottype); >>>>> >>>>> It does not look so black magic anymore but it's way less ambiguous >>>>> than the first proposal (I guess) >>>>> >>>>> Thanks >>>>> >>>>> >>>>> >>>>> >>>>> On Sun, Apr 14, 2013 at 1:34 PM, Angus Croll <anguscr...@gmail.com>wrote: >>>>> >>>>>> Lending my support to Object.mixin accepting a function as the >>>>>> argument—but no surprise there I guess :) >>>>>> >>>>>> Note: since functional mixins and constructors are syntactically >>>>>> identical we can now get gorgeously expressive—and make type inheritance >>>>>> way simpler (for the first time allowing multiple type inheritance) >>>>>> >>>>>> //make a new thing and a new thang >>>>>> var thing = new Thing; >>>>>> var thang = new Thang; >>>>>> >>>>>> //OR have Thung inherit from Thing and Thang >>>>>> Object.mixin(Thung.prototype, Thing); >>>>>> Object.mixin(Thung.prototype, Thang); >>>>>> >>>>>> >>>>>> On Sun, Apr 14, 2013 at 12:59 PM, Andrea Giammarchi < >>>>>> andrea.giammar...@gmail.com> wrote: >>>>>> >>>>>>> right, I've simplified a lot and tested cross platform: >>>>>>> >>>>>>> https://github.com/WebReflection/object-mixin#object-mixin >>>>>>> >>>>>>> thoughts? >>>>>>> >>>>>>> >>>>>>> On Sun, Apr 14, 2013 at 10:07 AM, Andrea Giammarchi < >>>>>>> andrea.giammar...@gmail.com> wrote: >>>>>>> >>>>>>>> OK, maybe just code was a non-sense ... >>>>>>>> >>>>>>>> So, the idea behind is mark a function explicitly as mixin ... how ? >>>>>>>> >>>>>>>> Any function that is passed and has an empty prototype (then is >>>>>>>> user defined or native) could be considered invocable as mixin. >>>>>>>> >>>>>>>> function addFunctionality() { >>>>>>>> this.method = function () { >>>>>>>> // now the outer context has a method >>>>>>>> }; >>>>>>>> } >>>>>>>> >>>>>>>> // mark the prototype as empty in ES5 >>>>>>>> delete addFunctionality.prototype.constructor; >>>>>>>> >>>>>>>> function MyClass() {} >>>>>>>> >>>>>>>> Object.mixin(MyClass.prototype, addFunctionality); >>>>>>>> >>>>>>>> rather than only >>>>>>>> >>>>>>>> Object.mixin(MyClass.prototype, {method: function () {}}); >>>>>>>> >>>>>>>> If the prototype has at least one own property in its prototype it >>>>>>>> will be considered a constructor so that: >>>>>>>> >>>>>>>> Object.mixin(MyClass.prototype, MySuperClass); >>>>>>>> >>>>>>>> can easily be transformed implicitly into: >>>>>>>> Object.mixin(MyClass.prototype, MySuperClass.prototype); >>>>>>>> >>>>>>>> >>>>>>>> This case is, however, less important, the fact Object.mixin should >>>>>>>> be able to accept a function and invoke it with target as context with >>>>>>>> optional arguments would be really a **great idea**, IMHO >>>>>>>> >>>>>>>> Thanks >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On Sun, Apr 14, 2013 at 2:45 AM, Andrea Giammarchi < >>>>>>>> andrea.giammar...@gmail.com> wrote: >>>>>>>> >>>>>>>>> also, in case you are guessing the typo .. reacher because it >>>>>>>>> could reach more (older) engines, doing a joke with richer .... got >>>>>>>>> it? .. >>>>>>>>> too damn fun, I know! >>>>>>>>> >>>>>>>>> >>>>>>>>> On Sun, Apr 14, 2013 at 2:04 AM, Andrea Giammarchi < >>>>>>>>> andrea.giammar...@gmail.com> wrote: >>>>>>>>> >>>>>>>>>> apologies >>>>>>>>>> getOwnPropertyDescriptor( >>>>>>>>>> source, >>>>>>>>>> key >>>>>>>>>> ) >>>>>>>>>> >>>>>>>>>> should have been >>>>>>>>>> getOwnPropertyDescriptor( >>>>>>>>>> enricher, >>>>>>>>>> key >>>>>>>>>> ) >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Sun, Apr 14, 2013 at 1:58 AM, Andrea Giammarchi < >>>>>>>>>> andrea.giammar...@gmail.com> wrote: >>>>>>>>>> >>>>>>>>>>> what I've written here: >>>>>>>>>>> >>>>>>>>>>> https://github.com/WebReflection/object-mixin/blob/master/src/object-mixin.js >>>>>>>>>>> >>>>>>>>>>> is a better proposal for the potential `Object.mixin()` in >>>>>>>>>>> current ES6 specs. >>>>>>>>>>> >>>>>>>>>>> It seems that Mixins Are Awesome and this can take most >>>>>>>>>>> advantages from being a function and not only an object: >>>>>>>>>>> >>>>>>>>>>> http://webreflection.blogspot.ie/2013/04/flight-mixins-are-awesome.html >>>>>>>>>>> >>>>>>>>>>> AFAIK, all interfaces described in W3C such EventTarget and >>>>>>>>>>> others could be also covered by this proposal ... so ... what do >>>>>>>>>>> you think ? >>>>>>>>>>> >>>>>>>>>>> /*jslint browser: true, forin: true, plusplus: true, indent: 4 */ >>>>>>>>>>> (function(Object, mixin) { >>>>>>>>>>> "use strict"; // happy linter ^_____^ >>>>>>>>>>> >>>>>>>>>>> /* <droppable> >>>>>>>>>>> * adhoc polyfill section for this purpose only >>>>>>>>>>> * never use these functions outside this closure ... like >>>>>>>>>>> ... >>>>>>>>>>> ne*/var >>>>>>>>>>> /* >>>>>>>>>>> ^ ... you see that? only reason I chose 4 spaces indentations >>>>>>>>>>> here :D >>>>>>>>>>> also this comment ... pure quality, right ?!?! ... anyway >>>>>>>>>>> ... */ >>>>>>>>>>> >>>>>>>>>>> // for IE < 9 Desktop browsers >>>>>>>>>>> defineProperty = Object.defineProperty || >>>>>>>>>>> function (o, k, d) { >>>>>>>>>>> o[k] = d.value; >>>>>>>>>>> }, >>>>>>>>>>> // same as above >>>>>>>>>>> getOwnPropertyNames = Object.getOwnPropertyNames || >>>>>>>>>>> function (o) { >>>>>>>>>>> var >>>>>>>>>>> // in case the guy does not inherit from >>>>>>>>>>> Object.prototype >>>>>>>>>>> has = Object.prototype.hasOwnProperty, >>>>>>>>>>> result = [], >>>>>>>>>>> key; >>>>>>>>>>> for (key in o) { >>>>>>>>>>> // in non ES5 compliant browsers >>>>>>>>>>> // there's no way to define properties >>>>>>>>>>> // as non enumerable unless these are >>>>>>>>>>> // there by default, like "constructor" is >>>>>>>>>>> // for functions.prototype >>>>>>>>>>> if (has.call(o, key)) { >>>>>>>>>>> result.push(key); >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> return result; >>>>>>>>>>> }, >>>>>>>>>>> // again ... IE < 8 >>>>>>>>>>> getOwnPropertyDescriptor = >>>>>>>>>>> Object.getOwnPropertyDescriptor || >>>>>>>>>>> function (o, k) { >>>>>>>>>>> return { >>>>>>>>>>> enumerable: true, >>>>>>>>>>> writable: true, >>>>>>>>>>> configurable: true, >>>>>>>>>>> value: o[k] >>>>>>>>>>> }; >>>>>>>>>>> }; >>>>>>>>>>> // </droppable> >>>>>>>>>>> >>>>>>>>>>> // if already defined get out of here >>>>>>>>>>> // this should be >>>>>>>>>>> // if (mixin in Object) return; >>>>>>>>>>> // but for some reason I went for JSLint ... >>>>>>>>>>> if (Object[mixin]) { >>>>>>>>>>> return; >>>>>>>>>>> } >>>>>>>>>>> // same descriptor as other spec'd methods >>>>>>>>>>> defineProperty( >>>>>>>>>>> Object, >>>>>>>>>>> mixin, >>>>>>>>>>> { >>>>>>>>>>> enumerable: false, >>>>>>>>>>> writable: true, >>>>>>>>>>> configurable: true, >>>>>>>>>>> value: function mixin( >>>>>>>>>>> target, // object to enrich with >>>>>>>>>>> source // mixin object/function >>>>>>>>>>> ) { >>>>>>>>>>> var >>>>>>>>>>> // check if source is a function >>>>>>>>>>> enricher = typeof source === 'function' ? >>>>>>>>>>> source.prototype : source, >>>>>>>>>>> // per each own property name >>>>>>>>>>> keys = getOwnPropertyNames(enricher), >>>>>>>>>>> length = keys.length, >>>>>>>>>>> i = 0, >>>>>>>>>>> key; >>>>>>>>>>> while (i < length) { >>>>>>>>>>> // define it ... >>>>>>>>>>> defineProperty( >>>>>>>>>>> target, >>>>>>>>>>> key = keys[i++], >>>>>>>>>>> // ... via same property descriptor >>>>>>>>>>> getOwnPropertyDescriptor( >>>>>>>>>>> source, >>>>>>>>>>> key >>>>>>>>>>> ) >>>>>>>>>>> ); >>>>>>>>>>> } >>>>>>>>>>> // if the object had no own names >>>>>>>>>>> // it's quite clear the intention of the user >>>>>>>>>>> // so that if a function without properties >>>>>>>>>>> // is passed through this method ... >>>>>>>>>>> if (!length && typeof source === 'function') { >>>>>>>>>>> // this function is invoked with the target >>>>>>>>>>> // as its own context >>>>>>>>>>> source.apply( >>>>>>>>>>> target, >>>>>>>>>>> // optional arguments to initialize >>>>>>>>>>> defaults >>>>>>>>>>> // for this mixin might be accepted too >>>>>>>>>>> keys.slice.call(arguments, 2) >>>>>>>>>>> ); >>>>>>>>>>> } >>>>>>>>>>> // always return the initial target >>>>>>>>>>> // ignoring a possible different return >>>>>>>>>>> // in latter case: consistency with this method >>>>>>>>>>> return target; >>>>>>>>>>> } >>>>>>>>>>> } >>>>>>>>>>> ); >>>>>>>>>>> }(Object, 'mixin')); >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> es-discuss mailing list >>>>>>> es-discuss@mozilla.org >>>>>>> https://mail.mozilla.org/listinfo/es-discuss >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >>> _______________________________________________ >>> es-discuss mailing list >>> es-discuss@mozilla.org >>> https://mail.mozilla.org/listinfo/es-discuss >>> >>> >> >
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss