stampit-org / stampit

OOP is better with stamps: Composable object factories.
https://stampit.js.org
MIT License
3.02k stars 102 forks source link

compose vs combine poll #46

Closed koresar closed 9 years ago

koresar commented 9 years ago

Guys, if you are reading this, please, click and vote: http://goo.gl/forms/O3yL2OYQsy We need at least 10 (but better be 20) votes.

Thank you

koresar commented 9 years ago

Cool! We are adding combine alias to the compose function.

stampit.compose()   4   27%
stampit.combine()   11  73%

results

ericelliott commented 9 years ago

You realize this means I have to post on social media to collect objections, right?

Down with .combine()!

;)

koresar commented 9 years ago

Right. :)

BTW, I used to compose music: http://promodj.com/ks So, I am a composer. I compose the final product/result. This means that stamp.create should have been named stamp.compose from the very beginning. Sometimes people combine music styles. A combined music style receives a new name occasionally. For example electro and house music styles resulted in electro house.

jrf0110 commented 9 years ago

I'm a little late to this game, but may I suggest the name .use(...)? Seems to be fairly idiomatic for this sort of thing.

var factory = stampit()
  .use( behaviorA )
  .use( behaviorB )
  .use( behaviorC );

JS folks would immediately see the similarities to other libs and might digest stampit's api more quickly

koresar commented 9 years ago

@jrf0110 good point. In this case the function should change this instead of creating and returning new stamp. Whereas current implementation returns new stamp on .compose() calls.

zebulonj commented 9 years ago

@koresar I have doubts about whether a call such as .use() should mutate the state of a stamp, due to the risk that such a call could later change the behavior of a previously shared stamp. By generating a new stamp with each such call, the library aligns more closely to the functional paradigm.

koresar commented 9 years ago

@zebulonj The stampit(m, s, e).compose(stamp2) call does not mutate state of the first stamp already. It's done.

All I wanted to say is that occasionally people would like to mutate the stamp. I already met two devs who did that on purpose.

zebulonj commented 9 years ago

Fair enough.

— Sent from my mobile device.

On Thu, Jan 22, 2015 at 6:02 PM, Vasyl Boroviak notifications@github.com wrote:

@zebulonj The stampit(m, s, e).compose(stamp2) call does not mutate state of the first stamp already. It's done.

All I wanted to say is that occasionally people would like to mutate the stamp. I already met two devs who did that on purpose.

Reply to this email directly or view it on GitHub: https://github.com/ericelliott/stampit/issues/46#issuecomment-71136106

jrf0110 commented 9 years ago

Oh and I was simply commenting on naming convention, not necessarily behavior :)

koresar commented 9 years ago

Latest poll results.

stampit.compose()   5   28%
stampit.combine()   13  72%
foxaal commented 9 years ago

If you start hunting around Wikipedia regarding the terms "compose" and "combine", you quickly come to the realization that "compose" makes more sense against the past. The term "aggregate" also come up, but "combine" seems to be nowhere. Is the objection to "compose" that it might get confused with matrix composition?

koresar commented 9 years ago

Current state of poll.

stampit.compose()   7   32%
stampit.combine()   15  68%

It's time to end the poll I reckon.

ericelliott commented 9 years ago

In this thread, .use() was suggested. I really like that, and no, I don't think we should modify the existing stamp, particularly if we spell out in the docs that stamps are immutable, and that you need an assignment when you call .use().

koresar commented 9 years ago

Probably .join()?

ericelliott commented 9 years ago

Why .join()?

koresar commented 9 years ago

See gitter. tijhaart January 16 2015

What about stampit.join? var stampD = stampit.join(stampA, stampB, stampC); Three letters less to write in comparison with compose. :laughing:

koresar commented 9 years ago

@foxaal suggested to take a look at Wikipedia.

Quoting Class-based_programming

In this model, objects are entities that combine state (i.e., data), behavior (i.e., procedures, or methods) and identity (unique existence among all other objects).

And quoting Class_(computer_programming)

Classes can be composed of other classes, thereby establishing a compositional relationship between the enclosing class and its embedded classes.

Clearly, it is wrong to rename or give any aliases to the existing compose() method. However, people tend to like combine more.

I'm confused. :)

foxaal commented 9 years ago

Here are some interesting references that seem relevant: http://en.wikipedia.org/wiki/Composition_over_inheritance http://en.wikipedia.org/wiki/Object_composition#Aggregation It is very important to get the naming to be consistent with the art. I'm not sure an opinion poll is the way to go. Better to see reasoned conversation leading to a higher ground for all -- best reasoning wins for everyone.

koresar commented 9 years ago

Eric, as long as we are trying to avoid classic OOP (see #44 you declined) let's also avoid classic OOP terminology.

The factory of factories is Eric's invention (or not, doesn't matter). The 'stamp' concept is something very new and very unique. Maybe we shouldn't reuse the classic terminology at all? Maybe we should invent our own terminology in order to emphasize that stamps are not alike classes?

So, my new proposal is to avoid both compose and combine, but use somehting like join instead.

Otherwise we might end up just like DB guys ended up with ACID and CAP. Where C is consistency but of the different kinds.

ericelliott commented 9 years ago

