Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

jQuery Overloading Strategy -- What Not To Do

52 views
Skip to first unread message

dhtml

unread,
Sep 10, 2011, 4:28:05 PM9/10/11
to
Just took a peek at the jQuery forums. One of latest posts:

http://forum.jquery.com/topic/jquery-and-textnodes

| I've recently stumbled upon a weird issue - for a given ajax
| response I would create HTML element and insert it into DOM,
| however weirdly, my first textNode would be dropped. So I did
| the test on newer version of jQuery, and here's mine
| observation:

| [...]
| $(document).ready(function() {
| console.log($("A<div>B</div>C<div>D</div>E"));
| });

| Expected result:
|
| [<TextNode textContent="A">, div, <TextNode textContent="C">,
| div, <TextNode textContent="E">]
|
| Received result:
|
| [div, <TextNode textContent="C">, div]

The last text node is also dropped. This is the result of the method
overloading approach and the `quickExpr` regex. Both of which still
persist to this day.


// A simple way to check for HTML strings or ID strings
// (both of which we optimize for)
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,

The first part of that expression, `[^<]*` says "0 or more characters
that aren't `<`". So in essence, they deliberately drop text nodes.

We've covered the problems with method overloading in numerous
threads). All of the proposed solutions recommend strange hacks to get
around this design.

$("<jQfix/>"+response+"<jQfix/>").filter(":not(jQfix)");

Another comment tries to justify jQuery's behavior:

"... jQuery in my opinion was very smart by simply removing those in
such cases."

Another poster states:

| instead of doing:
|
| $(myhtml).appendTo(targetDiv);
|
|
| do this:
|
| $(targetDiv).append(myhtml);

And realizing that jQuery has two different ways of doing essentially
the same thing, and they they work differently. The second approach
goes through jQuery's long `domManip` function and then
`buildFragment`.

I've also told on many occasions that complicated methods lead to
trouble.

Function `buildFragment` goes through `clean`, which tries to either
parse the HTML or use innerHTML and then attempting to normalize some
of that, also calling `findInputs` which despite its name, returns
undefined. It begins like so:

| jQuery.buildFragment = function( args, nodes, scripts ) {
| var fragment, cacheable, cacheresults, doc;
|
|
| // nodes may contain either an explicit document object,
| // a jQuery collection or context object.
| // If nodes[0] contains a valid object to assign to doc

There is more method overloading in a newly introduced function.
Method `buildFragment` is new. So they're adding new functionality and
relying on the same old mistakes. How do you describe the psychology
that goes into that thinking? I'd call it insanity. And look just a
bit down in `buildFragment`, they realize getting bit by problems of
method overloading:

| // Ensure that an attr object doesn't incorrectly stand in as
| // a document object
| // Chrome and Firefox seem to allow this to occur and will
| // throw exception
| // Fixes #8950
| if ( !doc.createDocumentFragment ) {
| doc = document;
| }


What that comment means by "attr object" -- and it is horribly
misleading -- is that if an object is passed in to create attributes,
as in `jQuery('<input type="hidden" />', { 'class': 'test' });` that
the initial call to jQuery will end up calling `buildFragment` and
then passing it `{ 'class': 'test' }` as attributes and since
`{ 'class': 'test' }` doesn't have an owner document, the whole thing
falls apart. Now why would that happen, you might wonder. Sure, it is
complicated and if anyone got lost reading that, it is understandable;
the strategy and source code are overly complicated.

jQuery is presented as a script that will help simplify browser
scripting and smooth over the differences between browsers. Instead,
it adds a lot of unneeded complexity that has, does, and will continue
to cause problems. It is the tool of choice for the the uninformed.

Instead, if one learns javascript and browsers then one can reasonably
conclude that:
1) jQuery isn't needed
2) jQuery adds complexity that causes problems

Creating something whose complexity exceeds that of the original
problem will undoubtedly create more problems than is projected to
solve. And that is exactly what jQuery does. It is a shortcut to
failure.

If the goal is to build high-quality web apps, then instead of using
jQuery, learn the DOM, learn how browsers work, and learn to program
using concise, well-named methods.

Cornford on overloading:
http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/70c20c95a94127e8/def848b5f197f41cQ#msg_9a67fd2073ce031f

Myself on J Resig's "banning" comp.lang.javascript:
groups.google.com/group/comp.lang.javascript/msg/71999734c4116c52

COrnford, on attitude towards learning:
http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/6ea0ec35f290dd1b/ac8801bfec8e670f#msg_6ca46c969b8d899a

dhtml

unread,
Sep 11, 2011, 3:21:41 PM9/11/11
to
...they care about the capturing group, or `(<[\w\W]+>)` and that can
include internal text nodes, sandwiched between elements (or more like
what looks like elements to them); only text nodes between tags are
matched. That is:

var match = quickExpr.exec("start <b>1</b> middle <b>3</b> end");
match[1]; // <b>1</b> middle <b>3</b>

That capturing group matches neither "start " nor " end" but matches "
middle ". It also matches invalid markup, quickExpr.exec("<a></b>"));

I don't know what `quickExpr` means or what the author wanted it to
do. Not to detract from the original topic of overloading and
complicated methods, i.e.

> We've covered the problems with method overloading in numerous
> threads).
That is the subject at hand.
[...]
--
Garrett

Andrew Poulos

