Scott said:
This is made even more pointed by the order of the arguments in that
last line.
It is because d (document) is an option used only with frames (another
layer of support that will be filtered by the builder shortly). JFTR,
the above functions are from the PE collection (though my
createElementWithAttributes has arguments in similar order).
Why in the world would o2 be placed in the middle of the
set of parameters sent to the lower-level API?
Because the optional one is best last.
How is a developer
supposed to remember that order?
You almost never use the optional one and the optional one is always last.
The usual reasons for such strange
orderings is backward compatibility.
Nothing strange above, other than the underscores.
It's possible that the last
parameter to both the createElement and the
createElementAndAppendChild did not exist in an earlier version of the
API and were added to the end so that existing code needed less
change.
Could be, but no.
Either that or d is an optional argument that has to be
carried through, and you want all the optional ones at the end.
It is optional and as such, it does not necessarily have to be carried
through (unless it is passed to the higher level function).
But
if that's the case, implementation convenience is trumping solid API
design -- never a good idea.
There's nothing like that going on with these simple wrappers. It
wouldn't make them better to move the optional document argument to the
middle.
One advantage to Thomas' suggestion is that you don't need to carry
this baggage through multiple levels of API.
What suggestion? I explained that he could do what he wanted to do with
my API, which is not very much unlike his.
But to me the main issue is the intellectual weight.
There's nothing intellectual about these simple wrappers.
var el = API.createElement('div');
var el = API.createElementWithAtttributes('div', { ... });
But wait, you want to use frames? How could that work?
var el = API.createElement('div', doc);
var el = API.createElementWithAtttributes('div', { ... }, doc);
Yes, just tack the optional document argument onto the end, exactly
where it should go.
Perhaps most of
the work I would need to do could be done through the upper-level
APIs, but I imagine that occasionally I would need to use the lower
levels too, right?
Sure, as in the above example.
At that point, I have to remember the simpler
lower-level versions and the more complex higher-level ones.
Not in the above example. There's nothing to remember.
Keeping
track of parameter order is an issue, but even remembering whether
it's called "createAndAppendElementWithAttributes" or
"createElementWithAttributesAndAppend" gets to be an intellectual
burden.
So create a macro.

Or do this (you should anyway):-
var myMethod = API.createAndAppendElementWithAttributes;
var el = myMethod(this, that, there);
And if you want to use frames:-
var el = myMethod(this, that, there, doc);
Yes, tack on the optional document argument, the only place it could
logically go.
For example, in Java, the IO libraries are well layered, but this
comes at a heavy price for users. I'm going to try this from memory,
but would not be at all surprised if I'm wrong:
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(
new File(filename))));
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
It's a bit of a feat to get that right if you haven't been using the
API for a while. Meanwhile in Python, I have little doubt about this
code:
And what is that feat? Printing a file to the console? If so, Java
sucks for file IO and I am sure some smart egg has written a
higher-level console API.
f = open(filename, 'r')
for line in f:
print line,
That's better.
The Python API simply has less to remember, less to get wrong. It is
less flexible, perhaps. But for most of my day-to-day work, I would
rather be using a simple-to-remember and simple-to-use API than one
with lots of bells and whistles.
Yes, but how does that apply to the wrappers at hand? Could they
possibly be made simpler? About the only hole I see is a setAttributes
wrapper. I suppose you could add an append/insertBefore wrapper too
(those exist only in the OO layer in mine, which does leave gaps in the
lower levels).
Yes, *needless* stacking. It's not that stacking cannot be useful.
But if not done extremely carefully, it bloats an API and makes it
harder to remember and to effectively use.
Yes, I agree that needless stacking is bad. I just don't think it's
been shown that the three methods in question are needlessly stacked.
Each layer serves a specific purpose. There are problems with creation
and problems with appending. Each layer deals with its own problems.