First, Leach is a skilled manipulator of words. He is capable of making a precise statement that projects the Microsoft viewpoint, regardless of the reality. That he is convincing and appears that he is a true believer is a side effect.
Second, he is artfully avoiding the reporter's question: "Would Microsoft have publicized the results if they hadn't been positive?" Of course, the answer is, No. But giving that answer would have drawn the interviewer's attention (and likely the reader's) to the possibility that Microsoft is paying for many studies, most of which document Linux's superiority in important respects, but then publishing only the minority that support Microsoft's claims. Instead, he sidesteps the question, telling the white lie that they hadn't even considered the possibility of having Linux come out on top and thus having to silence those findings: "[That Windows would come out on top] was never going to be a question."
He sidesteps the question and reinforces the "reality" that Microsoft wants to project in one clever response.
Would it be considered terribly inappropriate, or even grounds for appeal, if the judge called Darl and Kevin McBride to the bench and then repeatedly, and with extreme prejudice, smote them with her gavel?
Yes, so it would seem. First, they baked it, and then they hung themselves by it. Quite sad, really, as it is rather tasty: After all, if you're going to hang yourself from a loaf of crusty, delicious bread, you ought to at least have a taste before meeting your untimely demise.
I, like many other folks, run OS X 10.2 (Jaguar) on an older, "Beige" G3, which is not supported by Panther. Unless Apple provides security patches for Jaguar in addition to Panther, Beige-G3 owners like me will be stuck with an OS that had known security holes and no reasonable way to plug the holes.
That's so wrong that I have a hard time believing that this is actually Apple's position. I expect that we'll hear from Apple shortly, and they will clarify their position -- that the patches for 10.2 will be out Real Soon Now.
But if not, Apple's going to get a lot of bad PR from this.
About fifteen years ago while working for a defense contractor, I
happened to be present while a DEC service technician was inspecting one
of the many on-site Vaxen as part of a "preventative-maintenance"
contract. This particular machine was running Ultrix, DEC's
then-favored flavor of Unix, and the sysadmin and I were standing
by while the inspection took place.
At one point in the inspection, the technician had to monitor the
machine from a boot-up state, and so he rebooted the machine. The
only problem was, the machine didn't come back up. Instead, it hung
early in the boot process, leaving the distinct impression on the
observers that the technician had hosed up a perfectly good -- and
very expensive -- minicomputer.
Apparently, the same impression was left on the technician, because
he started sweating. A lot. He tried rebooting the machine again,
obviously unsure of what the hell he had done to land in his present,
miserable condition and just as obviously wanting desperately to be
released from it. The machine hung up again. More sweat. Another
attempt. Same thing: Hang. Then he opened the case and peered
inside. He was clearly grasping at straws. The sweat started to bead on
his forehead.
Eventually, after about fifteen minutes of increasingly distressing
diagnostic procedures, consulting the LEDs, and hand wringing, he
gave up: "You've got a bad motherboard. I'll have to call in for a
swap." He half ran away from the uncomfortable scene to make his
phone call.
While he was gone, the sysadmin busted out laughing. Then he pointed
at the keyboard on the console VT320. The Scroll Lock LED was lit.
The sysadmin said that the technician must have hit it earlier and
never took it off before rebooting. When the kernel tried to send
boot-up messages to the console, the console wouldn't accept them,
and so the kernel blocked, waiting for the Scroll Lock to be
released!
A few minutes later, the technician returned, looking only a bit
less nervous. In his best it's-under-control voice: "Yeah, we'll have
that new board out right away. No problem." The sysadmin's reply:
"Great! I'm sure glad we have the preventative-maintenance contract,
because I bet those boards are plenty expensive. I'd hate to pick up
the tab for one of them." After a few precious moments of letting
that thought sink in, the sysadmin "noticed" the scroll-lock
situation: "Hey, isn't the scroll lock on? Let's just see what
happens if I..." He then tapped the keyboard.
I'm not buying your claim about run-time derivation
and abstraction levels, since the target language is likely to be the
same either way, even if the translation language is
different.
This argument misses three important points: First, even if the target
language is the same, at compile time you have the luxury of targeting
the target language's compiler and leveraging all of its
power. At run time you have no such luxury.
Second, the code that is
responsible for the run-time derivation must be written in the target
language, and if the target language makes the derivation difficult
(because, e.g., it is too low level), you will do more work than
necessary -- or fall back to weaker abstractions in your
specifications.
Third, in the run-time case, all of the code that executes the
derivations (e.g., an interpreter) must be written by hand and hence
be readily understandable by humans. Compile-time code generators
need not suffer this higher burden: They can generate incomprehensible
output code because no human is meant to maintain it.
To convince yourself of the merits of my counterpoints,
consider the case of parsers. The specification is a file defining a
grammar. Your job is to create a parser for the specified grammar,
and you know that the grammar will change occasionally. Now, you can
generate the parsing code at compile time (in effect, writing
something similar to yacc or antlr), and this task is straightforward.
Or, you can try the run time approach. Of course, at run time you
won't have the facilities of the target language's compiler at your
disposal. Therefore, you'll have to code -- by hand -- a
general-purpose parsing apparatus that you can
reconfigure at run time based on the input grammar.
Spend a few moments thinking about how you might approach this
coding problem. It's much harder than the equivalent compile-time
problem. Why? Because at run-time you're operating at a much lower
level of abstraction. You can no longer leverage the abstractions
provided by the compiler. You're stuck at the level of run-time
abstractions, which is a subset of what you can do with the compiler.
For example, it's easy to create new classes at compile time but
very difficult at run time.
Finally, booch asked:
BTW, is there a well-used term to distinguish run-time
derivation from code generation?
But I'm not very clear on the advantages of code
generation versus descriptive code. One example I like to use is glade
versus libglade. The advantage of being able to convert a descriptive
file at run-time seems to outweigh the benefits of doing it at compile
time.
Code generation and what you are calling "descriptive code" are both
methods to derive an implementation from a specification (a "description
file"). The difference between the methods is that the former does
the work at compile time, and the later, at run time.
Deciding which method is better, like most programming decisions,
depends on the situation. In the case of user interfaces, it is
advantageous to be able to change the UI after the code has been
compiled; therefore, run-time derivation is probably a better choice.
In the case of my object-based database example, compile time
derivation allows the compiler to do the important and otherwise
expensive job of ensuring that the back-end database and the overlying
application are in sync, and so it was a better choice.
Later, booch wrote:
But I don't find [compile-time checking] to be all
that helpful either.
You're missing something important here. The point of using an
external specification (i.e., a descriptive file) instead of
hand-written code is that you can create extremely high-level
abstractions that are ideal for the job at hand, and then use those
abstractions to "write" your specification.
Once you have a suitable specification, then you can begin to weigh
the differences between the compile- and run-time methods: By doing
the derivation at compile time, you are free to use tools and
languages beyond your ultimate target language. For example,
even if Java is your target language, you can use Ruby or Haskell to
convert your specification into Java. This lets you choose the tools
and languages that are best suited for representing powerful
abstractions and translating your specifications into code. With
run-time derivation, however, you're limited to your target language,
even if it's a poor choice for your desired abstractions.
If the descriptive file has errors, it's not
going to work either way. And you're going to have to do your error
checking on the descriptive code the same way, whether you're doing it
at compile time or run-time.
The problem with this thinking is that, if you use run-time derivation,
you're more likely to use weaker abstractions in your specifications
because you're tempted to constrain your abstractions to those
that are easiest to represent in your target language. When you use
weaker abstractions, you place a higher burden on the people who must
write the specifications, and that burden results in a greater chance for
error.
Code Generation is for people who don't understand or are too lazy for abstraction...
Baloney.
Code generation is a practical, efficient tool for solving many
problems where OO-style abstraction need not enter the picture. One such class
of problems is building interfaces and glue code from external
specifications.
A few years ago, I wrote a simple code generator that reads the SQL
DDL for a large database and generates an object-based interface to
the database. Client coders could then use the object-based interface
to access the database. The advantages of this approach proved to be
numerous:
Single, authoritative reference specification.
The object interface was always in sync with the reference, which for
this project was the database schema.
Richer compile-time error detection. The
projection of the schema into the object interface was fully available
to the type system so that many kinds of client errors could be caught
at compile time, not run time.
Reduced opportunity for errors between subsystem
boundaries. Because the object-based interface was generated
by machine from the actual database -- and not derived from some
programmer's understanding of the database -- there were
fewer opportunities for impedance mismatch across the boundaries
of the application code and the database. (Studies of errors in
complex projects have shown that errors are more common between
subsystem boundaries, and so this benefit is important.)
mcc further states:
But I cannot think of any case in an object-oriented
language where it would be both less work and more maintainable to
write a code generator than to just abstract away the parts that would
be auto-generated.
If you can't think of any such cases, it's because you're thinking too
small. Look at the bigger picture. For starters:
When the number of variables affecting the desired code characteristics
is large enough to make hand-coding (at any level of abstraction)
impractical. E.g., FFTW: "FFTW
uses a code generator to produce highly-optimized routines for
computing small transforms."
When your code must conform to an external reference specification
that changes rapidly enough to make hand coding (at any level of
abstraction) impractical. (See my example above.)
When the requirement for correctness is so stringent as to make
hand-coding methods impractical, mandating code generation from
a formal specification.
When you must target an output language whose native abstraction
capabilities are too crude to capture directly the degree of abstraction
that is merited. Believe it or not, most popular OO languages
fall into this category for many commonly occuring problems. Hence the popularity of design patterns. (Compare, e.g., with the abstraction capabilities of modern
functional programming languages like Haskell and O'Caml.)
Make no mistake about it, code generation is a practical, effective tool that every programmer should understand. To dismiss it out of hand is a costly mistake.
Maybe we need a fundamentally better CVS replacement than Subversion or arch. From the Quick Reference Guide to Free Software Revision Control Systems, the most interesting candidate is darcs. Under darcs, any checked-out copy of code is a fully functional branch repository, making distributed developement easier than under traditional one-master-repository systems. Plus, any revision control system whose author has developed a formal Theory of Patches can't be all bad.;-)
So yes, I'll look into just posting the spec without all that legaleze stuff.
Excellent! Thanks for being cool about this.
It's the weekend, though, so I doubt it would happen until Monday.
Can you give us anything right now? Monday, I'll be working, but today I can look at your spec. I'm sure a lot of other Slashdot readers are in the same boat. Also, on Monday, your article will be long gone from the Slashdot front page, and so you might want to make better use of this opportunity to introduce readers to the meat of dSVG.
Even if you must wait until Monday to get the OK from the lawyers to post the spec, certainly you can give us something now to give us a feel of dSVG.
How about posting or linking to a few snippets of dSVG code? (Actually, I'm surprised that you didn't include a snippet or two in your original announcement.) Most programmers reading this article will want to see what dSVG code looks like. Throw us a bone!
I am interested in reviewing the spec, but it's presently tied to the test-suite software, which is locked away behind a long, complicated, and scary-looking license agreement that I'm not comfortable agreeing to. Could you please provide a link to just the spec?
Since you have already submitted the spec to the W3C SVG WG, it's already public knowledge, and there's no reason to hide it behind legalese, right? Can't you just provide a link straight to it?
I'm sure a lot of other people are more interested in the spec than anything else. If you want them (and me) to take a look at dSVG, please make the spec available by itself.
Quick-and-dirty vs. Do-the-right-thing -- what's the right choice?
Let's consider the evidence:
I keep finding myself on projects where a quick and
dirty solution will bring in money for the company, and a correct (ie,
properly documented, well engineered, process followed, etc) solution
will get us left in the dust.
If this is true, then the author of the original post has answered his
own question: The quick-and-dirty solution was the correct
solution. What he had initially labeled as "correct" -- good docs,
adherence to sound processes, and so forth -- according to his
analysis wasn't viable; it would have caused his company to be "left
in the dust."
So he did the right thing.
And yet, he offers this testimony later:
Most recently, work I did in record time was used to
help bring in several large contracts, and then I found myself in hot
water for not having followed process et al.
What went wrong?
I'll tell you what went wrong. The author apparently made the choice
to go quick and dirty by himself. Instead, he should have
forced his managers to make the call: If you want to go that
fast, we'll have to cut corners. Are you willing to accept the
consequences? Then he could have held them to their decision.
If they came back to him later with complaints about quality or his
deviation from internal processes, he would have had a sound rebuttal:
You told me to cut corners, and that's what I did.
But it's not always that simple. Sometimes it is irresponsible to
cut corners, even when your managers direct you to do it. For
example, if you're working in an engineering capacity, you have a
responsibility to the public to protect their safety and well being.
If your boss asks you to cut corners on the software that controls
X-ray dosing in medical imaging equipment, your answer must be,
No.
Nevertheless, even in this case, the right thing to do is force the
managers to make a decision, and hold them to it. I'm sorry, but
I can't cut corners. We both have a responsibility to the public
here, and so we have no choice but to find another way to meet our
timelines. Agreed?
So, to answer the final question:
[I]s it better to do the quick thing and greatly
increase the chance of $uccess now, or to do the correct thing and
avoid pain later... ?
The answer is simple: It's not your call. Don't make it.
Let me clarify. In the statement that you quoted, I was extending the discussion about commodity, consumer-level technology that I had opened in my introductory paragraph. To be clear, this is what I meant:
Server hacks like the 66-MHz PCI bus speed and 64-bit-wide PCI are neither practical nor sustainable as part of a commodity, consumer-level PC architecture.
The point that I was making is that 64/66 PCI and PCI-X are "server hacks" that stretch extra headroom out of an aging bus concept that was originally targeted at mainstream PCs. These extensions are neither practical (too expensive) nor sustainable (can't keep adding additional traces) for advancing the mainstream PC architecture, which has now outgrown the original technology.
In order to break the I/O bottleneck for the mainstream PC, something else is required. Hence PCI Express.
Standard PCI tops out at 133 MB/s, which is about 1000 Mb/s. Hence one active Gigabit Ethernet card can saturate a PCI bus, leaving no headroom for other I/O. With GbE becoming commodity, consumer-level technology and 10-Gigabit Ethernet on the horizon, PCI is a bottleneck to the advancement of the PC architecture.
Server hacks like the 66-MHz PCI bus speed and 64-bit-wide PCI are neither practical nor sustainable.
That's why we need something different, something like PCI Express. It raises the I/O bar enough to give us another few years of unconstrained growth of the PC architecture.
Stop talking about "ageism"; do something about it
on
Ageism in IT?
·
· Score: 4, Interesting
Is there ageism in IT? Probably. Nevertheless, there are legitimate
reasons why younger programmers are often hired over older
programmers.
First, younger programmers have less experience in
life. Lacking the well-earned caution of older professionals,
they tend to be enthusiastic about their work, which they meet with
alacrity. Managers often interpret this enthusiasm as "energy,"
"speed," and "higher productivity" -- all valuable traits worth
seeking an an employee. Even though I know of no measurements or
studies to support this interpretation, the perception is widespread,
and it's not unreasonable for HR folks to act upon it.
Second, as others have pointed out, younger programmers
usually have fewer extracurricular responsibilities to compete
with work. Managers see this as increased devotion to the company and
the opportunity to get more work for the same money. Again, it's not
unreasonable to give preference to people with fewer extracurricular
distractions.
Third, in the software industry, experience is rapidly
devalued because the valuable mainstream technologies often make
one another obsolete. (This is in contrast to, say, the legal
profession, where decades-old experience is readily applicable.)
While this fact doesn't directly benefit younger programmers, it does
put more-experienced (and hence older) programmers at a disadvantage
because they are perceived as wanting compensation for their
vast, often irrelevant experience. In other words, managers often
feel that more-experienced programmers want more pay than they are
truly worth.
All of these reasons give managers and HR folks good reason
to hire programmers who just happen to be young.
But, there's more to the story
That said, I have been coding for about twenty years. There is no
doubt in my mind that the me of today can write much better software
than the me of ten years ago, and I can do it in less time. Likewise,
when I consider all of the young, hotshot coders who I used to work
with when I was a young, hotshot coder, I would rather hire them as
they are today than as they were back then. Simply put, they
are better coders today.
Back then, we cranked out the code, and our employers loved us.
But, being honest, much of that code was crap, and much of our
"productivity" was wasted on false starts, gold plating, blind hackery,
and all-night debugging sessions that could have been avoided by a
more disciplined approach to creating software. The thing is,
our managers couldn't tell the difference between fast, furious
activity and true productivity. And neither could we.
And that's the most dangerous threat to older, more-experienced
software professionals: Lack of measurement. I'm convinced that
experienced professionals who have invested in their abilities, made
consistent effort to learn from their mistakes, and know how to
communicate effectively are worth their weight in gold. In the long
haul, they will outpace inexperienced hotshots almost every time.
But without measuring actual performance, you'll never notice.
You'll mistake long hours for productivity. You'll mistake
unnecessary all-nighters for dedication. And you'll mistake
older programmers for expensive versions of their younger
counterparts.
So, if you are an older, experienced software professional, stop
talking about "ageism". It's a lost cause. Start talking about
realisitc productivity measurements. If you want to be
perceived as more valuable, you'll have to do it the hard
way: You'll have to prove it.
The tactic of walk-out is as old as the labor movement
and is a valid response to unreasonable demands from management.... A
'strike' is a valid tool.... It is not unprofessional to go on 'strike',
it is a right.... Unions are just as relevant today as they were in the
30's.
Two questions:
First, did you read the whole story?
The
reason I ask is because the original poster made it clear that this
was not a collective bargaining situation. This is not a strike.
This is not a walk-out. They are not trying to gain anything
from the company. They don't want better pay. They don't want
better hours. Rather, they want to leave -- for good -- in a way
calculated to inflict maximum harm.
Surely, you can see the difference. Right?
Second, are you replying to my response, or some imagined anti-union rant?
The reason I ask is because my response doesn't suggest that the employees
shouldn't walk out together, nor does it suggest that they throw away their right to act
collectively. It says, rather, that if they do walk
out, they should do it as professionals.
Given that they are leaving for good, they have no desire to shock
the company into a better bargaining position by an immediate
walk-out. Therefore, the only thing the employees could
possibly have gained by leaving without notice is the momentary
satisfaction of having taken revenge on their employer. As I pointed
out, this satisfaction isn't worth the damage it would cause to their
reputations.
The vast computing resources that children have today are both a curse
and a blessing. The curse is that there is so much more complexity
for today's children to grapple with than we had when we were learning
to write software. But, the blessing is that today's children have
vast computing resources at their disposal, resources that we could
scarcely dream about.
I think we ought to harness those resources. We ought to use them
to teach children those languages that are immensely powerful yet,
judged by our standards, too inefficient to be practical.
In particular, I'm referring to functional programming languages
like Scheme and Haskell.
Now, hear me out.
Why functional programming languages? Because they lend themselves
to extremely powerful, mathematical ways of thinking about and solving
problems. Learning these ways of thinking when young will benefit our
children for the rest of their lives. For example, take a look at the
The TeachScheme! Project.
I wish something like that was available when I was in High School.
Let us not teach our children the technologies of today but of
tomorrow. More and more, I am convinced that functional programming,
once considered too computationally inefficient for industry work, will
be tomorrow's dominant programming paradigm. No other way of
programming so readily lends itself to the formalism that is necessary
to manage the ever-increasing complexity of modern software projects.
So, let us give our children the tools they will need to solve
the problems of their day. Teach them functional programming.
That doesn't mean you must work overtime in terrible conditions
for poor pay. But it does mean, if you decide to take your employment
elsewhere, that you leave the company like a professional.
Treat your reputation like a valuable possession -- because it is.
You get together with the rest of the department for a 'fsck this company' meeting and decide to walk out.
Sorry, but walking out is a "screw-your-employer" gesture. It's about
as unprofessional as you can get and, even worse, makes you look
vindictive. Is that really the impression you want to leave? Do you
really want to trade a good piece of your reputation for a few
fleeting moments of take-this-job-and-shove-it jubilation?
Be professional. Give two weeks notice.
Like most people, you are probably under an "at will" employment
agreement that gives you the right to walk out whenever you please.
Don't do it. Give the two weeks, which is universally considered
reasonable and comes at no cost to your good reputation.
If you do resign, tender your resignation in writing. Make it
simple, polite, and direct -- professional. Something like,
"I am writing to inform you of my resignation, effective on
date." That's all you need. Do not
include a grand, barbed explanation of why you're leaving,
which is especially tempting when you feel that your employer has wronged you.
When your employer receives a stack of resignation letters on the same day, they'll get the point. No need for you to draw circles around it or point to it with big red arrows.
Remember: When you leave, do so in a way that makes it clear to your employer
that they are losing somebody valuable. Be professional.
Underappreciated indeed, Miller's Crossing is a great, fun film. One of the Coen brothers' best. Gabriel Byrne, John Turturro, and Albert Finney. Great script. 'Nuff said.
Too bad it's not available on DVD. (Yet! I just learned (via IMDB) that this film, released in 1990, is coming to DVD in May. Yipee!)
It's VERY VERY hard to mask these timing issues by
"random" delays. [...] Best case, the attacker will have to run his
attack a couple more times to get the same results through the noise.
This is true only if the random delays are added to the
running time of the operation you want to conceal. A simple,
alternative method that reveals no information about the operation's
running time is to decide upon the total (typically random) running
time before performing the operation. Then, after
the operation completes, pad out the balance of the decided-upon time
with a delay:
You'll notice that this method reliably conceals the running time of
perform_op and, further, that true_random can be
replaced with a weaker function (and even a constant!) without
risk of compromising the running time of the concealed operation.
Nevertheless, it would be better to rewrite the concealed operation so that its running time didn't reveal sensitive information. Having to use delaying tactics imposes a significant response-time penalty, which can be a problem where low latency is desired. But it's nice to know that these concealment techniques are available when it's not possible to change the concealed operation (e.g., when the operation is part of a closed-source library).
As systems become increasingly complex, the practicality of (and even
the feasibility of) treating them as a monolithic entities becomes a
legitimate concern. One method of addressing this concern is via
abstraction, where suitable models are used as representations of their
real-world counterparts. Indeed, abstraction is one of the
fundamental principles of engineering and has been used for thousands
of years to great success in the construction of complex systems.
For example, in electrical engineering, it is common to simplify
complex circuits by breaking them into smaller circuits, analyzing
each of the smaller circuits, and then replacing the smaller circuits
with appropriate black-box equivalents. With these black boxes in
place, the original circuit becomes much easier to understand.
However, as in any modeling exercise, it is crucial to choose
appropriate models and to understand the limitations of the models
chosen. While a simple resistance model might be a good substitute
for DC and low-frequency circuits, it would be inappropriate as a
substitute for higher-frequency circuits where capacitance effects
come into play.
So, returning to the original poster's questions:
Do Slashdot readers think that the theories used to
teach (and learn) programming lead to programmers that tend to
approach problems with a 'black box', or 'virtual machine' mentality
without considering the entire system?
Yes, in these days too much stock is placed in the idea of letting
somebody else worry about the complexity. This is especially so in
mainstream industry, where one of the key selling points of software
development systems is that with Magic DevStationPro X you no longer
have to worry about the details but instead just use some brilliant
Wizard or API to work at "a higher level." This applies not only to
software development but also to user-level domains such as operating
systems and applications. For example, a common notion in industry is
that by using Microsoft operating systems on servers, administrators
no longer need to know how to administer servers; rather, they need
only know how to use the GUI administration tools. In other words,
the pitch is that you need not concern yourself that the GUI tools
present a mere model of the underlying system. Let the model
be the system and reap the rewards.
That's hogwash. The model approximates the system, no more.
In engineering, this is well understood, and I suspect that in good CS
programs the same can be said.
Abstraction is a powerful tool. It is widely applicable,
effective, and well founded -- when used appropriately. It probably
ought to be used more often. Nevertheless, it is not a substitute for
rational thought. Nor is it a replacement for being responsible for
the entirety of the systems we build.
That, in and of itself, would
explain a lot of security issues, as well as things as simple as user
interface nightmares. Comments?"
It would certainly explain some of these problems, but I suspect that
far more errors are the result of interface errors. One of the tools
that goes with abstraction is composition -- breaking things into
pieces, treating the pieces individually (at fine granularity), and
combining the pieces (at a larger granularity) to yield a system. The
risk of combining pieces is that in order to put them together
properly, the boundaries where they coincide -- their interfaces --
must be well understood and compatible. Since the individual pieces
make natural units for delegation, pieces are often assigned to
different people who may have slightly differing understandings of the
boundary conditions. As a result, "interface mismatches" are a
significant source of error in software systems.
Certainly abstraction plays a role here. Each piece can be thought
of as a black-box model. The limitations of that model, and the
assumptions under which the model is valid, are certainly important
characteristics of the piece's interface with the world. Yet, these
characteristics are frequently neglected in documentation and often go
uncommunicated across delegation boundaries. This sad fact makes
interface mismatches an especially harmful side effect of using
abstraction and composition in common software development practice.
Nevertheless, abstraction is a powerful and genuinely useful tool.
It is also a necessary tool if we are to build increasingly complex
systems. Like any tool, its uses and limitations must be understood
if it is to be applied effectively. Thus, getting back to the
original poster's question about whether the use of black boxes is
harmful, my answer is, No.
The problem isn't abstraction, the problem is improper use of
abstraction.
No offense, but it's obvious from your comment that you
aren't a lawyer (even if you hadn't told us).
No offense, but did you read my post? Where does it rely upon a legal
argument? It doesn't.
Rather, I suggested that he make a strong ethical argument on the
grounds that revealing the necessity of a credit check as a condition
of his employment AFTER he and the employer had negotiated the terms
of his employment, AFTER they had reached an agreement, and AFTER he
had left his previous job, was a flagrant abuse of the negotiation
process and showed the employers to be inherently dishonest people --
unless of course, it was all a silly mistake. In which case, they can
all forget about the matter and get back to work.
Unless you have a contract (preferably written), there
are no such things as the terms of your employment.
Hogwash! How much is he paid? What is his title? What are his
duties? When does he start? Are these not terms of employment?
Certainly, he went through some process of interviewing and
subsequent negotiations. What caused the negotiations to stop? What
caused the employer to say, "Glad to have you aboard. We'll see you
next Monday." What caused the new employee to say, "I'm looking
forward to it"? An agreement, of course. Even if the agreement
wasn't written, it is still an agreement. Even if it isn't legally
binding, it was still an agreement.
And the employers know it. That's the thrust of my argument.
Unless the employers are truly dishonest people, they will recognize
that springing a make-or-break condition of employment on a new hire
after he and they have already come to an agreement was, is,
and always shall be a breach of the honesty and good faith that
underly any negotiation process. Once the new hire makes this clear
and asserts his willingness to make a stand on it, the employers must
either agree with him that the whole matter was a regrettable mistake,
best forgotten, or live with the stigma of being publicly branded as
a lying bunch of weasels.
My hunch is that most corporate folk would choose to forget about
it.
There is only one term of employment for a non-contractual
employee: at will. [...]
This is immaterial to my argument. It's not a matter of legalese but
people politics. It just so happens that our protagonist is aligned
with the forces of Good on this one, and he can use it to his advantage.
Legal strategy need not enter consideration.
First, I am not a lawyer. If you want advice you can trust, talk to one. Now, regarding this:
On my first day, I was provided with all of the
standard employment paperwork... as well as a document that is to
provide my permission for the Company to do a... credit history
check.
Let me get this straight: They sprung this condition of employment on
you after you accepted the job, left your previous job, and
arrived for the first day of work? That's outrageous!
If I were in your shoes, I would say no, politely and firmly:
I am sorry, but I will not agree to these new terms.
We have already negotiated the terms of my employment, and these
additional items were not part of our agreement. For you to attempt
to change the terms now, after we had agreed upon them, and after I
have left a good job with my previous employer, runs counter to
established business practice and is simply unethical. As a matter of
principle, I must reject these new terms.
As a courtesy to you
and a sign of my good faith, I will consider the whole thing to be a
simple mistake and press it no further. I trust this will be the end
of the matter.
If they didn't let the issue drop, I would talk to a qualified
attorney. Pursuing the matter would probably irreparably damage
your relationship with your new employer. But, then again, if they
really pulled something this weaselly, maybe they aren't the good
employers you thought they were when you signed on.
These two could legally prevent businesses (and agencies) from accessing their own documents if encoded in undocumented, proprietary formats and the tools to manage these formats are no longer licensed.
I don't think so. If I create a document, I automatically become its copyright holder. If an office-software vendor encodes my document into some proprietary format, the result is a derived work based on my copyrighted material. The encoded property within is mine, not the vendor's, and hence the DMCA does not in any way prevent me from decoding the vendor's format in order to retrieve my copyright-protected material.
Remember, the DMCA's (overly reaching) powers are granted to the copyright holder who tries to protect his own works by placing technological barriers around them. In your example, an office-software vendor tried to place technological barriers around works that they did not own. The DMCA does not apply.
Second, he is artfully avoiding the reporter's question: "Would Microsoft have publicized the results if they hadn't been positive?" Of course, the answer is, No. But giving that answer would have drawn the interviewer's attention (and likely the reader's) to the possibility that Microsoft is paying for many studies, most of which document Linux's superiority in important respects, but then publishing only the minority that support Microsoft's claims. Instead, he sidesteps the question, telling the white lie that they hadn't even considered the possibility of having Linux come out on top and thus having to silence those findings: "[That Windows would come out on top] was never going to be a question."
He sidesteps the question and reinforces the "reality" that Microsoft wants to project in one clever response.
Give him his props: This man has skills.
Just curious.
Does anybody know about the latencies on this network? Can it be used for interactive tasks like ssh? VNC? videoconferencing?
That's so wrong that I have a hard time believing that this is actually Apple's position. I expect that we'll hear from Apple shortly, and they will clarify their position -- that the patches for 10.2 will be out Real Soon Now.
But if not, Apple's going to get a lot of bad PR from this.
At one point in the inspection, the technician had to monitor the machine from a boot-up state, and so he rebooted the machine. The only problem was, the machine didn't come back up. Instead, it hung early in the boot process, leaving the distinct impression on the observers that the technician had hosed up a perfectly good -- and very expensive -- minicomputer.
Apparently, the same impression was left on the technician, because he started sweating. A lot. He tried rebooting the machine again, obviously unsure of what the hell he had done to land in his present, miserable condition and just as obviously wanting desperately to be released from it. The machine hung up again. More sweat. Another attempt. Same thing: Hang. Then he opened the case and peered inside. He was clearly grasping at straws. The sweat started to bead on his forehead.
Eventually, after about fifteen minutes of increasingly distressing diagnostic procedures, consulting the LEDs, and hand wringing, he gave up: "You've got a bad motherboard. I'll have to call in for a swap." He half ran away from the uncomfortable scene to make his phone call.
While he was gone, the sysadmin busted out laughing. Then he pointed at the keyboard on the console VT320. The Scroll Lock LED was lit. The sysadmin said that the technician must have hit it earlier and never took it off before rebooting. When the kernel tried to send boot-up messages to the console, the console wouldn't accept them, and so the kernel blocked, waiting for the Scroll Lock to be released!
A few minutes later, the technician returned, looking only a bit less nervous. In his best it's-under-control voice: "Yeah, we'll have that new board out right away. No problem." The sysadmin's reply: "Great! I'm sure glad we have the preventative-maintenance contract, because I bet those boards are plenty expensive. I'd hate to pick up the tab for one of them." After a few precious moments of letting that thought sink in, the sysadmin "noticed" the scroll-lock situation: "Hey, isn't the scroll lock on? Let's just see what happens if I ..." He then tapped the keyboard.
And the Vax booted right up.
True.
Second, the code that is responsible for the run-time derivation must be written in the target language, and if the target language makes the derivation difficult (because, e.g., it is too low level), you will do more work than necessary -- or fall back to weaker abstractions in your specifications.
Third, in the run-time case, all of the code that executes the derivations (e.g., an interpreter) must be written by hand and hence be readily understandable by humans. Compile-time code generators need not suffer this higher burden: They can generate incomprehensible output code because no human is meant to maintain it.
To convince yourself of the merits of my counterpoints, consider the case of parsers. The specification is a file defining a grammar. Your job is to create a parser for the specified grammar, and you know that the grammar will change occasionally. Now, you can generate the parsing code at compile time (in effect, writing something similar to yacc or antlr), and this task is straightforward.
Or, you can try the run time approach. Of course, at run time you won't have the facilities of the target language's compiler at your disposal. Therefore, you'll have to code -- by hand -- a general-purpose parsing apparatus that you can reconfigure at run time based on the input grammar.
Spend a few moments thinking about how you might approach this coding problem. It's much harder than the equivalent compile-time problem. Why? Because at run-time you're operating at a much lower level of abstraction. You can no longer leverage the abstractions provided by the compiler. You're stuck at the level of run-time abstractions, which is a subset of what you can do with the compiler. For example, it's easy to create new classes at compile time but very difficult at run time.
Finally, booch asked:
Not that I know of.Deciding which method is better, like most programming decisions, depends on the situation. In the case of user interfaces, it is advantageous to be able to change the UI after the code has been compiled; therefore, run-time derivation is probably a better choice. In the case of my object-based database example, compile time derivation allows the compiler to do the important and otherwise expensive job of ensuring that the back-end database and the overlying application are in sync, and so it was a better choice.
Later, booch wrote:
You're missing something important here. The point of using an external specification (i.e., a descriptive file) instead of hand-written code is that you can create extremely high-level abstractions that are ideal for the job at hand, and then use those abstractions to "write" your specification.Once you have a suitable specification, then you can begin to weigh the differences between the compile- and run-time methods: By doing the derivation at compile time, you are free to use tools and languages beyond your ultimate target language. For example, even if Java is your target language, you can use Ruby or Haskell to convert your specification into Java. This lets you choose the tools and languages that are best suited for representing powerful abstractions and translating your specifications into code. With run-time derivation, however, you're limited to your target language, even if it's a poor choice for your desired abstractions.
The problem with this thinking is that, if you use run-time derivation, you're more likely to use weaker abstractions in your specifications because you're tempted to constrain your abstractions to those that are easiest to represent in your target language. When you use weaker abstractions, you place a higher burden on the people who must write the specifications, and that burden results in a greater chance for error.Code generation is a practical, efficient tool for solving many problems where OO-style abstraction need not enter the picture. One such class of problems is building interfaces and glue code from external specifications.
A few years ago, I wrote a simple code generator that reads the SQL DDL for a large database and generates an object-based interface to the database. Client coders could then use the object-based interface to access the database. The advantages of this approach proved to be numerous:
- Single, authoritative reference specification.
The object interface was always in sync with the reference, which for
this project was the database schema.
- Richer compile-time error detection. The
projection of the schema into the object interface was fully available
to the type system so that many kinds of client errors could be caught
at compile time, not run time.
- Reduced opportunity for errors between subsystem
boundaries. Because the object-based interface was generated
by machine from the actual database -- and not derived from some
programmer's understanding of the database -- there were
fewer opportunities for impedance mismatch across the boundaries
of the application code and the database. (Studies of errors in
complex projects have shown that errors are more common between
subsystem boundaries, and so this benefit is important.)
mcc further states: If you can't think of any such cases, it's because you're thinking too small. Look at the bigger picture. For starters:- When the number of variables affecting the desired code characteristics
is large enough to make hand-coding (at any level of abstraction)
impractical. E.g., FFTW: "FFTW
uses a code generator to produce highly-optimized routines for
computing small transforms."
- When your code must conform to an external reference specification
that changes rapidly enough to make hand coding (at any level of
abstraction) impractical. (See my example above.)
- When the requirement for correctness is so stringent as to make
hand-coding methods impractical, mandating code generation from
a formal specification.
- When you must target an output language whose native abstraction
capabilities are too crude to capture directly the degree of abstraction
that is merited. Believe it or not, most popular OO languages
fall into this category for many commonly occuring problems. Hence the popularity of design patterns. (Compare, e.g., with the abstraction capabilities of modern
functional programming languages like Haskell and O'Caml.)
Make no mistake about it, code generation is a practical, effective tool that every programmer should understand. To dismiss it out of hand is a costly mistake.It's worth a look, if only for the ideas.
Even if you must wait until Monday to get the OK from the lawyers to post the spec, certainly you can give us something now to give us a feel of dSVG.
How about posting or linking to a few snippets of dSVG code? (Actually, I'm surprised that you didn't include a snippet or two in your original announcement.) Most programmers reading this article will want to see what dSVG code looks like. Throw us a bone!
Cheers,
Tom
Since you have already submitted the spec to the W3C SVG WG, it's already public knowledge, and there's no reason to hide it behind legalese, right? Can't you just provide a link straight to it?
I'm sure a lot of other people are more interested in the spec than anything else. If you want them (and me) to take a look at dSVG, please make the spec available by itself.
Thanks!
So he did the right thing.
And yet, he offers this testimony later:
What went wrong? I'll tell you what went wrong. The author apparently made the choice to go quick and dirty by himself. Instead, he should have forced his managers to make the call: If you want to go that fast, we'll have to cut corners. Are you willing to accept the consequences? Then he could have held them to their decision.If they came back to him later with complaints about quality or his deviation from internal processes, he would have had a sound rebuttal: You told me to cut corners, and that's what I did.
But it's not always that simple. Sometimes it is irresponsible to cut corners, even when your managers direct you to do it. For example, if you're working in an engineering capacity, you have a responsibility to the public to protect their safety and well being. If your boss asks you to cut corners on the software that controls X-ray dosing in medical imaging equipment, your answer must be, No.
Nevertheless, even in this case, the right thing to do is force the managers to make a decision, and hold them to it. I'm sorry, but I can't cut corners. We both have a responsibility to the public here, and so we have no choice but to find another way to meet our timelines. Agreed?
So, to answer the final question:
The answer is simple: It's not your call. Don't make it.In order to break the I/O bottleneck for the mainstream PC, something else is required. Hence PCI Express.
Server hacks like the 66-MHz PCI bus speed and 64-bit-wide PCI are neither practical nor sustainable. That's why we need something different, something like PCI Express. It raises the I/O bar enough to give us another few years of unconstrained growth of the PC architecture.
First, younger programmers have less experience in life. Lacking the well-earned caution of older professionals, they tend to be enthusiastic about their work, which they meet with alacrity. Managers often interpret this enthusiasm as "energy," "speed," and "higher productivity" -- all valuable traits worth seeking an an employee. Even though I know of no measurements or studies to support this interpretation, the perception is widespread, and it's not unreasonable for HR folks to act upon it.
Second, as others have pointed out, younger programmers usually have fewer extracurricular responsibilities to compete with work. Managers see this as increased devotion to the company and the opportunity to get more work for the same money. Again, it's not unreasonable to give preference to people with fewer extracurricular distractions.
Third, in the software industry, experience is rapidly devalued because the valuable mainstream technologies often make one another obsolete. (This is in contrast to, say, the legal profession, where decades-old experience is readily applicable.) While this fact doesn't directly benefit younger programmers, it does put more-experienced (and hence older) programmers at a disadvantage because they are perceived as wanting compensation for their vast, often irrelevant experience. In other words, managers often feel that more-experienced programmers want more pay than they are truly worth.
All of these reasons give managers and HR folks good reason to hire programmers who just happen to be young.
But, there's more to the story
That said, I have been coding for about twenty years. There is no doubt in my mind that the me of today can write much better software than the me of ten years ago, and I can do it in less time. Likewise, when I consider all of the young, hotshot coders who I used to work with when I was a young, hotshot coder, I would rather hire them as they are today than as they were back then. Simply put, they are better coders today.
Back then, we cranked out the code, and our employers loved us. But, being honest, much of that code was crap, and much of our "productivity" was wasted on false starts, gold plating, blind hackery, and all-night debugging sessions that could have been avoided by a more disciplined approach to creating software. The thing is, our managers couldn't tell the difference between fast, furious activity and true productivity. And neither could we.
And that's the most dangerous threat to older, more-experienced software professionals: Lack of measurement. I'm convinced that experienced professionals who have invested in their abilities, made consistent effort to learn from their mistakes, and know how to communicate effectively are worth their weight in gold. In the long haul, they will outpace inexperienced hotshots almost every time.
But without measuring actual performance, you'll never notice. You'll mistake long hours for productivity. You'll mistake unnecessary all-nighters for dedication. And you'll mistake older programmers for expensive versions of their younger counterparts.
So, if you are an older, experienced software professional, stop talking about "ageism". It's a lost cause. Start talking about realisitc productivity measurements. If you want to be perceived as more valuable, you'll have to do it the hard way: You'll have to prove it.
First, did you read the whole story?
The reason I ask is because the original poster made it clear that this was not a collective bargaining situation. This is not a strike. This is not a walk-out. They are not trying to gain anything from the company. They don't want better pay. They don't want better hours. Rather, they want to leave -- for good -- in a way calculated to inflict maximum harm.
Surely, you can see the difference. Right?
Second, are you replying to my response, or some imagined anti-union rant?
The reason I ask is because my response doesn't suggest that the employees shouldn't walk out together, nor does it suggest that they throw away their right to act collectively. It says, rather, that if they do walk out, they should do it as professionals.
Given that they are leaving for good, they have no desire to shock the company into a better bargaining position by an immediate walk-out. Therefore, the only thing the employees could possibly have gained by leaving without notice is the momentary satisfaction of having taken revenge on their employer. As I pointed out, this satisfaction isn't worth the damage it would cause to their reputations.
I think we ought to harness those resources. We ought to use them to teach children those languages that are immensely powerful yet, judged by our standards, too inefficient to be practical. In particular, I'm referring to functional programming languages like Scheme and Haskell.
Now, hear me out.
Why functional programming languages? Because they lend themselves to extremely powerful, mathematical ways of thinking about and solving problems. Learning these ways of thinking when young will benefit our children for the rest of their lives. For example, take a look at the The TeachScheme! Project. I wish something like that was available when I was in High School.
Let us not teach our children the technologies of today but of tomorrow. More and more, I am convinced that functional programming, once considered too computationally inefficient for industry work, will be tomorrow's dominant programming paradigm. No other way of programming so readily lends itself to the formalism that is necessary to manage the ever-increasing complexity of modern software projects.
So, let us give our children the tools they will need to solve the problems of their day. Teach them functional programming.
That doesn't mean you must work overtime in terrible conditions for poor pay. But it does mean, if you decide to take your employment elsewhere, that you leave the company like a professional.
Treat your reputation like a valuable possession -- because it is.
Sorry, but walking out is a "screw-your-employer" gesture. It's about as unprofessional as you can get and, even worse, makes you look vindictive. Is that really the impression you want to leave? Do you really want to trade a good piece of your reputation for a few fleeting moments of take-this-job-and-shove-it jubilation?Be professional. Give two weeks notice.
Like most people, you are probably under an "at will" employment agreement that gives you the right to walk out whenever you please. Don't do it. Give the two weeks, which is universally considered reasonable and comes at no cost to your good reputation.
If you do resign, tender your resignation in writing. Make it simple, polite, and direct -- professional. Something like, "I am writing to inform you of my resignation, effective on date ." That's all you need. Do not
include a grand, barbed explanation of why you're leaving,
which is especially tempting when you feel that your employer has wronged you.
When your employer receives a stack of resignation letters on the same day, they'll get the point. No need for you to draw circles around it or point to it with big red arrows.
Remember: When you leave, do so in a way that makes it clear to your employer that they are losing somebody valuable. Be professional.
Too bad it's not available on DVD. (Yet! I just learned (via IMDB) that this film, released in 1990, is coming to DVD in May. Yipee!)
Nevertheless, it would be better to rewrite the concealed operation so that its running time didn't reveal sensitive information. Having to use delaying tactics imposes a significant response-time penalty, which can be a problem where low latency is desired. But it's nice to know that these concealment techniques are available when it's not possible to change the concealed operation (e.g., when the operation is part of a closed-source library).
For example, in electrical engineering, it is common to simplify complex circuits by breaking them into smaller circuits, analyzing each of the smaller circuits, and then replacing the smaller circuits with appropriate black-box equivalents. With these black boxes in place, the original circuit becomes much easier to understand.
However, as in any modeling exercise, it is crucial to choose appropriate models and to understand the limitations of the models chosen. While a simple resistance model might be a good substitute for DC and low-frequency circuits, it would be inappropriate as a substitute for higher-frequency circuits where capacitance effects come into play.
So, returning to the original poster's questions:
Yes, in these days too much stock is placed in the idea of letting somebody else worry about the complexity. This is especially so in mainstream industry, where one of the key selling points of software development systems is that with Magic DevStationPro X you no longer have to worry about the details but instead just use some brilliant Wizard or API to work at "a higher level." This applies not only to software development but also to user-level domains such as operating systems and applications. For example, a common notion in industry is that by using Microsoft operating systems on servers, administrators no longer need to know how to administer servers; rather, they need only know how to use the GUI administration tools. In other words, the pitch is that you need not concern yourself that the GUI tools present a mere model of the underlying system. Let the model be the system and reap the rewards.That's hogwash. The model approximates the system, no more. In engineering, this is well understood, and I suspect that in good CS programs the same can be said.
Abstraction is a powerful tool. It is widely applicable, effective, and well founded -- when used appropriately. It probably ought to be used more often. Nevertheless, it is not a substitute for rational thought. Nor is it a replacement for being responsible for the entirety of the systems we build.
It would certainly explain some of these problems, but I suspect that far more errors are the result of interface errors. One of the tools that goes with abstraction is composition -- breaking things into pieces, treating the pieces individually (at fine granularity), and combining the pieces (at a larger granularity) to yield a system. The risk of combining pieces is that in order to put them together properly, the boundaries where they coincide -- their interfaces -- must be well understood and compatible. Since the individual pieces make natural units for delegation, pieces are often assigned to different people who may have slightly differing understandings of the boundary conditions. As a result, "interface mismatches" are a significant source of error in software systems.Certainly abstraction plays a role here. Each piece can be thought of as a black-box model. The limitations of that model, and the assumptions under which the model is valid, are certainly important characteristics of the piece's interface with the world. Yet, these characteristics are frequently neglected in documentation and often go uncommunicated across delegation boundaries. This sad fact makes interface mismatches an especially harmful side effect of using abstraction and composition in common software development practice.
Nevertheless, abstraction is a powerful and genuinely useful tool. It is also a necessary tool if we are to build increasingly complex systems. Like any tool, its uses and limitations must be understood if it is to be applied effectively. Thus, getting back to the original poster's question about whether the use of black boxes is harmful, my answer is, No.
The problem isn't abstraction, the problem is improper use of abstraction.
Rather, I suggested that he make a strong ethical argument on the grounds that revealing the necessity of a credit check as a condition of his employment AFTER he and the employer had negotiated the terms of his employment, AFTER they had reached an agreement, and AFTER he had left his previous job, was a flagrant abuse of the negotiation process and showed the employers to be inherently dishonest people -- unless of course, it was all a silly mistake. In which case, they can all forget about the matter and get back to work.
Hogwash! How much is he paid? What is his title? What are his duties? When does he start? Are these not terms of employment?Certainly, he went through some process of interviewing and subsequent negotiations. What caused the negotiations to stop? What caused the employer to say, "Glad to have you aboard. We'll see you next Monday." What caused the new employee to say, "I'm looking forward to it"? An agreement, of course. Even if the agreement wasn't written, it is still an agreement. Even if it isn't legally binding, it was still an agreement.
And the employers know it. That's the thrust of my argument. Unless the employers are truly dishonest people, they will recognize that springing a make-or-break condition of employment on a new hire after he and they have already come to an agreement was, is, and always shall be a breach of the honesty and good faith that underly any negotiation process. Once the new hire makes this clear and asserts his willingness to make a stand on it, the employers must either agree with him that the whole matter was a regrettable mistake, best forgotten, or live with the stigma of being publicly branded as a lying bunch of weasels.
My hunch is that most corporate folk would choose to forget about it.
This is immaterial to my argument. It's not a matter of legalese but people politics. It just so happens that our protagonist is aligned with the forces of Good on this one, and he can use it to his advantage. Legal strategy need not enter consideration.If I were in your shoes, I would say no, politely and firmly:
If they didn't let the issue drop, I would talk to a qualified attorney. Pursuing the matter would probably irreparably damage your relationship with your new employer. But, then again, if they really pulled something this weaselly, maybe they aren't the good employers you thought they were when you signed on.
Remember, the DMCA's (overly reaching) powers are granted to the copyright holder who tries to protect his own works by placing technological barriers around them. In your example, an office-software vendor tried to place technological barriers around works that they did not own. The DMCA does not apply.