unread,
Sep 12, 2011, 5:04:02 AM9/12/11
to
What's the point of arguing against the use of jq? Its won! Its use is
widespread and when I warn web app developers against using it they ask
why (especially as it appears to "work" fine for them). I try to explain
but without them having sufficient js knowledge I can't get through.

The jq people will probably fix issues as they arise (assuming that they
understand them in the first place) and the jq community will rejoice at
having a new near-perfect release.

Andrew Poulos

Scott Sauyet

unread,
Sep 12, 2011, 7:16:50 AM9/12/11
to
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?

-- Scott

Scott Sauyet

unread,
Sep 12, 2011, 7:21:46 AM9/12/11
to
Scott Sauyet wrote:
> While I don't object to `getVal/setVal` a single function `val`
> also seems all right.

While I don't object to `getVal/setVal`, a single function, `val`,
also seems all right.

(Missing commas that are important for readability.)

-- Scott


RobG

unread,
Sep 12, 2011, 7:08:44 PM9/12/11
to
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.


--
Rob

dhtml

unread,
Sep 12, 2011, 9:17:53 PM9/12/11
to
On Sep 12, 4:16 am, Scott Sauyet <scott.sau...@gmail.com> 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?  

The problems with overloading come down to typechecking woes and added
complexity for what to do with the type found. Other twists include
optional arguments, and even optional middle arguments, which requires
reassigning and shifting things over.

JQeruy adds an additional twist by examining the contents of strings
passed. IF the argument is a string, if that string looks like
something that can be matched by a very naive HTML regex, then try to
build some HTML instead of selecting nodes. I.e.

| if ( selector.charAt(0) === "<"

For me, I'd rather see a function like `buildHTML`. THen again, I'm
wary of a function that takes string, and then uses innerHTML, regex,
and cloneNode to build HTML. I can't justify doing that in a general
sense.

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?
>
Methods that do more than one thing are more complicated.

A get/set method, as you've described, does one of two things: 1)
either return something or 2) have side effects are inherently more
complex than methods that do one thing.

The SOLID principles, and I'm thinking of SRP now, can keep code
clean, simple, easy to understand, predictable. SRP is a good
guideline for designing methods, generally. For methods that perform
operations that are is tricky, the trickiness more apparent and not
obfuscated by API design decisions.

Depends why and how you do it.
--
Garrett

dhtml

unread,
Sep 13, 2011, 12:24:39 AM9/13/11
to
On Sep 12, 6:17 pm, dhtml <dhtmlkitc...@gmail.com> wrote:
> On Sep 12, 4:16 am, Scott Sauyet <scott.sau...@gmail.com> wrote:
>
> > dhtml wrote:

While I was writing alone, someone burst in and would not stop talking
to me.

Probably should not have posted then. Corrections below.

[...]
> A get/set method, as you've described, does one of two things: 1)
> either return something or 2) have side effects.

[inserted fullstop]

That's -->
inherently more
> complex than methods that do one thing.
>
> The SOLID principles, and I'm thinking of SRP now, can keep code
> clean, simple, easy to understand, predictable.  SRP is a good
> guideline for designing methods, generally. For methods that perform
> operations that are is

-> "are", not "are is"

Scott Sauyet

unread,
Sep 13, 2011, 7:31:40 AM9/13/11
to
dhtml wrote:
> Scott Sauyet wrote:

>> Do you think all overloading in JS is a problem?  
>
> The problems with overloading come down to typechecking woes and added
> complexity for what to do with the type found. Other twists include
> optional arguments, and even optional middle arguments, which requires
> reassigning and shifting things over.

The implementation of overloaded methods is of course problematic, and
the only justification I can see for it is in *perceived* API
simplicity. Of course an API that has

val(/*optional*/ any) /* if `any` supplied, sets the value to
`any`, otherwise returns current value.

is not actually any simpler than one that has

getVal() /* @returns Any. Gets the current value. */
setVal(any) /* @return undefined. Sets the current value to
`any`. */

In fact, it'ss arguably more complicated. It's certainly harder to
document well. But there is still some persistent feeling that the
API with the single function is cleaner.

My question is whether this vague and fuzzy feeling that the single-
functioned API is simpler could ever be enough of a reason for
complicating the implementation. I'm entirely mixed on this. I'm all
for complicating implementation to simplify an API. But what about
when the API isn't *really* any simpler?


> [ ... ]
>> While I don't object to `getVal/setVal` a single function `val`
>> also seems all right.  Do you object?
>
> Methods that do more than one thing are more complicated.

Yes, but so are objects that do more than one thing. The question is
whether that complication is ever justified.



> A get/set method, as you've described, does one of two things: 1)
> either return something or 2) have side effects are inherently more
> complex than methods that do one thing.
>
> The SOLID principles, and I'm thinking of SRP now, can keep code
> clean, simple, easy to understand, predictable.  SRP is a good
> guideline for designing methods, generally.

SRP is a guideline for designing class of objects, not for defining
libraries. Of course libraries can consist of classes that follow all
of the SOLID principles. And there could be straightforward
extensions of the SOLID principles to library design, but I tend not
to use JS in a particularly object-oriented manner, so such
considerations are often of less importance to me.


> For methods that perform
> operations that are is tricky, the trickiness more apparent and not
> obfuscated by API design decisions.

I almost always prefer a clean API to a clean implementation.


