On Mon, Oct 17, 2011 at 10:04 AM, kmalakoff <xmann.i...@gmail.com> 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 <rayn...@gmail.com> 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" <xmann.i...@gmail.com> 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 <rayn...@gmail.com> 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 the difference between OO and dynamic aspect-
> > oriented programming and why there is an initialize/destroy not in the
> > actual object. You wouldt need to buy into the use cases for dynamic
> > aspect composition over OO hierachy where each instance may have
> > different compositions, nor the need to cleanup after each mixin.
> > KM> Use case: on-the-fly I adapt Knockout dependent observables
> > handlers based on the actual type of object being observed. To the
> > library user, they are just creating a handler, but behind the scenes
> > the handler is being adapted and cleaned up in a custom way with
> > different dynamic mixins based on what is actually being observed.
> >
> >
> >
> > > *Mixin.instanceData
> >
> > > *Why? Seriously, what's wrong with `this.fans = []` why must I store
> some
> > > data in your framework.
> >
> > KM> This was a decision to avoid property clashes among independent
> > mixin library writers. It quickly became apparent that if the system
> > is generalized and people independently write mixins, there will be an
> > increased probability that their properties will clash. Of course,
> > this doesn't *force* anyone to do anything, it just provides a
> > mechanism for avoiding property clashes if a mixin author believes
> > there is a high risk.
> >
> > Use case: you write a mixin for superstars and I write a mixin for
> > building ventilation management. We both want to use a property called
> > fans = []
> >
> > Thats verbose and frustrating.
> > KM> There is also a shorter version of the API Mixin.iD()
> >
> >
> >
> > > *Mixin.out*
> > > > Sorry, what. Why would you ever want to remove a mixin?
> >
> > KM> This function is the way you invoke destroy on a specific mixin
> > (eg. the symmetry between Mixin.in <-> Mixin.out). I could have called
> > it Mixin.destroy, but given that you and mixin and mixout, the naming
> > seemed more self-evident and internally consistent. Also, in my own
> > code, I use one of three life cycle models: "classes" that require no
> > cleanup, new/clone/destroy or new/retain/release so Mixin.out is
> > mainly useful for the last two, but you can cleanup a mixin manually
> > in any case by calling Mixin.out on any instances (for example, those
> > that don't follow one of the final two conventions).
> >
> > KM> Use case: you can mixin (Mixin.in) a specific set of user
> > interface elements to a view, bind their jQuery events, etc; then
> > remove and unbind them (Mixin.out) when the user chooses a sub menu,
> > and then mix them back in when they return (Mixin.in), and finally
> > when your view is destroyed at the end of its lifetime, clean up
> > (Mixin.out).
> >
> > > Now basically, You have a lot of over engineered useless methods on
> your >
> >
> > library. > > I'm sure...
> > KM> I'm not sure if my use cases have convinced you of the benefits of
> > dynamic aspect-oriented programming. I think your criticisms really
> > "hit many nails on the head" and properly raise the question of is
> > this library over-engineered or at the right level of complexity given
> > the problems it is designed to solve. I've been using it for 3 months
> > on my personal project so I don't have the perspective and am a little
> > enamored by the power and flexibility of the library, but (going back
> > to the nails) - I might be in a situation of "a man with a hammer sees
> > every problem as a nail"...many cases do not require this full
> > functionality, but since it is here, I'm using it generally for
> > classic Javascript mixins in addition to dynamic aspect-oriented
> > programming.
> >
> > > > Normally the place where you "convince" people these methods have a
> real
> > > purpose is in your (...
> >
> > KM> I think you can say "sparse", but "non-existant" is a little
> > strong ;-)   Personally, I prefer to look at tests for examples on how
> > to use a library so I really put my focus there and tried to draw the
> > user in the readme to use the tests as reference, but I have also
> > tried to provide various forms of documentation (1) the tests folder
> > has both unit and integration tests (2) there is the README itself (3)
> > there is a docs folder with the project (4) there is my blog:
> http://braincode.tumblr.com/and (5) I set up an examples project
> > (https://github.com/kmalakoff/examples-kmalakoff). What do people
> > prefer in terms of documentation anyways?
> >
> > I really appreciate this feedback. Hopefully, I have been able to
> > explain the goals of the library and the use cases it is trying to
> > address. Are you convinced? Either way, I would really like to
> > understand why or why not.
> >
> > Cheers,
> >
> > Kevin
> >
> > -- To view archived ...
> >
> > read more ยป
>
> --
> To view archived discussions from the original JSMentors Mailman list:
> http://www.mail-archive.com/jsmentors@jsmentors.com/
>
> To search via a non-Google archive, visit here:
> http://www.mail-archive.com/jsmentors@googlegroups.com/
>
> To unsubscribe from this group, send email to
> jsmentors+unsubscr...@googlegroups.com
>

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/jsmentors@jsmentors.com/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/jsmentors@googlegroups.com/

To unsubscribe from this group, send email to
jsmentors+unsubscr...@googlegroups.com

Reply via email to