[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 6502 illegal opcodes questions



Michael J. Mahon wrote:

> Of course there is a need for higher levels of abstraction.
>
> But much of the discussion here has been driven by "strongly typed"
> and "restricted" languages and semantics vs. "weakly typed" and
> unrestricted (nonportable) languages.

And much of the argument against being that strongly typed yields
inefficiency, a point I strongly disagree with.

> The presumed superiority of the former is that it either:
> 1) makes it harder to do bad things accidentally,
> 2) makes it harder to do bad things intentionally,
> 3) makes it easier to do good things accidentally, or
> 4) makes it easier to do good things intentionally.
>
> I note that 1) and 3) (the unintentional flavors) can be readily
> supported, and can be construed as support for relative newbies.

Not just newbies, though. Plenty of good programmers have used
techniques that over time have proven to be problematic. Some of them
realise the problems and stop using the techniques, some of them don't.
It's common to end up in a heated discussion with a  fine engineer who
doesn't want to change an obviously flawed approach because they cannot
see the future benefits of doing so.

> It is much more difficult to make a case for 2), since intention
> knows no bounds, and I think we have all seen cases where the
> finest language has been horribly abused.

Can't argue with that. It's certainly possible in any environment to
exploit it horribly. It's true though that as the level of 3) goes up,
the frequency of 2) goes down. You're much less likely to try hard to
do do something that has an obvious easy way.

But then, it certainly does happen ;-)

> It is certainly possible to write non-portable code in any sufficiently
> complex system, simply by exploiting some irregular behavior--and there
> will *always* be some irregular behavior to be exploited.  ;-)

The hardest part of the problem, and one yet unsolved by language
design.

A classic source of behavoral irregularity is in module initialisation.
You frequently situations where a module is initialised according to
it's documentation, only to find out you didn't do it exactly right,
and ended up depending on some non-determined default within the
module, and later version break your system. Regardless of the level of
typing involved, this one can surface. It's a current topic of research
to figure out solutions to this issue.

> It is also possible to write spaghetti code in any language, if
> only by writing it as a state sequencer in a looped case statement.

This is actually one of the best examples of where language design
falls down, and it's often construed that you need to rely on
old-school constructs to build efficient state machines. While this is
essentially false, I'd like to see better language support for state
machines in the first place. It's odd that such a fundamental facet of
computer science has such poor abstractions in place around it.

> Case 4) is the most interesting, since it offers the real possibility
> of improvment by raising the level of abstraction.  It is worth noting,
> though, that most abstractions employed in more modern languages were
> developed by designers working in less restrictive languages, doing
> explicitly what was later encapsulated implicitly.
>
> Therefore, a less abstract language, far from preventing a good designer
> from doing beautiful abstractions, actually provides the medium for the
> abstractions to be created and prove their worth.  It remains to be seen
> whether abstract languages like Java will similarly give birth to new
> levels of abstraction "beyond objects".

Design Patterns is an excellent example post-object abstraction. While
there's a lot of hype around the concept the original text, entitled
"Design Patterns" is an interesting read. Essentially, the authors
studied the code of several large "successful" systems built in OO
languages, and discovered many recurring patterns which they distilled
into generic descriptions and templates as solutions to commonly
recurring problems.

If you've heard OO programmers uttering terms like Singleton, Facade,
Builder, Adaptor, this is where these terms come from. It's evolved
into a 'language' for developers to talk about complex design ideas.
For the moment, it's a language for humans rather than machines, but
it's only a matter of time.

