Totally agree on the boolean traps. Methods like .clone() have the same issue. But migrating out to a new API and actually removing the old one would take at least two years at this point, given that we're going to slow the pace after 1.9/2.0 arrives.

So, write the new documentation for these methods. Name? Description? Is the old .stop() method deprecated? Scheduled to be removed in 2.1? Or staying forever to allow old code to work since there is nothing functionally broken about the old API?

There's an optional queue parameter at the FRONT, so it's already doing hockey. I doubt many people use that signature with custom queues (it was just added in 1.7) so perhaps we could drop that outright.

I don't think we need to drop it... it will just become one of the options. If the type param is an object re-assign the property values to the matching named args as needed and continue as done previously?

If we want to land anything for 1.9 it should happen before the next beta, which means, um, today.

I'd like to avoid going from a "boolean trap" to a "misspelled names in anonymous objects" trap.

If .stop({ clearQueue: true }) is the same as .clearQueue().stop() (it seems to be) we should just advise people to use it. That costs us zero bytes.

For .stop({ jumpToEnd: true }) perhaps we could introduce a new API method that makes it clear what is happening, something like .finish() that implies we're completing the animation steps immediately and not really .stop()ping it dead in its tracks.

All that needs to be done is adding .finish() and changing the docs to deprecate the boolean args and provide the recommended alternatives.

======

For .clone(withDataAndEvents, deepWithDataAndEvents) there needs to be a separate discussion. Even though it accepts two booleans I suspect damn near every call just uses 0 or 1 and I'd just prefer to leave it alone.

A boolean trap is simply "bad API design" and may lead to ambiguity as to purpose, but is straightforward in implementation. Magic strings make it harder to detect errors in userland, same goes for anonymous objects.

IMO, dmethvin's approach of creating new named API functions seems like the "right" "fix", in that it will error out on misspellings, and be clear in intention:
.clone(), .cloneWithData(), .cloneDeepWithData() Of course, this ruins the jQuery aesthetic of short function names, but I think it's a clarity win.

I'd say all boolean parameters should be considered for re-evaluation, but the one that comes to mind for me is outerWidth(true). The dimension functions should be called: contentBoxWidth(), paddingBoxWidth(), borderBoxWidth(), and marginBoxWidth()... no booleans.

@jaubourg, .clone(true) is the same as .clone(true, true) because the deep arg is the same as the first arg unless it's explicitly specified. So the only time it comes into play is if you explicitly say .clone(false, true) and I can't imagine a reason why anyone would need to specifically do that.

So although a .cloneWithDataAndEvents() might make sense, to capture the current behavior we'd need something like cloneWithDataAndEventsExceptForTheRoot() which again I think is so rare that we just act like it isn't there.

@jaubourg, .clone(true) is the same as .clone(true, true) because the deep arg is the same as the first arg unless it's explicitly specified. So the only time it comes into play is if you explicitly say .clone(false, true) and I can't imagine a reason why anyone would need to specifically do that.

It's even worse than what I (wrongly) assumed :/

So although a .cloneWithDataAndEvents() might make sense, to capture the current behavior we'd need something like cloneWithDataAndEventsExceptForTheRoot() which again I think is so rare that we just act like it isn't there.

+1

@mikesherov, seems to me you see traps everywhere... how about mispelled or badly named API functions? It's a trap!

There is no silver bullet. Booleans, strings, separate functions, it all boils down to the actual use case.

The boolean trap comes into play when you have several boolean arguments next to one another, not when you have a single boolean argument. With a single argument, the question is about ambiguity. This is the problem with the outerWidth method: true/false don't have any obvious meaning in this context.

Beside, that's why I actually love "magical" strings. They work perfectly to create $.Callbacks for instance as they should in any situation where you need to specify several "flags". I always find them to be very easy to read and make sense of given how inherently explicit they are.

My first thought on the .finish() method is that it would complete all animations, or at least have an option to complete all animations. It seems more useful to make sure all animations on the element are done before I move on to something else.

I was thinking we might add a .finishAll() method for that reason but then again if you wanted to finish *only* the current step you could .clearQueue().finish() right? So it seems the combo of those two APIs cover all the cases without need for a boolean option to .finish().

The interesting thing about that is that there is no easy way to do the equivalent of finishing all animation steps today and I've wanted it a couple of times. So I'd go for that. Other thoughts?