Eric, as long as we are trying to avoid classic OOP (see #44 you declined) let's also avoid classic OOP terminology.

The concept of object composition is not limited to classical OO, but this is a moot point, I think, since we've already agreed that it should be changed based on the poll results.

Maybe we should invent our own terminology in order to emphasize that stamps are not alike classes?

It's usually better to reuse terminology that is compatible so that users can reuse some of their prior knowledge. This is a basic principle of good API design.

So, my new proposal is to avoid both compose and combine, but use somehting like join instead.

I'm OK with this. So we should be asking, do we want to call it .use() or .join()? What are the pros and cons?

foxaal commented 9 years ago

"join" sounds like a relational database.

jrf0110 commented 9 years ago

.join()

Pros

Cons

.use()

Pros

Cons

koresar commented 9 years ago

I agree that both join and use sound far from the best.

jrf0110 commented 9 years ago

Not sure who your'e agreeing with, but if it's me, I'd like to clarify that I think .use() is the best method name ( I mean, I suggested it after all :D )

koresar commented 9 years ago

In many existing JS modules use is used to mutate the object. For example express.js. Whereas we agreed that stamps must be immutable.

zebulonj commented 9 years ago

My two cents:

  1. I don't have a horse in the alias race, but I strongly prefer compose. To me, it conveys the behavior... something new is created. I don't like combine. When I combine ingredients in the kitchen, I no longer have the ingredients.
  2. More important than the alias, I do strongly believe that stamps should be immutable once created.

Regarding the poll... where is this poll located? How has response been solicited? I've voiced my opinion here, but I've never participated in a poll. With such low response, I say its results are meaningless. I agree with the poster who said they'd prefer the result come of rational debate.

foxaal commented 9 years ago

Meteor uses "use" to throw packages into the same app: api.use("jquery") for example. But the old "compose" seems well-suited to what stampit is trying to accomplish -- and less nebulous.

ericelliott commented 9 years ago

.join()

Pros

Cons

.use()

Pros

Cons

.compose()

Pros

Cons

.combine()

Pros

Cons

koresar commented 9 years ago

It's time to end the debate. Let's leave the function naming as is. I.e. the only compose function should stay. No aliases.

Agree?

foxaal commented 9 years ago

I would agree. After all, "Composable object factories" is the original hook for stampit.

ericelliott commented 9 years ago

I'm OK with whatever the consensus is. =)

koresar commented 9 years ago

Ok. Closing this issue.

Personal thanks to @foxaal , @zebulonj , @jrf0110 for the useful input. Cheers guys!

dfkaye commented 9 years ago

@ericelliott Just back from the mountaintop and this is what it said:

Ignore the community ~ this is your project, not theirs ~ if they're unhappy they can fork it and rename at will

It was convincing at the time...

ericelliott commented 9 years ago

@dfkaye I'm definitely not afraid to say "no" if I feel strongly about something. See the closed issues for several examples. ;)

But I'm also open to input -- especially if it's input that might make the API easier to use.

dfkaye commented 9 years ago

@ericelliott OK ~ my vote is don't change the name ~ yet.

From what I've read, compose() acts as a mixin method for other stamps, treating them as traits, so mixin() might be more accurate.

combine() sounds like it does what methods() does but others may hear it as mixin().

use() is well-intentioned but its use in other libraries (notably express) is to insert capabilities into a kind of call stack which is not what's happening here.

Might re-consider the "issue" that there are multiple methods for decorating or cough extending a stamp ~ for example, does it really make sense to add a method or two to a stamp via methods() rather than as a trait that contains those methods via compose()?

Like the mountaintop said earlier, it's your baby ~ mountaintop may have had some red wine, though...

~ my two cents.

ericelliott commented 9 years ago

Might re-consider the "issue" that there are multiple methods for decorating or cough extending a stamp ~ for example, does it really make sense to add a method or two to a stamp via methods() rather than as a trait that contains those methods via compose()?

This question has come up before. I think it's important that we don't remove any of JavaScript's object-creation capabilities, and since there really are three different kinds of prototypal OO in JavaScript, and each one behaves in fundamentally different ways, I think it really is necessary to have three distinct ways to add behaviors to a stamp.

I've experimented with different APIs that have fewer methods in the past. Stampit was definitely an evolutionary step forward because of the flexibility it affords in that respect.

Thanks for the mountaintop feedback. I hope the wine was tasty! =)

backspaces commented 9 years ago

Sorry to be late to the show. "compose" is a term used in mathematics when one function wraps around another. It was used in the early days of "structured programming" (remember "goto considered harmful?) to prove that only a few primitive control constructs were needed in languages, and to prove goto was not needed.

Let f(x) = ... and g(y) = .... then f(g(x)) is the composition of f & g.

-- Owen

foxaal commented 9 years ago

Yes, and then the term found its way into computer science. http://en.wikipedia.org/wiki/Function_composition_%28computer_science%29 Function composition versus object composition: http://en.wikipedia.org/wiki/Object_composition

Stampit's compose function seems more like what is called "aggregation" in the link above on object composition...

ericelliott commented 9 years ago

As I mentioned before, Stampit does both function composition (using this as input and output instead of arguments and return values), and object composition (using object concatenation).

foxaal commented 9 years ago

@Owen -- whoops, sorry for my confusing comment -- so you are saying "composition" as a term in computer science entered in the days of moving beyond goto. @Eric -- got it. "Function composition" seems to exactly match the mathematical composition. "Object composition" maybe has some flavors ranging from concatenation at the most elemental, to something like lodash 3.0's merge function, at another level. Merge superimposes or projects one object onto another.