Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > jQuery Overloading Strategy -- What Not To Do

Reply
Thread Tools

jQuery Overloading Strategy -- What Not To Do

 
 
Scott Sauyet
Guest
Posts: n/a
 
      09-17-2011
dhtml wrote:
> Scott Sauyet wrote:
>> dhtml wrote:
>> My main question was whether you feel that all forms of overloading
>> are problematic.

>
> Gotcha. No, I don't think overloading's always bad.


Okay, I'd love to hear other people's ideas as well on this.


>>> Well the jQuery function itself has more overloading, so complexities.

>
>> Right, we agree that the jQuery function is an atrocity of
>> overloading. *Still, is all overloading atrocious?

>
> I try to minimize complexity in methods. Conditionals and loops add
> complexity, too but sometimes it makes sense to use them.


The distinction I've been trying to make, though, is between
complexities within the implementation and complexities within the
interface presented. When there's a tradeoff to be made between the
two, I almost always will choose to keep the interface complexity
low. Of course it's better if neither is complex, but still there is
often a choice to be made between these.


>> * * Invoice.prototype.addLineItems = function(items) {
>> * * * var myItems = this.items;
>> * * * items = isArray(items) ? items : [items];
>> * * * each(items, function(item) {
>> * * * * myItems.push(item);
>> * * * });
>> * * };

>
>> This is a form of overloading. *The function can take a single
>> LineItem parameter or an array of LineItems. *To me, since the systems
>> that feeds me does not always distinguish between single items and
>> arrays of them, it's much cleaner to have the isArray check, and hence
>> the overloading, in this function. *

>
> That's what `Array.prototype.concat` does. So you can get rid of the
> entire function and just use `concat`. Like so:
>
> | myItems.concat(items);


I can't win.

I swear, if it weren't for a non-disclosure agreement, I'd just post
some actual code from my current project. pretend instead of

| myItems.push(item);


I wrote

| doSomethingDifficultThatDoesntHaveAnEquivalentNati veOneLiner(item)




>> I'm taking the Worse is Worse side in the classic Richard Gabriel
>> debate. *[1]

>
> Haha, yes - *I like that "less is more" stuff. And knowing how and
> when to say "no" when asked to provide spurious features.


That latter is something I struggle with far too much. It's hard when
those asking for the features are the ones signing the checks!

-- Scott
 
Reply With Quote
 
 
 
 
dhtml
Guest
Posts: n/a
 
      09-18-2011
On Sep 17, 1:45*pm, Scott Sauyet <(E-Mail Removed)> wrote:
> dhtml wrote:
> > Scott Sauyet wrote:
> >> dhtml wrote:
> >> My main question was whether you feel that all forms of overloading
> >> are problematic.

>
> > Gotcha. No, I don't think overloading's always bad.

>
> Okay, I'd love to hear other people's ideas as well on this.
>

Code examples would help.

> >>> Well the jQuery function itself has more overloading, so complexities..

>
> >> Right, we agree that the jQuery function is an atrocity of
> >> overloading. *Still, is all overloading atrocious?

>
> > I try to minimize complexity in methods. Conditionals and loops add
> > complexity, too but sometimes it makes sense to use them.

>
> The distinction I've been trying to make, though, is between
> complexities within the implementation and complexities within the
> interface presented. *When there's a tradeoff to be made between the
> two, I almost always will choose to keep the interface complexity
> low. *Of course it's better if neither is complex, but still there is
> often a choice to be made between these.
>

I disagree.

[...]

> > | myItems.concat(items);

>

Actually:
| this.items = myItems.concat(items);

> I can't win. *
>

Sorry that didn't help.

> I swear, if it weren't for a non-disclosure agreement, I'd just post
> some actual code from my current project. *pretend instead of
>
> | *myItems.push(item);
>
> I wrote
>
> | *doSomethingDifficultThatDoesntHaveAnEquivalentNati veOneLiner(item)
>

OK.