> Depends why and how you do it.

As always! :-)

-- Scott

dhtml

unread,
Sep 15, 2011, 2:10:07 PM9/15/11
to
On Sep 13, 4:31 am, Scott Sauyet <scott.sau...@gmail.com> wrote:
> dhtml wrote:
> > Scott Sauyet wrote:
> >> Do you think all overloading in JS is a problem?  
>
[...]
>
> The implementation of overloaded methods is of course problematic, and
> the only justification I can see for it is in *perceived* API
> simplicity.  Of course an API that has
>
>     val(/*optional*/ any) /* if `any` supplied, sets the value to
> `any`, otherwise returns current value.
>
> is not actually any simpler than one that has
>
>     getVal() /* @returns Any.  Gets the current value. */
>     setVal(any) /* @return undefined.  Sets the current value to
> `any`. */
>

Name 'getVal' is a contrived plastic example. Methods that are well-
named, simple, self-documenting. Obviates the need for documentation.

> In fact, it'ss arguably more complicated.  It's certainly harder to
> document well.  But there is still some persistent feeling that the
> API with the single function is cleaner.
>
Whose feeling? Can we stick to pros/cons?

> My question is whether this vague and fuzzy feeling that the single-
> functioned API is simpler could ever be enough of a reason for
> complicating the implementation.  I'm entirely mixed on this.  I'm all
> for complicating implementation to simplify an API.  But

But an API to do what?

what about
> when the API isn't *really* any simpler?
>
> > [ ... ]
> >> While I don't object to `getVal/setVal` a single function `val`
> >> also seems all right.  Do you object?
>
> > Methods that do more than one thing are more complicated.
>
> Yes, but so are objects that do more than one thing.  The question is
> whether that complication is ever justified.
>
Objects have more than one behavior. An object is a set of (hopefully
well-named) properties and/or methods. Methods shouldn't.

Take a panel, for example, might have "show" ahdn "hide". Now you
could potentially make a method that does both:

e.g. setDisplay(bShow);

But what for? That just means that the API needs documentation,
whereas someting like "show" -- do you get what that should do?

With method overloading, as seen in jQuery, the approach is to try to
figure out how to dynamically dispatch the desired behavior, and then
do that in a dynamic environment (browser) where anything is expected
to be passed in. It's the "setDisplay" on a grand scale, with host
object, determination of string contents to dispatch behavior, all
kinda thing.

That's a terrible strategy for developing methods. Methods should
know what type of parameter is going to being passed in. But
especially in javascript where you have host objects of multiple
environments, where typeof obj might be "object" in one env,
"function" in another, "string" in yet another. And I can think of a
couple of such methods that fit that criteria.

Javascript methods that allow anything and everything to be passed in
and then expect to be able to make determinations of what type it is,
e.g. typeof it == 'object' fail on those expectations. Who remembers
here when jQuery developers had problems with `typeof
document.images`? Or the fighting of Safari childNodes crashes, "What
is a Software Engineer"

https://groups.google.com/group/comp.lang.javascript/msg/5392683d50886d0f?hl=en

> > A get/set method, as you've described, does one of two things: 1)
> > either return something or 2) have side effects are inherently more
> > complex than methods that do one thing.
>
> > The SOLID principles, and I'm thinking of SRP now, can keep code
> > clean, simple, easy to understand, predictable.  SRP is a good
> > guideline for designing methods, generally.
>
> SRP is a guideline for designing class of objects, not for defining
> libraries.  
SRP is a design principle. It is for designing libraries. I suggest
you do a little more research.

Of course libraries can consist of classes that follow all
> of the SOLID principles.  And there could be straightforward
> extensions of the SOLID principles to library design, but I tend not
> to use JS in a particularly object-oriented manner, so such
> considerations are often of less importance to me.
>
Methods that do multiple things are inherently more complex and so
harder to debug. And when the set of things being done is so
complicated that it can't be explained, that's way off the deep end.
That's the jQuery function.

> >                                              For methods that perform
> > operations that are is tricky, the trickiness more apparent and not
> > obfuscated by API design decisions.
>
> I almost always prefer a clean API to a clean implementation.

You can't have both?
--
Garrett

Scott Sauyet

unread,
Sep 15, 2011, 4:23:13 PM9/15/11
to
dhtml wrote:
> Scott Sauyet wrote:
>> dhtml wrote:
>>> Scott Sauyet wrote:
>>>> Do you think all overloading in JS is a problem?  
> [...]
>
>> The implementation of overloaded methods is of course problematic, and
>> the only justification I can see for it is in *perceived* API
>> simplicity.  
>> [ ... ill-considered 'getVal'/'setVal' example removed ... ]
>
> Name 'getVal' is a contrived plastic example. Methods that are well-
> named, simple, self-documenting. Obviates the need for documentation.

Sorry, I wasn't thinking about it that way. I was thinking about
jQuery's "val" function which is both an accessor and mutator for it's
objects wrapping INPUT and SELECT elements.

A cleaner example would be, say, `height`.

It's certainly a debatable point as to whether the `setHeight`/
`getHeight` pair is more complicated than a single `height` function,
but if nothing else, the latter has fewer symbols to remember.
Perhaps it's slightly easier to learn with the `set/get` versions, but
it's no easier to use, and the complexity of implementation is not
significantly different.