> If it were not for languages with explicit pointers, all our current
> "object oriented" languages would never have come to be.  The first
> such programs were written in assembly language, and were far more
> versatile and efficient in their realm than comparable programs
> written today.  (Sutherland's Sketchpad comes immediately to mind.)

Sure. It's worth pointing out though that explicit pointers aren't
necessary to achieve efficient designs, just as, on 32 bit platforms
anyway, there's no need to write position dependant code. If you're
targetting a 6502 or even 68000, you have to make some compromises, but
those restrictions simply no longer exist, and the need for techniques
that allow for the restrictions are gone with them.

As we've discussed, it's possible to write portable code in languages
like C, provided you're *very* careful. Good designers can achieve
this, and not compromise efficiency either. The obvious point is
though, what can the good designer achieve if he doesn't have to expend
unnecessary energies being conscious of issues that can be solved by
language design?

> Further, though abstraction is essential, the best designers are
> characterized by a much wider "abstraction bandwidth" than is
> common, and their ability to span many levels of abstraction in
> their thought is what allows them to create *efficient* designs,
> rather than just "correct" designs.  (BTW, designers with "high
> bandwidth" are always in short supply, and much of todays software
> reflects their absence.)

I agree. I do believe though that such designers achieve more with
better languages and tools.

> I have been frequently appalled to find that *system* programmers
> working at the lowest levels of OS design are often almost completly
> ignorant of the *machine* implications of the code that they write.

And this is a problem that's only getting worse. You can only fit so
much teaching into a 3-4 year degree, so many core concepts are being
removed from curriculums as it's considered important for a graduate to
have current skills.

> There is *no* substitute for a low-level understanding of what is
> actually going on in a system.  Unfortunately, higher level tools tend
> to further obscure actual system behavior by making it more "esoteric".

I agree. I feel it's a problem we'll never really solve, only mitigate.
higher level tools certainly do eliminate the need for a lot of
low-level understanding, but as your example illustrates, it's when the
problems arise that low-level understanding is necessary.

One has to ask though what an inexperienced developer was doing writing
process scheduler code!

> > Been there too. Time has proven it doesn't work well, and that test
> > driven development techniques provide more safety, and allow more
> > flexible forms of expression in the process, easing chafing.
>
> No argument here--test scaffolds have proven their worth many times
> over, yet their adoption as a standard part of any development has
> been widely rejected.  Maybe we're past that now...

A couple of fairly important tools, Ant (Essentially a portable "make"
on steroids) and JUnit (A Unit testing framework) have become massively
popular in the Java development arena, along with the phrase
"continuous integration", which more or less implies having a fully
automated build/test/deploy framework, to the extent that a machine on
the network checks out the code repository with each commit, builds it,
runs the entire test harness, and emails the person responsible for
violating a test case, should that occur.

The difference that this methodology has made to system quality (not
necessarily code quality) and development time is difficult to describe
in words.

One of the nicer side effects is it tends to free developers from the
'fear' that they might break something if they decide to make
relatively major change, since they can easily validate the system.
This has given rise to a practice known as refactoring, which good
developers did anyway, but now has been formalised to the extent that a
much larger segment of the developer community have embraced it.

> You know, I fundamentally agree with your point.  But I am sobered by
> the realization that 90% of the software we are talking about is code
> to download music or animate the "bounce" in a cursor bar.
>
> The fundamentally inessential and, at most, transient importance of the
> vase majority of code that is written, constrasted with the much smaller
> amount of truly essential, even critical, code, makes the argument for
> armies of "average" coders much less relevant.

This is true. But then, the 'commercial world' or more precisely, the
world where software itself is an end product is only one segment of
our industry, and I share your disdain for it. Trash will be trash
regardless of tools.

> The truth is that very little code needs to be really good.  If it's
> just 2% of all the code written, then it could all be done by 98th
> percentile people.  And, frankly, I don't really care whether the other
> 98% of code is written well, or even written at all.

I agree for the most part, but there's still a lot of code out there I
consider essential that's utter crap. Web Browsers are a good example.

> It reminds me of "Sturgeon's Law".  When, at a cocktail party, Theodore
> Sturgeon was asked what he did, he replied, "I write science fiction."
> The response was, "Science fiction!  90% of science fiction is crap!"
> To which Sturgeon replied, "Sir, 90% of *everything* is crap."

I'm a fan of this law too :-)

> So there is no real shortage of good designers, just a poor system of
> allocating them to projects.  Almost 90% of them are working on crap!

Michael, I hope you're right :-)

> It is a frequently stated goal of language designers to make bad things
> harder and good things easier.  What has never been studied is whether
> these tools actually improve the productivity and quality of output of
> the 2% of *great* programmers, on whom we all ultimately depend.
>
> Most programmer productivity (not to be confused with quality, but not
> unrelated) studies have shown *much* greater variance (50:1!) is
> attributed to individuals rather than to the tools they use.  My own
> experience supports this finding.  (BTW, "programmer productivity"
> has nothing to do with "lines of code" but with "problems solved".)

I have but my own experience to go on, but I've observed in my own work
that using more sophisticated tools has made me more productive.
There's solutions I can build in days using something like Java that
would takes weeks in C. Would the resultant C system be any better? I'd
have to say no, not likely.

Perhaps this puts me in the category of not being a good developer, but
if that's the case so be it ;-)

> I can appreciate an editor that pops up the full procedure interface
> for me as soon as I type a half-dozen characters of its name, but I
> note that it facilitates calling the *wrong* procedure as well as the
> right one.  I'm glad that it lets *me* choose.  ;-)

Ironcally, now that I'm using Ruby more and Java less, I'm finding
myself using a good old  fashioned text editor (the language is too
dynamic to allow a lot of autocompletion). I actually don't miss the
fancy IDE all that much.

> Actually, I was talking about the 8MB of code--most of it *not* within
> the Hellow World application--that will be executed in the act of
> painting "Hello, World!" on the screen.  The 8MB of libraries embedded
> in a trivial application are a separate issue (to which there are well
> known but seldom applied solutions).

I think this is a very overstated point - I can't really comment on
exactly how much code get's executed in order for a Java program to
push Hello World out stdout, but I'm pretty sure it's a lot less than
8mb ;-)