Remove the isArray check and use typeof items == "string". Simpler,
faster, safer. With mindset, you may find that you can remove more
dependencies than just isArray.
--
Garrett
 
Reply With Quote
 
 
 
 
dhtml
Guest
Posts: n/a
 
      09-18-2011
On Sep 15, 7:28*pm, Scott Sauyet <(E-Mail Removed)> wrote:
> dhtml wrote:

[...]
> > Now on that factory pattern, *I remember teh last time I showed you
> > that pattern that you thought it was too complicated. *[ ... ]

>
> Really, I don't remember that? *I know you discussed this pattern when
> we talked about APE, but I don't remember making this critique at all.
>

OK, sorry. Whatever the initial motivating factor was, I added
DelegateFactory.

Using a DelegateFactory based widget requires no boilerplate. The
tricky part is creating the DelegateFactory I'd like to simplify that
process.
--
Garrett
 
Reply With Quote
 
dhtml
Guest
Posts: n/a
 
      09-18-2011
On Sep 12, 4:08*pm, RobG <(E-Mail Removed)> wrote:
> On Sep 12, 9:16*pm, Scott Sauyet <(E-Mail Removed)> wrote:
>
> > dhtml wrote:
> > >> We've covered the problems with method overloading in numerous
> > >> threads).

>
> > > That is the subject at hand.

>
> > Do you think all overloading in JS is a problem? *I agree that many of
> > jQuery's overloadings are absurd, most prominently its main function
> > `jQuery`. *But I haven't found anything really wrong with the dual get/
> > set nature of a number of its functions. *While I don't object to
> > `getVal/setVal` a single function `val` also seems all right. *Do you
> > object?