So my question was really whether you objected to that sort of
overloading. Or perhaps even if you object as strenuously to that
sort of overloading as you do to, say, the overloading of the main
jQuery function.


>> In fact, it'ss arguably more complicated.  It's certainly harder to
>> document well.  But there is still some persistent feeling that the
>> API with the single function is cleaner.
>
> Whose feeling? Can we stick to pros/cons?

Mine. Why should I care about yours? :-)

I really am talking about pros and cons. In one very naive way, it's
almost tautological that an API with a single function is simpler than
one with two functions. So there is at least one pro to an API that
can be used this way:

var r = new Rectangle(20, 10);
alert(r.area()); // 200
r.height(15);
alert(r.area()); // 300
alert(r.height()) // 15

over one that works like this:

var r = new Rectangle(20, 10);
alert(r.calculateArea()); // 200
r.setHeight(15);
alert(r.calculateArea()); // 300
alert(r.getHeight()) // 15

Do you object to the single-function API?


>> My question is whether this vague and fuzzy feeling that the single-
>> functioned API is simpler could ever be enough of a reason for
>> complicating the implementation.  I'm entirely mixed on this.  I'm all
>> for complicating implementation to simplify an API.  But
>
> But an API to do what?

Whatever. If I want to use an API to handle a certain facet of my
system, I would rather have a simple API. If I want to read a file
into a String using Ruby, it's as simple as

text = File.read(file_name)

In Java, I'd need to use about ten lines of code, invoking
FileInputStreams, BufferedReaders, IOExceptions, StringBuilders, and
so on. Ruby clearly has a simpler API for this.

If I'm using an external API (even one I've written myself) in my
code, I want the code using it to be as clear as possible, and that at
the expense of how easy the API is to write.


>>> Methods that do more than one thing are more complicated.
>
>> Yes, but so are objects that do more than one thing.  The question is
>> whether that complication is ever justified.
>
> Objects have more than one behavior. An object is a set of (hopefully
> well-named) properties and/or methods. Methods shouldn't.

That's just restating your objection. Do you think overloading is
never justified?


> Take a panel, for example, might have "show" ahdn "hide". Now you
> could potentially make a method that does both:
>
> e.g. setDisplay(bShow);
>
> But what for? That just means that the API needs documentation,
> whereas someting like "show" -- do you get what that should do?

Can `show` be animated? Do you need a parameter that describes what
animation to use? How about the duration? And if it's animated,
could I also supply a callback to run when it's done? If we have an
API that uses `show` to handle a plain change to visibility, a simply
animated one, or one that's animated with a followup callback, is this
somehow more complicated than an API like this?:

show()
animatedShow("fadeIn", 600)
animatedShowWithCallback("slideUp", 400, function()
{doSomething();})

Yes, the implementation of a single "show" function to handle these
possibilities is more difficult than any individual one of the above
would be, but the total code is not likely to be much harder. This
extended API is clearly more difficult to remember. I would argue
that it's more difficult to use as well.


> With method overloading, as seen in jQuery, the approach is to try to
> figure out how to dynamically dispatch the desired behavior, and then
> do that in a dynamic environment (browser) where anything is expected
> to be passed in. It's the "setDisplay" on a grand scale, with host
> object, determination of string contents to dispatch behavior, all
> kinda thing. [ ... ]

Yes, I really don't like that style. I think a great deal of jQuery's
overloading is horrible. I just don't agree that all overloading is
bad.


> That's a terrible strategy for developing methods.  Methods should
> know what type of parameter is going to being passed in. [ ... ]

I have another case that I'm using a lot in my current project.

var handleXYZ = function(param) {
each(makeArray(param), function(item) {
doSomething(item);
});
};

I receive (from an external source) references that might be single
elements of, say, Strings or might be an array of Strings. I write a
single function to handle either case and use a `makeArray` function
to handle them uniformly in my code. Would you suggest that I should
have a separate `handleMultipleXYZs` function? Because the original
source of these things is outside my control, using such would
necessitate sprinkling `isArray` checks over all the code that calls
these functions rather than centralizing it in the one function. Do
you really object to that sort of overloading?


> https://groups.google.com/group/comp.lang.javascript/msg/5392683d5088...

One of the very first threads I read here! :-)


>>> A get/set method, as you've described, does one of two things: 1)
>>> either return something or 2) have side effects are inherently more
>>> complex than methods that do one thing.
>
>>> The SOLID principles, and I'm thinking of SRP now, can keep code
>>> clean, simple, easy to understand, predictable.  SRP is a good
>>> guideline for designing methods, generally.
>
>> SRP is a guideline for designing class of objects, not for defining
>> libraries.  
>
> SRP is a design principle. It is for designing libraries. I suggest
> you do a little more research.

Saying that an object should have a single responsibility does not
carry over to the design of a library. I don't think it's easy to
assign a single responsibility to C++'s Standard Template Library;
there's just too much going on there. But the point is that a library
is not an object. Yes, jQuery works with it's own objects which are
essentially wrapped sets of DOM elements, but in the end, it's mostly
a collection of functions that can run against such a wrapped
collection. There would be little fundamental difference if these
functions were stand-alone utilities that ran against arrays of DOM
elements. In essence, don't try to think of the jQuery API as you
would an object in an OO system; it's simply not that sort of
interface.

And a collection of functions does not necessarily have a single
responsibility.


