Hi Jake, These statements from my readme are not about efficiency of the prototype chain, but more about code structure and maintainability...trying to make it so decisions you take now in a class hierarchy don't need to keep being revisited based on future sub- class decisions. The great thing about Javascript (compared to the C++ world I used to develop in where you have to think about diamond inheritance patterns, etc) is its flexibility.
Despite its flexibility, I have still seen developers choose inheritance over composition in their Javascript classes. I believe part of the reason for this is that there wasn't a good and easy to understand aspect-oriented framework and given the flexibility of Javascript almost too many ways to do things meaning everyone does what they want and sometimes it is at the expense of re-usability. This is where I am hoping that Mixin.js comes in...it has served me well on my personal projects, I believe it is mature and useable enough to start having some other people use it and to provide some feedback, so I spent some time to package it up to share it, and I'm hoping other people will also benefit from it too. I see very much that you have spent a lot of time and thought working on your property descriptor library and that you also believe it can benefit people. Great! That said, I develop in Coffeescript which has an OK class model and I live with it, and already have a significant codebase based on Mixin.js so what I am really interested in is getting a few recommendations to my four (hopefully precise enough) questions from this morning to improve my library. I am happy to integrate improvements from the community into the library and to take requests, but I'm sorry to say that unless someone points out a critical flaw or until a better library than mine becomes massively adopted with a large library of available mixins, I am unlikely to pay the cost of changing my approach. I really appreciate your enthusiasm and passion, but time is short and so I need to pragmatically focus on improving what I've already got. Kevin On Oct 17, 11:24 am, Jake Verbaten <[email protected]> wrote: > On Mon, Oct 17, 2011 at 10:04 AM, kmalakoff <[email protected]> wrote: > > I really appreciate our discussion (see the below except from the > > README) as it has help me to clarify the goals and differences with > > the standard mixin. > > > The reason I raised this JSMentor is to try to get some feedback on > > this framework which is a bit different from standard mixin. I'm > > hoping that you and others may feel compelled to try using this way of > > doing things since I'm not sure, but I think there aren't other > > frameworks for instance-level mixins lifecycle control! > > > It still mixes things in at a class level, but also provides instance > > level initialize and destroy given that I couldn't really find a > > mechanism or standard using Object.extend to do this. So I primarily > > use this library as the standard mixin with instance-level initialize > > and destroy which is why I called it mixin.js rather than > > aspect.js...I'll open a question on the renaming and see what people > > think. > > > Cheers, > > > Kevin > > > I've updated the README to try to help explain things: > > > **************************** > > Mixin.js brings "dynamic aspect-oriented programming" to Javascript. > > "Dynamic" means you can add and remove independently encapsulated > > functionality and data to your instances on-the-fly. "Aspect-oriented" > > means you can flatten your class hierarchy and add/remove > > functionality only where & when needed. > > > Classic object-oriented design can force you to regularly make > > tradeoff decisions based on your evolving subclasses like deciding > > between polluting common super classes (eg. push common functionality > > up the hierarchy whenever it needs to be reused) vs making un-DRY code > > when only a subset of sub-classes require common functionality (eg. > > cut/paste and maintain the code). Mixin.js provides you with a light > > framework to avoid the decision altogether...make a mixin, use it > > where & when you need it...decisions made, stay made. > > One should never make un-DRY code so any code that something needs should be > inherited, can you give concrete examples of when inheritance won't work and > I should be using an aspect for behaviour at the object level? > > > > > **************** > > I bet you're asking yourself what made me I write this anyways > > and...isn't it overkill? > > > The problem I had was that I was implementing Backbone.Views. Some of > > them needed scrollable content areas (using iScroll), some of them > > needed to be dynamically rendered based on Backbone.Models loading and > > unloading whereas others needed to render collections, some of them > > needed to have timers to change state after a specific timeout, all of > > them had custom destroy methods to unbind jQuery events, some views > > needed to subscribe to state changes on other views, etc. My base view > > class was becoming a kitchen sink class and I thought, there's got to > > be a better way! > > Yes there is a better way, don't dump methods in your "base class" build up > inheritance chains, make a Backbone.views.scrollableView, Make a > Backbone.views.dynamicView > > > > > So I started on the path of factoring out each aspect, providing > > initialize and destroy code for each, and mixing-in functionality on > > the fly. Now, I have a very simple view base class that only provides > > the minimal & common view functionality (it actually doesn't even need > > to be a Backbone.View anymore since all the functionality is now in > > mixins) and a view hierarchy two deep. Each view is simple to read, > > Why is a deep hierachy bad? You realise that the prototype chain is a > heavily optimised beast, there is very little overhead in walking the > prototype chain, and even that overhead dissappears with the JIT. > > > > > > > > > light on code, and customized to meet its unique needs. > > **************************** > > > On Oct 16, 1:11 pm, Jake Verbaten <[email protected]> wrote: > > > Have you considered renaming it to aspect.js ? > > > > Seriously, mixins are mixed into classes and I used that term and concept > > > all the way through your code to judge it. > > > > Personally Ive never used aspects and I dont like changing the behaviour > > or > > > meaning of objects at run time. i may need to look into your examples > > some > > > more. > > > > I simply cant relate because thats not how I code > > > > On Oct 16, 2011 4:07 AM, "kmalakoff" <[email protected]> wrote: > > > > Hi Jake, > > > > Thank you for the feedback! You raise some very important concerns and > > > tradeoffs in the design of the API. My short answer is that most of > > > the aspects you raised comes out of the goal of the library being in > > > creating a dynamic-aspect-oriented framework and arose from the API > > > evolved to solve real problem I encountered when developing and using > > > the API, but I'll go into more detail, provide use cases, and you can > > > judge whether there are better solutions to the problems! > > > > Comments (KM>) inline.... > > > > On Oct 12, 5:19 pm, Jake Verbaten <[email protected]> wrote: > I have no > > > (big) problems with readi... > > > > > mixin method (pd.mixin <https://github.com/Raynos/pd#pd.mixin>) > > > > > // use pd to make example simple :https://github.com/Raynos/pd> > > > > pd.extendNatives(); > > var Sup... > > > > > // yes Object.prototype.new - > >https://github.com/Raynos/pd#pd.extendNatives > > > > // is awesome > var rockstar1 = RockStar.new(); > > var Fan = {}; > var > > > > fan1 = Fan.new(), fan2 = F... > > > > > Live Example <http://jsfiddle.net/nJbXW/1/> > > > > KM> I've looked at your library and examples. Unfortunately, I > > > actually updated the Rockstar example in the README (https:// > > > github.com/kmalakoff/mixin) after posting it here to demonstrate the > > > dynamic nature of the proposed system (basically dynamically adding/ > > > removing mixins to instances on the fly). Also, the example was design > > > to demonstrate the API in a concise way, not to provide an advanced > > > use case to justify the purpose of the library (classic disconnect > > > between real-world problems and examples). I believe the problem you > > > are trying to address is improving the OO nature of Javascript, > > > whereas, the library I am proposing is trying to address a slightly > > > different problem space that could be described as "dynamic aspect- > > > oriented programming". In other words, allowing the library user to > > > respond dynamically to situations and importantly, give them a > > > convention for cleaning up. > > > > In some situations, what I propose is unnecessary/overkill and in some > > > situations it fits the bill (but of course, there will always be > > > different ways to solve the same problem) - I included the > > > subscriptions mixin as a more advanced example. I'll try to explain > > > these design considerations in responding to your points below. > > > > > Now let's take a moment to go back to the API methods you've shown in > > your > > > > example. > > > > > *Mixin.registerMixin * > > > > > Why would you want to register a mixin by string name? A mixin should > > > > just > be an object. > > > KM> Originally I was using objects. The problem I ran into was that I > > > was using CommonJS that required a path to the object so when I > > > packaged the library and sample mixins I needed to 1) find a way to > > > provide users the flexibility to pick and choose which mixins they use > > > and 2) to not force a specific directory and file structure for them > > > but let them choose how they lay things out. The answer I came up with > > > was "named loose coupling" but if there is a better solution, I'm > > > happy to apply it - just let me know. > > > > KM> Use case: one user doesn't use CommonJS and all of their mixins > > > are in the global namespace; another users uses CommonJS and layouts > > > out their mixin files in "vendor", and a different user puts other > > > people's mixins under "vendor/mixin" and their own mixins in a lib > > > folder: "lib/my_mixins" > > > > > *Mixin.initialize* > > > > > The object you "register" has properties like it's name (why should > > it > > > > have > a name, just use t... > > > KM> Naming conventions aside, there are few reasons for this > > > initialize and destroy being outside the object actually being mixed > > > in: > > > > 1) The library is designed to flatten an OO hierarchy using aspects > > > ("aspect" was another name I was considering for the library instead > > > of "mixin") and each aspect can be mixed in and out by the library > > > user when they need. Each time the mixin or mixout happens, the mixin > > > has an opportunity to initialize and cleanup. For example, in much of > > > my code, I use Backbone.Events and jQuery so I bind and unbind events > > > on the fly when mixin in and out. > > > > 2) I decoupled the initialize method and put it outside the object was > > > to avoid clobbering between mixins and to not have a fixed new/destroy > > > call order, but something on-the-fly and dynamic. > > > > KM> Use cases: in the subscriptions mixin, an Observor can dynamically > > > upgrade an object to have the Subscriber mixin so if their one is > > > destroyed, they automatically cleanup their links to one another. So a > > > Subscriber doesn't need to know beforehand that it will become a > > > subscriber and not all instances of the subscriber class need this > > > functionality and so the cleanup code is only the ones that actually > > > subscribed to something during their lifetime (not all instances of > > > the same "class"). > > > > > *Mixin.in* > > > > > Yes you need that, but why can't this just be `Mixin`. > > > > KM> I agree that it is not really an optimal decision for the most > > > used function in the library, but I made this decision mainly because > > > of API symmetry with Mixin.out but also to try to cleanly define > > > namespaces and have everything hang off of one root called Mixin. Of > > > course, the root could also be the mixin function itself. > > > > > Also why are you mixin it into instances of classes instead of the > > classes > > > > themself. That's jus... > > > > KM> Same answer as to > > ... > > read more » -- To view archived discussions from the original JSMentors Mailman list: http://www.mail-archive.com/[email protected]/ To search via a non-Google archive, visit here: http://www.mail-archive.com/[email protected]/ To unsubscribe from this group, send email to [email protected]