>
> It becomes a problem when those writing the scripts don't understand
> the underlying behaviour of browsers. There are many questions on
> stackoverflow about fundamental browser behaviour, such as is it OK to
> just use selectElement.value rather than
> selectElement.options[selectElement.selectedIndex].value, that get
> responses like "just use jQuery: $(#selectElementId).val()".
>
> Which not only doesn't answer the OP's question, but actively
> discourages them from asking in the first place. A full explanation
> would include getting the value of a select element depending on the
> markup with links to relevant standards and the well known quirks in
> commonly used browsers. I would have thought that a full explanation
> is a better argument for using a library than a simplistic "just use
> it".
>
> Browsers are slowing converging on support for standards, and
> standards themselves are changing to provide more explicit support for
> what developers want to do (forget what users actually want, it's all
> about the developers, isn't it?). It will not be that long before
> behaviour will be sufficiently standard and basic functionality
> sufficiently complete that 3rd party libraries will not be required
> for most things. For example, script-based CSS selector engines are
> redundant in browsers with querySelector/All support, many transitions
> can now be performed purely in CSS, no doubt simple animations will
> follow.
>

Implementations need to be careful with implementing new features. It
may seem tempting to release a new feature (say something in HTML5)
but if that feature is buggy, it means that users have to deal with
those bugs and web developers have to do deeper capability checks. I'm
thinking now of ES5 features that got shipped buggy and HTML5 input
type=date, which is a mess in WebKit.

Spec developers need to keep degradation strategies in mind so that
when developers use the feature, they can provide a graceful
degradation path for implementations that lack that new feature.


On specs and getting back to Overloading, here is an example of
problematic overloading:
| For the DOM we have this idea of having a method that
| can conveniently create an element, set its attributes, event
| handlers, and child nodes. However, to keep the method
| convenient some of those need to become optional and therefore
| it requires some kind of overloading, which is
| where things become problematic.
| Maybe there is a better design, but so far we have something
| like this:
|
| create(name)
| create(name, attributes)
| create(name, children)
| create(name, attributes, children)
Here, `children` follows `attributes`.

| create(name, attributes, eventhandlers, children)
But now `children` follows `eventhandlers`.

|
| name is a string.
|
| attributes is an object.
|
| eventhandlers is an object.
|
| children is either a Node or string, or an array of Nodes and
strings.

The typechecking issue is not the problem; it is another step down the
wrong path. The wrong path is defining the "create" to be so
complicated that it defies descriptive name. The intent of "create" is
to do number of various things, using various parameters provided in
unmemorable and variant order.

http://lists.w3.org/Archives/Public/...lSep/0430.html
--
Garrett
 
Reply With Quote
 
Scott Sauyet
Guest
Posts: n/a
 
      09-19-2011
dhtml wrote:
> Scott Sauyet wrote:


>> The distinction I've been trying to make, though, is between
>> complexities within the implementation and complexities within the
>> interface presented. *When there's a tradeoff to be made between the
>> two, I almost always will choose to keep the interface complexity
>> low. *Of course it's better if neither is complex, but still there is
>> often a choice to be made between these.


> I disagree.


Do you disagree with my choice (to keep the complexity in the
implementation and not the interface)? Or with the idea that there is
sometimes a tradeoff to be made?

-- Scott
 
Reply With Quote
 
dhtml
Guest
Posts: n/a
 
      09-19-2011
On Sep 19, 5:12*am, Scott Sauyet <(E-Mail Removed)> wrote:
> dhtml wrote:
> > Scott Sauyet wrote:
> >> The distinction I've been trying to make, though, is between
> >> complexities within the implementation and complexities within the
> >> interface presented. *When there's a tradeoff to be made between the
> >> two, I almost always will choose to keep the interface complexity
> >> low. *Of course it's better if neither is complex, but still there is
> >> often a choice to be made between these.

> > I disagree.

>
> Do you disagree with my choice (to keep the complexity in the
> implementation and not the interface)? *Or with the idea that there is
> sometimes a tradeoff to be made?
>

I was disagreeing with the choices coming down to a tradeoff. Now
you're saying sometimes a tradeoff must be made; I agree with
sometimes, though perhaps not for the same situations you're thinking
of.

Your revamped item/items overloading added a tiny bit of complexity
with a ternary statement. That not seem like a problem to me.

Another example of overloading with host objects:
`jQuery.isPlainObject`, added long after reviews of jQuery problems
caused by their use of overloading. Somehow those reviews didn't stop
`isPlainObject` from being created and depended on to discriminate
between any type of value, including null, undefined, host object,
native object, both internally within the core of jQuery and
externally for the whole world.

That function fails for the reasons pointed out here long ago (see
"JQuery button problem" and "congrats to jQuery"). Essentially it
boils down to not defining the intention, being too generalized, then
imparting false expectations on what the browser should do.

With `isPlainObject` the false expectation is expecting a specific,
non-standard enumeration order. They expect that across all
implementations and all objects (including host objects) and then when
it doesn't do what they want, by filing that (yet another) false
expectation as a bug. Since enumeration order is nonstandard, of
course method can be expected to fail (and it does). (And anyone using
or considering jQuery should look carefully at those threads and also
http://bugs.jquery.com/ticket/9507).

We've covered cases of overloading that work and are justifiable. We
have also seen cases that can't work (by any reasonable expectations)
and don't work. We haven't yet debated cases where overloading can
work but adds more complexity than it is worth.

Complicated methods invite more bugs and are harder to debug, so why
add them?

Generally desirable: Clear implementation code. If that code uses
other defined objects then those objects should have clear interfaces
and well-defined methods. Closures can be used to hide details and
keep the interface simple.
--
Garrett
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Microsoft expanding it use of jQuery & involvement with jQuery lorlarz Javascript 6 03-25-2010 10:14 PM
jQuery Query about comparing jQuery references Aaron Gray Javascript 20 07-27-2008 01:53 PM
Overloading __init__ & Function overloading Iyer, Prasad C Python 3 09-30-2005 02:17 PM
Re: Overloading __init__ & Function overloading Steve Holden Python 0 09-30-2005 01:58 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 01:53 PM



Advertisments