>> [ ... ]
> Methods that do multiple things are inherently more complex and so
> harder to debug.

But it's hard to draw the line between doing multiple things and doing
one thing with multiple variations.


> And when the set of things being done is so
> complicated that it can't be explained, that's way off the deep end.
> That's the jQuery function. [ ... ]

ACK.


>> I almost always prefer a clean API to a clean implementation.
>
> You can't have both?

When you can, of course you should. But the two are often at odds. I
will usually come down on the side of keeping the API cleaner and
letting the implementation get uglier when necessary. Would you
prefer the reverse?

-- Scott

dhtml

unread,
Sep 15, 2011, 6:34:11 PM9/15/11
to
On Sep 15, 1:23 pm, Scott Sauyet <scott.sau...@gmail.com> wrote:
> dhtml  wrote:
> > Scott Sauyet wrote:
> >> dhtml wrote:
> >>> Scott Sauyet wrote:
> >>>> Do you think all overloading in JS is a problem?  
> > [...]
>
> >> The implementation of overloaded methods is of course problematic, and
> >> the only justification I can see for it is in *perceived* API
> >> simplicity.  
> >> [ ... ill-considered 'getVal'/'setVal' example removed ... ]
>
> > Name 'getVal' is a contrived plastic example. Methods that are well-
> > named, simple, self-documenting. Obviates the need for documentation.
>
> Sorry, I wasn't thinking about it that way.  I was thinking about
> jQuery's "val" function which is both an accessor and mutator for it's
> objects wrapping INPUT and SELECT elements.
>

