Scott said:
Scott said:
David Mark wrote:
Scott Sauyet wrote:
Things like this are very convenient:
select("div.navigation a:not(li.special a)");
Honestly, that looks ludicrous to me.
Okay, it might look that way to you. To me it is a very concise and
intuitive way to say "select all the anchor elements that are inside
divs with a class of navigation but are not inside list items with a
class of special, and by the way, return them in document order,
please." That was the requirement.
The question remains, though, did the requirement make sense in the first
place? Was it really not possible to solve this problem differently, for
example with event bubbling, with using the CSS cascade, with using
standards-compliant event-handler attributes, or a combination of them?
And then, is the approach that had been chosen to meet the requirement more
or at least equally reliable than the alternatives? [ ... ]
These, of course, are useful and important questions.
I'm bothered, though, that a number of people here seem to feel they
know the answers to them in the abstract without any knowledge of
specifics of various situations. There seems to be a consensus among
some of the regulars in c.l.j.s. that CSS selector engines are a bad
idea; I'm not sure of the basis for that consensus. but it seems to be
strong enough that people are willing to assume those who disagree
have misunderstood either their own requirements or have failed to
consider alternatives. There seems to be no room for the possibility
that people have the requirements right, understand the alternatives,
and choose to use selector engines.
That in and of itself is speaking in the abstract. I much prefer looking
at the situation at hand to make a decision on how to affect the code.
[...]
I'm wondering if people here regularly work in fairly ideal
environments where they're in charge of all the mark-up and all the
CSS as well as all the JS used. While I'm sometimes in that
situation, it's much more common for me to be trying to squeeze some
behavior into existing HTML/CSS, often interspersed with existing JS.
It's often dictated by the project whether I can use inline JS. Often
a JS library has been chosen, and I must use it. Often parts of my
page are generated by black box systems.
Is this sort of environment unusual here?
Most of the time the code is awful. I'd like to look at why this is. I
feel that it is useful to understand a problem because in so doing, the
alternatives to causing the problem usually become self-evident.
Part of the problem comes from low standards of personal self
achievement. People just don't try hard. I see this every day at the
gym. I see it in doctors who are often arrogant, yet display lack of
knowledge of nutrition (often evidenced by their own corpulence). I see
it in customer service representatives who do not read or listen, but
parrot the same lines they're taught. Most relevantly, I see low
standards for acheivement on the web. Web developers are copying bad
ideas and practices and doing what they're told by managers who do not
have any business to do the telling.
The result of not trying hard is that the end product -- the web, in
this case -- suffers greatly. The web is a horrible mess. most sites
nowadays don't require javascript, but are authored in such a way that
if the user has javascript turned off, then the site does function.
Other sites display javascript errors or use strategies that are not
forwards compatible or limited to a subset of browsers.
An even worse problem is the internal quality of sites, where the site
is "working" as far as the client is concerned, but is designed in such
a way that changes are difficult and can have unwanted effects.
Another factor that contributes to badly designed web applications is
project requirements being handed from the top-down. The requirements
may start from marketing, which generates business requirements, to
project managers, to hiring managers, who hire the front-end coder.
Hiring managers usually do know how to hire qualified front-end
developers. As a result, they tend to end up making decisions based on
not-so-good criteria (e.g. "can you write a merge sort" or the trick
logic questions that are fun, but totally worthless for solving
web-related programming problems)
If the project ideas and goals are evaluated earlier in the process
involving the front-end developer, and not at the end of the line with
the final decision of what must be done, and reiterated involving the
front end developers, then bad program decisions can be avoided in
solutions that solve the problem more simply or effectively.
No matter what project, if the project involves writing rich
functionality in the browser, then there is going to be a need to write
javascript functionality and that functionality will be best organized
into abstractions. How to organize those abstractions requires
assessment of the situation by somebody with experience using the
technologies correctly and who has experience in organizing systems of
javascript. Having knowledge of how to use a javascript library is not
pertinent to the type of skillset of organizing abstractions.
To summarize: Every project company will have to write its own library.
The degree of sophistication of this library may vary and the things
that it does will likely vary as well.
The process of adding new features atop existing functionality for which
they are not elegantly accommodated results in code debt. Google groups
is a fine example of that, as can be seen many of the "improvements"
show that new functionality that was added atop a system that was not
well designed in the first place resulted in code that was a total mess
(Discussions of this exist in the archives.)
I have authored such things as, for example, a "StubManager" which fired
"StubChangeEvents", a "TimeSynchronizer", "RadioGroup",
"ConditionFilter". Each project have a use-case that is unlikely to be
reused in another project. Knowing when, why, and how to create
abstractions for such use cases is important.
In addition to writing its own library, every company will have to
actively maintain its code. A formalized testing process for maintenance
can go a long way to make it easier to quickly make new changes and
additions to the code while verifying not only "does it still work", but
redefining what "work" means, and if there is something that the program
is doing that it should not be doing anymore, then the code that is
performing that can be removed.
When the software does not do what is wanted of it, and when a
behavioral change is wanted, then it becomes necessary to change the
code. The change often requires modifying that which already exists and
that requires understanding everything that the existing code should be
doing (and identifying code which is irrelevant, useless ("dead code")).
Layering functionality on top of legacy code can tend to increase
technical debt. It leads to more dead or useless code and general
confusion about what the code does, e.g. "what does this do", "I thought
it was working before", and other such inanities.
At a certain point of debt accrual, changes become so expensive so that
the important changes must be weight against the cost of rewriting the
entire system from scratch.
I can recall specific instances where the code was gutted and removed
and the result was a system that was clearer and cleaner than would have
been possible if that had not been done.
One was where the code had included content in the form of:
<script>
if(isMacIE) {
document.write("<img ..");
// etc for NN4, et al.
</script>
In that case, I did my best to understand exactly what the code should
be doing and ended up removing the script tag. The result was code that
could be clearly understood by almost anyone.
I can think of many more cases where that sort of approach was not used,
and for a period of time, I was very patient with others, trying to not
push my ideas of how things ought to be done. I recall specifically on a
project where I took that mindset that the code was awful, I worked my
ass off, my coworkers were lazy and unprofessional, and the project
failed. I am not not so patient and make no bones about pointing out
problems in the code. I am not interested in being part of a failing
project.
What I have been doing is to create a base library that will make it
easier to develop widgets and systems. You can still easily write bad
code and if you don't know what you're doing with it, it is probably
going to be even easier to write bad code (by facilitating and
empowering and augmenting mistakes on a whole new level). What it does
do is make it easier for someone who wants to write a system for a RIA
(or browser-based app, or whatever you call 'em).
So to answer your question: "Is this sort of environment unusual here?"
I would stay that it is not unusual, but is instead a very common
symptom where the developer is asked to add features to a maldesigned
system.