> > It's not ideal, but what's the alternative? If you don't follow this
> > road, a cap is placed on the possible solutions you can build. The
> > overheads introduced by high level abstraction systems is a very
> > interesting field of research, and one that great inroads into managing
> > has been made.
>
> I have no problem with the upper two or three "layers" being rather
> loosely bound--after all they are, or should be, in flux.
>
> My issue is with the dozen levels beneath these, which have not changed
> for a decade, and are much in need of collapsing into a much more
> efficient and, yes, less portable structure.  (BTW, have you noticed
> the steadily decreasing value of architectural portability?  ;-)

After 5 years of Java development I've not needed to worry :-) Besides
OS portability is very important these days, and while were only really
dealing with 2 or 3 machine architectures now, it's still an issue.

A good example is Linux, which needs no 'collapsing'. I'm fond of the
KISS principle when it comes to OS design though.

> Code which is executed many times per day by tens of millions of people
> can be justifiably optimized, since it will save *huge* amounts of human
> and machine resources to do so.

Can somebody send this to the developers of Microsoft Office 2003 ? :-)

> > I can see a time when massive parallel computing clusters 'churn'
> > through algorithms, fitting them to particular machines are problem
> > domains. Programming done by the human will be not much more than
> > assembling from vast libraries of prevalidated solutions. It doesn't
> > take much thinking into the future to imagine a time when software
> > complexity is so high that this is the only feasible solution to
> > building more complex systems.
>
> I remain radically suspicious of any approach that minimizes the
> fundamental role of conscious design--unless we plan to use genetic
> algorithms to evolve programs.  (I'm not entirely kidding here, but
> this is clearly not "around the corner".)

My point is that the tools *should* allow the humans to focus on
conscious design, spending less effort on fiddly details that should be
inconsequential today. This is one of the big issues with current
languages, to lesser and greater extents depending on which one we
choose to discuss.

> In this area, the fundamental limiters I see are complexity (human
> limiter), resources (human and machine limiters), and performance
> (machine limiter).
>
> I expect tools to help manage complexity, as you do, but I also
> require tools to manage human and machine resources, and machine
> performance.  In the (related) areas of resources and performance,
> tools can be used to help visualize usage so that a designer can
> make better informed tradeoffs.
>
> I am quite disappointed with the relatively poor quality of tools
> to correlate system design choiced (like class structures) with
> real system metrics, like memory resources and performance.  As
> we move into more concurrent systems, measures of locality will
> be extremely important, and remain largely unaddressed in the
> current generation of tools.

I think for the most part we agree on these issues - the tools you
invisage are much the same as the ones I do. Going a step further, once
we have tools that can gather such metrics, it's likely that the
techniques people will use to examine them and then 'tune' will be
disciplined enough that a large degree of automation will be possible.

> In the not too distant future, we will be able to treat today's large,
> "nonportable" bodies of code, together with the behavioral spec of the
> systems they run on, as a "source language" from which we will be able
> to compile a program with equivalent behavior on any system we choose.

I agree that this will happen too, but it's far enough away that we
have to make do with intermediate solutions in the mean time. Many,
many years of compiler research stands in the way of such things.
Meanwhile people are still arguing that compiler research done in the
1960's and 70's, such as using p-code machines as intermediate forms
along the path to better optimised solutions are a bad idea! Too
inefficient they say. For the most part, this is baloney. I tire of
issues that have been solved *years* ago continually being touted as
reasons to not move forward.

> The real problem with legacy applications is that we need them to
> continue to behave *exactly* the same, to avoid compatibility ripples.
>
> The best way forward has always been not to "port" legacy apps, but to
> *replace* them entirely with new subsystems, supporting new functions.

Indeed! Which is why I advocate moving to newer systems, like VMs! It's
the 'newer' systems that encourage reuse of legacy subsystems that
should be thrown in the trash that I dislike.

> The practical useful lifetime for code is measured in the cost of
> human change, not machine change, so having practical portablity
> may turn out to obstruct rather than expedite the move to a truly
> better solution.

Hmm. A decade of industry success to Java indicates that this is
probably not the case.

I'm reminded of the early 1990's when John Carmack announced that DOOM
would be written completely in C using cross compilers (they used NeXT
workstations). He was scoffed at by industry types at the time that
believed you couldn't write a game that pushed PC hardware to it's
absolute limits without hand-tuned assembly routines in the critical
sections. DOOM came along, and a lot of people ate humble pie.

More recently, John announced that ID's next 3D engine would probably
be written in Java. Again he is scoffed. I'm personally looking forward
to the pie eating that will most likely ensue :-)

Matt