Oh, duh. (what's the emoticon for "foot in mouth"?)

> A cleaner example would be, say, `height`.
>
> It's certainly a debatable point as to whether the `setHeight`/
> `getHeight` pair is more complicated than a single `height` function,
> but if nothing else, the latter has fewer symbols to remember.
> Perhaps it's slightly easier to learn with the `set/get` versions, but
> it's no easier to use, and the complexity of implementation is not
> significantly different.

OK, though I'm not sure if I need both of those methods.

>
> So my question was really whether you objected to that sort of
> overloading.  Or perhaps even if you object as strenuously to that
> sort of overloading as you do to, say, the overloading of the main
> jQuery function.
>
Well the jQuery function itself has more overloading, so complexities.

[...]
> I really am talking about pros and cons.  In one very naive way, it's
> almost tautological that an API with a single function is simpler than
> one with two functions.  So there is at least one pro to an API that
> can be used this way:
>
>     var r = new Rectangle(20, 10);
>     alert(r.area()); // 200
>     r.height(15);
>     alert(r.area()); // 300
>     alert(r.height()) // 15
>
> over one that works like this:
>
>     var r = new Rectangle(20, 10);
>     alert(r.calculateArea()); // 200
>     r.setHeight(15);
>     alert(r.calculateArea()); // 300
>     alert(r.getHeight()) // 15
>
> Do you object to the single-function API?
>
Depends on the usage. It might make sense to have r.getDimensions
return an object {x: n, y: n}.

> >> My question is whether this vague and fuzzy feeling that the single-
> >> functioned API is simpler could ever be enough of a reason for
> >> complicating the implementation.  I'm entirely mixed on this.  I'm all
> >> for complicating implementation to simplify an API.  But
>
> > But an API to do what?
>
> Whatever.  If I want to use an API to handle a certain facet of my
> system, I would rather have a simple API.  If I want to read a file
> into a String using Ruby, it's as simple as
>
>     text = File.read(file_name)

Synchronous file reads are problematic.

[...]
Sorry, that was a bit abrasive, but point being, the principle can be
applied not just to Objects, but to methods.

> Saying that an object should have a single responsibility does not
> carry over to the design of a library.  I don't think it's easy to
> assign a single responsibility to C++'s Standard Template Library;
> there's just too much going on there.  But the point is that a library
> is not an object.  Yes, jQuery works with it's own objects which are
> essentially wrapped sets of DOM elements, but in the end, it's mostly
> a collection of functions that can run against such a wrapped
> collection.  There would be little fundamental difference if these
> functions were stand-alone utilities that ran against arrays of DOM
> elements.  In essence, don't try to think of the jQuery API as you
> would an object in an OO system; it's simply not that sort of
> interface.
>
Well, it sort of is because when a query is made, there is a factory
to create a jQuery object (which is a collection), then methods to
operate on that object.

> And a collection of functions does not necessarily have a single
> responsibility.

I'm thinking of the type of function that does one thing vs the type
of function that does many things. The function that does one thing is
going to be a lot easier to debug.

>
> >> [ ... ]
> > Methods that do multiple things are inherently more complex and so
> > harder to debug.
>
> But it's hard to draw the line between doing multiple things and doing
> one thing with multiple variations.

Sometimes it can be. like boolean parameters, for example (which
again, I'm not a fan of). For example `useCapture` stinks. It's a
boolean parameter for a capturing phase. Listening to either phase is
mutually exclusive to its counterpart.

I don't see the SRP as a strict "rule" but as a useful guideline.

[...]

>
> > You can't have both?
>
> When you can, of course you should.  But the two are often at odds.  I
> will usually come down on the side of keeping the API cleaner and
> letting the implementation get uglier when necessary.  Would you
> prefer the reverse?
>
I disagree with the premise; I think it's a false dichotomy.

I also think that in javascript for the web, most times what can be
done with events, closures, object literals, you won't be using all of
the traditional OOP getters and setters -- those just add cruft.

I'd like to get and look at some actual code other than jQuery.

Here is an example of some code that I wrote. I see so many places in
my own code where it the code is too complicated and the interface is
too clunky. No bragging here, just some code that I'm fairly familiar
with.

https://github.com/GarrettS/ape-javascript-library/blob/master/src/widget/scroller/Scroller.js

The public interface is:
APE.widget.Scroller.getById(id, timeDuration, vertical);

`id` is the id of the widget.
`timeDuration` is optional and has a default.
`vertical` is a boolean argument. Again, I don't like boolean
arguments because they're usually poor descriptors. But that's what I
wrote. If I were to change it, I'd make the script figure out if it is
a vertical scroller by looking at the element's className.

Now on that factory pattern, I remember teh last time I showed you
that pattern that you thought it was too complicated. So what I did
from that is to make it so that the widget creator can create a
factory that delegates to create the object on an event, like "focus".

Using a Delegate Factory would not be the first thing I would want to
fix in the Scroller code but it is a possibility.

If changed to use DelegateFactory, including the script in a document
would cause a delegate "focus" listener to be added. The callback for
that examines target of "focus" events at the document level. If the
target looks like a scroller "prev"/"next" button, it initializes a
Scroller widget. That way, the implementation code is just the HTML
and CSS and the SCRIPT element. There is no "setVertical" or anything
like that at all.

I hope you don't find this to be a red herring, I just don't see the
get/set paradigm as being a major issue in reducing method count.
--
Garrett

dhtml

unread,
Sep 15, 2011, 6:45:36 PM9/15/11
to
Can we use CSS transitions instead? I can do it in JS but transitions
would be a lot simpler.

> Yes, the implementation of a single "show" function to handle these
> possibilities is more difficult than any individual one of the above
> would be, but the total code is not likely to be much harder.  This
> extended API is clearly more difficult to remember.  I would argue
> that it's more difficult to use as well.
>
The extended API is harder to remember, there, but i'd rather not
extend it like that. The `onshow` callback can be generic and then up
to the client of the API to shadow/replace it.

[...]

>
> I have another case that I'm using a lot in my current project.
>
>     var handleXYZ = function(param) {
>       each(makeArray(param), function(item) {
>         doSomething(item);
>       });
>     };
>
> I receive (from an external source) references that might be single
> elements of, say, Strings or might be an array of Strings.  I write a
> single function to handle either case and use a `makeArray` function
> to handle them uniformly in my code.  Would you suggest that I should

If you typecheck there...

var coll = typeof param == "string" ?
param.split() : param.slice();

You can do that but it's a little ugly. Not horrible, but better
without that.

> have a separate `handleMultipleXYZs` function?  Because the original
> source of these things is outside my control, using such would
> necessitate sprinkling `isArray` checks over all the code that calls
> these functions rather than centralizing it in the one function.  Do
> you really object to that sort of overloading?
>
I do, but not so strongly. I don't like seeing that conditional in the
beginning because it is ugly. But it isn't that hard to figure out.

> >https://groups.google.com/group/comp.lang.javascript/msg/5392683d5088...
>
The link doesn't work.
[...]
--
Garrett

Scott Sauyet

unread,
Sep 15, 2011, 10:28:09 PM9/15/11
to
dhtml wrote:
> Scott Sauyet wrote:
>> dhtml  wrote:
>>> Scott Sauyet wrote:
>>>> dhtml wrote:
>>>>> Scott Sauyet wrote:
>>>>>> Do you think all overloading in JS is a problem?  
>>> [...]
>> It's certainly a debatable point as to whether the `setHeight`/
>> `getHeight` pair is more complicated than a single `height` function,
>> but if nothing else, the latter has fewer symbols to remember.
>> [ ... ]
>
> OK, though I'm not sure if I need both of those methods.

No, and there's plenty of reason for not bothering with getters or
setters in most cases when working in JS. I brought them up because I
knew they were another form of overloading that jQuery practices.

My main question was whether you feel that all forms of overloading
are problematic. And I persist with it because it's been a sticky
question for me in my own API design. I'm pulled in both directions.
I seem to have mostly settled on accepting overloading on a single
parameter, either allowing it to have several different sorts of
related values, or allowing it to be optional. I avoid the style that
jQuery uses of using many parameters and allowing some in the middle
to be optional, shifting the others around to assign everything
correctly. I'm curious as to whether others would still find this
style problematic.


>> So my question was really whether you objected to that sort of
>> overloading.  Or perhaps even if you object as strenuously to that
>> sort of overloading as you do to, say, the overloading of the main
>> jQuery function.
>
> 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?



>> And a collection of functions does not necessarily have a single
>> responsibility.
>
> I'm thinking of the type of function that does one thing vs the type
> of function that does many things. The function that does one thing is
> going to be a lot easier to debug.

Yes, and there are other good reasons to prefer it. But sometimes
there are competing forces suggesting that you might be better putting
some complexity in the method to make calls easier. My earlier
example was somewhat misunderstood, so I'll try to be a little more
explicit:

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. Then I don't need to perform that
check in every place in the source code where I want to call
addLineItems. The non-overloaded version of the API would have both
`addLineItem` and `addLineItems` (or `addMultipleLineItems` if the 's'
is too subtle a difference.) It would sprinkle the `isArray` check
through many more parts of my code, a clear violation of the DRY
principle.



> [...]
>>> You can't have both?
>
>> When you can, of course you should.  But the two are often at odds.  I
>> will usually come down on the side of keeping the API cleaner and
>> letting the implementation get uglier when necessary.  Would you
>> prefer the reverse?
>
> I disagree with the premise; I think it's a false dichotomy.

I'm not trying to claim that you can never have both. But there are
times when the cleanest possible API requires an implementation that
is not as clean as would be possible if you allowed some API stains.
I'm taking the Worse is Worse side in the classic Richard Gabriel
debate. [1]


> I'd like to get and look at some actual code other than jQuery.

Wouldn't we all? :-)


> Here is an example of some code that I wrote. I see so many places in
> my own code where it the code is too complicated and the interface is
> too clunky. No bragging here, just some code that I'm fairly familiar
> with.
>
> https://github.com/GarrettS/ape-javascript-library/blob/master/src/widget/scroller/Scroller.js
>
> The public interface is:
> APE.widget.Scroller.getById(id, timeDuration, vertical);
>
> `id` is the id of the widget.
> `timeDuration` is optional and has a default.
> `vertical` is a boolean argument. Again, I don't like boolean
> arguments because they're usually poor descriptors. But that's what I
> wrote. If I were to change it, I'd make the script figure out if it is
> a vertical scroller by looking at the element's className.
>
> 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.

> [...discussion removed...] There is no "setVertical" or anything
> like that at all.
>
> I hope you don't find this to be a red herring, I just don't see the
> get/set paradigm as being a major issue in reducing method count.


I don't find it all that important either. It was just the first
example that came to mind of a tolerable overloading.

-- Scott

[1] http://en.wikipedia.org/wiki/Worse_is_better

Scott Sauyet

unread,
Sep 15, 2011, 10:30:21 PM9/15/11
to
Scott Sauyet rote:
> 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?  [ ... ]

Let's try that punctuation again:

Really? I don't remember that. [ ... ]


:-)

-- Scott

Gregor Kofler

unread,
Sep 16, 2011, 7:15:39 AM9/16/11
to
Am 2011-09-15 22:23, Scott Sauyet meinte:

> I really am talking about pros and cons. In one very naive way, it's
> almost tautological that an API with a single function is simpler than
> one with two functions. So there is at least one pro to an API that
> can be used this way:
>
> var r = new Rectangle(20, 10);
> alert(r.area()); // 200
> r.height(15);
> alert(r.area()); // 300
> alert(r.height()) // 15
>
> over one that works like this:
>
> var r = new Rectangle(20, 10);
> alert(r.calculateArea()); // 200
> r.setHeight(15);
> alert(r.calculateArea()); // 300
> alert(r.getHeight()) // 15
>
> Do you object to the single-function API?

Sure. What does Rectangle.height() without argument? Just return the
current height? Set some - perhaps elsewhere defined - default value?
The single-function API needs documentation, the latter one not.

OTOH I can't see - apart from saving 3 characters - any benefit from
using the single-function API.

Gregor


--
http://vxweb.net

Gregor Kofler

unread,
Sep 16, 2011, 7:47:51 AM9/16/11
to
Am 2011-09-16 13:15, Gregor Kofler meinte:
In addition I (and I suppose most other developers) prefer verbs (or
verb-like structures) as names for methods and nouns for properties.

Scott Sauyet

unread,
Sep 16, 2011, 7:49:28 AM9/16/11
to
Gregor Kofler wrote:
> Scott Sauyet meinte:
[ ...Regarding the difference between a single `height` function that
serves as both an accessor and a mutator and a more explicit pair of
functions `setHeight`/`getHeight`. ... ]

>> Do you object to the single-function API?
>
> Sure. What does Rectangle.height() without argument? Just return the
> current height? Set some - perhaps elsewhere defined - default value?
> The single-function API needs documentation, the latter one not.
>
> OTOH I can't see - apart from saving 3 characters - any benefit from
> using the single-function API.

I'm really not trying to defend that sort of API; I personally don't
write them that way. I was just pointing them out as a type of
overloading that's less noxious than many other types. I also
presented a type of overloading that I actually do use, one where a
parameter might represent either a single item or a collection of
them.

I was trying to gauge whether it's any overloading at all that raises
peoples ire or if it's only the kind that leads to twisted, confused
parameter-handling logic.

-- Scott

Gregor Kofler

unread,
Sep 16, 2011, 8:20:17 AM9/16/11
to
Am 2011-09-16 13:49, Scott Sauyet meinte:
> Gregor Kofler wrote:
>> Scott Sauyet meinte:
> [ ...Regarding the difference between a single `height` function that
> serves as both an accessor and a mutator and a more explicit pair of
> functions `setHeight`/`getHeight`. ... ]
>
>>> Do you object to the single-function API?
>>
>> Sure. What does Rectangle.height() without argument? Just return the
>> current height? Set some - perhaps elsewhere defined - default value?
>> The single-function API needs documentation, the latter one not.
>>
>> OTOH I can't see - apart from saving 3 characters - any benefit from
>> using the single-function API.
>
> I'm really not trying to defend that sort of API; I personally don't
> write them that way. I was just pointing them out as a type of
> overloading that's less noxious than many other types. I also
> presented a type of overloading that I actually do use, one where a
> parameter might represent either a single item or a collection of
> them.

I use this kind of overloading, too. Some methods allow parameters to be
single values or arrays of values. The single-value option is more of a
convenience thing, though, since myFunc([lonelyParam]) will always work.

> I was trying to gauge whether it's any overloading at all that raises
> peoples ire or if it's only the kind that leads to twisted, confused
> parameter-handling logic.

As usual ones MMV. But having methods doing diametrically opposed
things, depending on the supplied parameters is by any means bad. Hard
to understand, needs extensive documentation, and will inevitably lead
to convoluted code, once the code needs to be expanded. (Which it
frequently does, since the basic layout of the API will be one of the
first steps.)

Gregor

Scott Sauyet

unread,
Sep 16, 2011, 9:00:11 AM9/16/11
to
Gregor Kofler wrote:
> Scott Sauyet meinte:

>> I was trying to gauge whether it's any overloading at all that raises
>> peoples ire or if it's only the kind that leads to twisted, confused
>> parameter-handling logic.
>
> As usual ones MMV. But having methods doing diametrically opposed
> things, depending on the supplied parameters is by any means bad. Hard
> to understand, needs extensive documentation, and will inevitably lead
> to convoluted code, once the code needs to be expanded. (Which it
> frequently does, since the basic layout of the API will be one of the
> first steps.)

Well, although that sounds right, Garrett has already mentioned
methods with boolean parameters. I think there are probably times
when it would still feel natural to have a method with a single
boolean parameter to do two diametrically opposed things, although the
API could obviously instead have two distinct methods. No examples
are immediately leaping to mind, but I'll bet we'd find some if we
tried.

-- Scott

dhtml

unread,
Sep 17, 2011, 12:21:09 AM9/17/11
to
On Sep 15, 7:28 pm, Scott Sauyet <scott.sau...@gmail.com> wrote:
> dhtml wrote:
> > Scott Sauyet wrote:
> >> dhtml  wrote:
> >>> Scott Sauyet wrote:
> >>>> dhtml wrote:
> >>>>> Scott Sauyet wrote:
> >>>>>> Do you think all overloading in JS is a problem?  
> >>> [...]
> >> It's certainly a debatable point as to whether the `setHeight`/
> >> `getHeight` pair is more complicated than a single `height` function,
> >> but if nothing else, the latter has fewer symbols to remember.
> >> [ ... ]
>
> > OK, though I'm not sure if I need both of those methods.
>
> No, and there's plenty of reason for not bothering with getters or
> setters in most cases when working in JS.  I brought them up because I
> knew they were another form of overloading that jQuery practices.
>
> My main question was whether you feel that all forms of overloading
> are problematic.  And I persist with it because it's been a sticky
> question for me in my own API design.  I'm pulled in both directions.

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

> I seem to have mostly settled on accepting overloading on a single
> parameter, either allowing it to have several different sorts of
> related values, or allowing it to be optional.  I avoid the style that
> jQuery uses of using many parameters and allowing some in the middle
> to be optional, shifting the others around to assign everything
> correctly.  I'm curious as to whether others would still find this
> style problematic.

Sure, and if the method can expect native ES objects/values, and no
host objects are involved, then it's safer.

>
> >> So my question was really whether you objected to that sort of
> >> overloading.  Or perhaps even if you object as strenuously to that
> >> sort of overloading as you do to, say, the overloading of the main
> >> jQuery function.
>
> > 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.

With some forms of overloading, complexity is multiplied. The get/set
one-method approach is a case of doubling the complexity. Another
example of doubled complexity is addEventListener's `useCapture`. And
although web page authors need not look at the source code of that; we
still have to deal with its concomitant browser bugs.

[...]

> Yes, and there are other good reasons to prefer it.  But sometimes
> there are competing forces suggesting that you might be better putting
> some complexity in the method to make calls easier.  My earlier
> example was somewhat misunderstood, so I'll try to be a little more
> explicit:

Sure, I don't know if there's a strict rule for it but generally I try
to avoid overloading.

>
>     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);

But for the time being, you can keep the function and just reduce its
body to have that one liner.

[...]

> 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.

[...]
--
Garrett

Scott Sauyet

unread,
Sep 17, 2011, 4:45:14 PM9/17/11
to
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

| doSomethingDifficultThatDoesntHaveAnEquivalentNativeOneLiner(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

dhtml

unread,
Sep 18, 2011, 12:20:17 AM9/18/11
to
On Sep 17, 1:45 pm, Scott Sauyet <scott.sau...@gmail.com> 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
>
> |  doSomethingDifficultThatDoesntHaveAnEquivalentNativeOneLiner(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

dhtml

unread,
Sep 18, 2011, 12:34:45 AM9/18/11
to
On Sep 15, 7:28 pm, Scott Sauyet <scott.sau...@gmail.com> 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

dhtml

unread,
Sep 18, 2011, 2:07:31 AM9/18/11
to
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/public-script-coord/2011JulSep/0430.html
--
Garrett

Scott Sauyet

unread,
Sep 19, 2011, 8:12:24 AM9/19/11
to
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

dhtml

unread,
Sep 19, 2011, 1:16:46 PM9/19/11
to
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
0 new messages