Friday, December 26, 2008

Coding War Story - Sometimes You Just Have to be Facing the Right Direction

Sometimes seeing something flicker out of the corner of your eye turns out to be the key to tracking down a bug.

One Monday morning I came in and saw that one of the processes in the missile command & control (C2) system our team was developing had crashed, throwing up an exception traceback. This system ran across several rack-mounted workstations when it was deployed. However, it also functioned just fine on a single workstation, which simplified the development tasks for the developers. It was not uncommon for me to leave it running on my workstation overnight or over the weekend so that I could just pick up again when I came in the next morning. Since the system had been idle for hours, and had been fine when I left for the weekend it was a little puzzling that it would spontaneously crash like that. The first thing that pops into mind is some kind of memory exhaustion, but when I looked at the state of the system, and where the traceback showed the crash occurring, it didn't look to be memory, nor was there any other readily apparent cause.

When this system was idling, it was pretty much literally idling. I'll get into some of the details in a bit, but basically in the idle state all the threads are suspended waiting to be notified of there being something to do. And since there was no command and control activity going on on my workstation over the weekend, everything should have just stayed quietly suspended.

And the other odd thing was what the traceback indicated. A subprogram had been invoked that went and retrieved some data for processing, and since there was no data for processing--the system was idle and had been for hours--it started trying to process garbage and just crashed out. And the weird thing was that there was no rational explanation for why that subprogram chain got invoked. It was called only when a specific message had come in, and there was no record in the logs of that having occurred, nor was there any reason to transmit that message when the system was idle.

This is not what we were working on, but it kinda looks like itI tasked one of the developer to go off and see what he could track down, and some time later he came back, just as puzzled as I was about the cause.

So we let it go for the time being, and other than letting the system run overnight (and the problem didn't repeat), chalked it up at the time as just one of those intermittent bugs that would hopefully manifest itself more helpfully later.

Time goes by, and more development happens.

One of the other developers comes to me and asks for help in finding out why the system crashed on their desktop workstation. It had been simply idling and they could find no clear reason why a particular sequence of subprograms calls had been made that led to the exception being raised that crashed it out.

This was familiar, but again we could find no reason for the idle system to crash out like this.

More weeks go by.

This system did a lot of detailed logging of what it was doing, so a common practice amongst the developers was to "tail -f" one or more of its logs while the system was running so as to get some immediate feedback about what was going on under the hood as the developer checked out their changes.

I was doing a code review or something at my desk when I noticed something flicker over on my workstation monitor. I hadn't yet written any code or done any testing that day, so everything should've been quietly idling. Looking at the monitor to see what had just happened I saw it--the exception traceback and crash had just happened, which took down the process that was running in its own window, and recorded some tracing in the logfile I happened to be tailing.

This time I noticed something about the freshly logged entries, versus those that immediately preceded it: the timestamps differed by one day and a fraction of a second.

That was suggestive.

Now this C2 system was written in Ada, and I'd been working with that programming language for around 15 years by this time. So I knew the language REALLY well. And also over that interval I'd gained a deep understanding of the runtime environments (RTEs) within which Ada programs executed. It's not that I explicitly set out to learn about the Ada RTE, but over years of development and debugging you just absorb information about data formats, layouts, byte boundaries, thread suspension, scheduling, resumption policies, etc.

So when I saw that there had been a nearly exact 24-hour interval between the last nominal log message and the crash, the first connection I made in my mind was to the Alsys Ada Duration type. Why that type? Well, Duration is a predefined Ada type used to represent time, in the form of seconds and fractions thereof.

Now for those unfamiliar with the Ada programming language, Ada is a strongly typed programming language that allow programmers to define application-specific types, both composite (records, arrays) and scalar (integer-based, float-based, character, and enumeration). And for scalar type definitions, one can specify its range and, in the case of real types, precision.

The Ada 83 programming standard does not specify a range and precision for the Duration type, those were left to the implementor to make common-sense choices appropriate to the hardware/OS being targeted by the compiler.

While I don't recall the precision specification, I do know that Alsys Ada running under HP-UX predefined the Duration type to have a range of 0.0 .. 86400.0, i.e. 24 hours. And that was the only place I knew of in the Alsys Ada RTE that had a direct association with a 24-hour time period.

So how exactly could Duration's 24 hour type definition be related to this crash? Well, there was no clear and obvious relationship, there were no delays or anything going in the vicinity of the code where the crash sequence appeared to initiate.

But, once again, there was another connection to be made.

Duration is closely associated with Ada's tasking functionality, in fact they're both covered in the same chapter of the Ada Language Reference Manual. And tasking did play a significant role in this C2 system.

Tasks are Ada's built-in concurrency constructs, and are conceptually rather similarly to threads. Rather then employing a separate library of functions or classes for implementing parallelism, Ada's concurrency features are built in to the language itself. Nowadays most Ada compiler implementations implement tasking on top of the native OS or VM threads, but there's no requirement that they do that. The semantics of Ada tasking specified by the standard usually don't match up exactly with the thread primitives provided by an OS, so the vendor may just let the differences slide if the inconsistencies are minor or trivial. Or, a vendor (or third party) can create a tasking RTE that manages all tasks completely on its own, with no reliance on any underlying OS thread capabilities. There are pros and cons to system-supplied versus vendor-created tasking/threading approaches, but especially with the state of compiler and threading technology in the early days of Ada, having the tasking implementation totally under the vendor's control could usually be justified in order to reliably get the right tasking behavior. And that's what Alsys Ada did.

A task that is going to communicate with other tasks, including the main program, does so via "entries", which specify a name and parameters for the data that is to be exchanged. The actual language statement that receives an entry invocation is the "accept" statement. So if you had a task, like Command_Processor, that had an entry "Receive_Command", you would see this somewhere in the task:

accept Receive_Command(Command_Buffer : Buffer_Type) do
-- Extract the command data to a local buffer before processing
... statements ...
end Receive_Command;

When the thread of control within the task hits such an accept statement, task execution is suspended and blocked. And it stays blocked until a call is made on that entry. The task will stay blocked even if the main program is ready to exit. Ada requires that until all tasks are terminated the program cannot perform a normal exit.

If a task needs multiple entries so that is able to perform multiple functions (including being explicitly told to terminate), the "select" statement is used to block the task until any one of multiple entries is invoked. For example:

accept Receive_Command(Command_Buffer : Buffer_Type) do
-- Extract the command data to a local buffer before processing
... statements ...
end Receive_Command;
accept Shutdown_System;
end select;

Now this task is suspended and blocked waiting for either of its two entries to be called. (And note in the latter accept statement that there need be no parameters if no data is to be exchanged, and no body of statements to execute while the task rendezvous is occurring--a call to an entry defined like this is effectively simply a notification that the task can exit the select statement and resume executing at the first statement following the select.)

Now while there's nothing wrong with this form of select statement usage in a task, it is a bit of an atypical usage of Ada's tasking idiom. The reason for that is that it provides no way to shut itself down when the main program is ready to exit. The task with this select statement is going to remain suspended until one of those two entries is invoked, and it wouldn't have mattered whether that second one was named Shutdown_System or "Queue_Message", to the enclosing task they're all simply entries to wait on.

So the typical composition of a select statement in a task includes a "terminate" alternative:

accept Receive_Command(Command_Buffer : Buffer_Type) do
-- Extract the command data to a local buffer before processing
... statements ...
end Receive_Command;
accept Shutdown_System;
end select;

Terminate is an Ada reserved word that in the context of a select statement terminates its enclosing task if the entire application is attempting to perform a normal exit. Thus there's no requirement that either of the entries be explicitly called in order to terminate the task and accomplish a program exit.

There are two alternatives to the "terminate alternative" that can be employed: The delay alternative and the conditional alternative. The delay alternative, which looks like:

accept Receive_Command(Command_Buffer : Buffer_Type) do
-- Extract the command data to a local buffer before processing
... statements ...
end Receive_Command;
accept Shutdown_System;
delay Time_To_Wait;
end select;

causes the select statement, after the delay interval has elapsed, to stop waiting for any entry calls, unblock task execution, and continue execution after the select statement. The delay expression can either be a literal, like 2.0, or a variable of type...Duration.

The other option is an "else clause" in the select statement, which means that if upon hitting the select statement there's no invocations pending on any of the accept alternatives that execution should go right into the sequence of statements that follow the "else".

Now the thing is that any one select statement can contain only one of these three alternatives: terminate, delay, or conditional. (I'm sure there's a very good reason for this, but I've never dug into the rationale.) This means that if you have a select statement enclosed in a loop that is supposed to cycle every so often--based on the delay expression--that you need to have an explicit way to shut down the task, because you're not allowed to have a terminate alternative to do it for you. Also, if your task holds system resources that need to be explicitly closed/released, you don't want to use the terminate alternative, because that just directly shuts down the task on program exit, with no opportunity within that task to release the resources.

So what what was in it in our problematic C2 system that was triggering a subprogram invocation from a task that was supposed to be blocked on a select statement?

Studying the code I saw that the select statement in the task was of that first, rather atypical select/accept style, i.e. just selecting on entry accept statements, there was no delay, terminate, or conditional alternative. It was written that way because that task held resources that were best explicitly released by the task itself, hence the terminate alternative was out; there was no reason for any kind of timeout, so no delay alternative was provided; nor was there any reason for a conditional alternative.

Since this was an uncommon form for a select statement, and 24-hour intervals of total inactivity are also rather unusual for a C2 software system, I decided to try something. I wrapped the select statement in a loop and added a delay alternative:

accept Receive_Command(Command_Buffer : Buffer_Type) do
-- Extract the command data to a local buffer before processing
... statements ...
end Receive_Command;
accept Shutdown_System;
delay Duration'Last - 10.0;

end select;
end loop;

Basically I just told the select statement to timeout after 23 hours, 59 minutes, and 50 seconds had elapsed. Once it did it would simply abort the select then loop back up and reinitiate it. Now there were two other instances of this particular select statement usage in the system, but I left them unchanged as a control.

I rebuilt the system, kicked it off, waited for it to go idle, noted the time, and went off and did some other stuff for the rest of the day.

Came back the next day, and waited for the 24 hours of idle time to elapse. The time approached, and I got a crash and traceback--but this time a different subprogram chain had gotten invoked, which it was quick to verify had originated from one of the unmodified control select statements. I changed both of the remaining select statements to the same loop/delay composition, and started it off again.

Work, go home, come back to work, blah blah... 24 hours. Nothin'. No crash, no traceback, everything just kept idling. I ran through a verification scenario and everything performed just fine.

So that was it, somehow that particular "select/accept/no alternatives" sequence could not stand being suspended for 24 hours. Maybe it had something to do with the range definition of the Duration type, and maybe not, I never knew for sure, since Alsys Ada was almost an orphaned product by then, and support was pretty much negligible.

We let the other co-contractors know about this issue, since it is not impossible, or even improbable, that a C2 system would sit idle for many hours, and the last thing you want in a time and place of elevated tensions is for one of your missile command & control systems to abruptly crash on you, when it had been running just fine for hours!

Y'know, if I hadn't happened to be facing in the general direction of the monitor when that crash happened I might never have noticed it. It would've been easy for me to have an updated build ready to test, and so simply blindly terminated the current run without even noticing its state before doing so. But one little flicker of movement seen out of the corner of my eye caught my attention, and years of experience with the language and its RTE guided me right down the path to tracing it to a vendor bug, and instituting a work-around before it ever came near to being deployed.

Thursday, December 4, 2008

Snow in the Higher Elevations

We got a little bit of snow here in North Alabama a couple days ago. Though it snowed around much of the area, the weather forecasters said it might amount to something only in the higher elevations.

Well, I can see the higher elevations from my front porch, and they were right:

The elevation of that ridge is about a thousand feet above my house, so it looks to me that about the top 100-200 feet of it were high enough to hold the snow for the day.

Saturday, November 15, 2008

The Chirp Song (Lyrics)

When you're out in the woods
And you've lost your way.
And the trials and tribulations of the day
Lift your fingers to your pits...
Raise your elbows high...
Open up your mouth
CHIRP! your blues away...
NIGHT...will turn to day...
IT'S...the only way...
CHIRP! (chirp)
CHIRP! (chirp)

Pardon this regression back to my youthful sing-a-longs.

(Corresponding participatory movements are left to your imagination.)

Monday, November 10, 2008

Restoring the Integrity of America

Obama Planning US Trials for Guantanamo Detainees - TIME: "'In reality and symbolically, the idea that we have people in legal black holes is an extremely serious black mark,' Tribe said. 'It has to be dealt with.'"

Thank God.

And how those individuals that professed to be born-again Christians--and I grew up as one--could defend and justify torture and imprisonment without trial I find absolutely unfathomable.

What part of Matthew 7:12...

"do to others what you would have them do to you"

and Matthew 5:44...

"love your enemies, and pray for those who persecute you"

justifies this:

A lot of Christians are going to have some serious shit to answer for on Judgment Day.

Friday, November 7, 2008

Tuning out the Right Wing Noise Machine

One side effect of the Obama administration that I'm looking forward to is that I can finally stop paying any significant attention to the hard-core right wing's bloviating. Hannity, O'Reilly, Fox News in general, Limbaugh, Hewitt, etc. have their agenda, and unfortunately because for the last two decades there have been politicians wielding real power in Congress and the Presidency that supported that agenda, one had to keep up with it if you wanted to oppose it. They couldn't be ignored--"know your enemy" and all that.

Even with the Democratic takeover of Congress in 2006 there was still a Conservative president vetoing, and sufficient GOP Senate representation to threaten filibusters over anything that attempted to roll back the accomplished parts of the agenda. (This is why nothing got done in Congress for the last two years--classic gridlock.)

Now, though, with Obama soon to take office, the gridlock breaks. While the GOP can still filibuster, that's the only weapon they've got left, and they just ain't going to be able to wield it every time they don't like something.

The key point, then, is that there's no longer any political muscle left for pushing through the conservative agenda, nor to stop it from being rolled back as needed. And while Hannity/Limbaugh/Hewitt will continue blaring the tune, there's no longer anyone there to dance.

And what with the GOP and conservative right manning up their circular firing squads, ejecting those that fail the purity test from the movement left and right, the whole conservative movement is becoming irrelevant. This means I no longer have to pay any attention to them, because they're ineffectual. (Fox News is even starting to eat itself.)

Now here's the thing though, in my book anyway. I prefer a strong, "loyal opposition" to the party in charge. It keeps everybody sharp, and smart, and keeps things from getting too far out of hand.

"Iron sharpens iron, so one man sharpens another." Proverbs 27:17

The GOP needs to get their act back together, sooner rather than later, though I'm seeing no evidence that that's going to happen for awhile.

In the meantime, though, I can drop Fox News from my TV channel listings and remove the spit guards protecting my car radio, and watch and support the adults trying to get some real work done.

Wednesday, November 5, 2008

An old, staticky guy does Python

For my entire 25+ year software development career I've used statically (and strongly to varying degrees) typed programming languages: Pascal, Modula-2, Ada, C, C++, and Java. I knew I needed to get some exposure to the current up-and-comer's--or pretty-much-already-here's--and so I decided to try Python.

The experience has been enjoyable, but there have been dubious aspects to it.

Definitely on the good side is the inclusion of lists, dictionaries, and tuples as first-class constructs within the language. It is an unalloyed joy to have these constructs available to the programmer as built-in, highly capable features of the language. I can't say enough good things about them. In the last few years I've become a great fan of maps/dictionaries as a fundamental approach to solving a variety of software development issues, and Python's comprehensive support for these and related constructs simplifies so many things.

List comprehensions are another valuable member of the Python toolkit. As I came up to speed with them I was reminded of Fortran's "Implied Do Loop" that I learned about way back in my college computer science classes.

List comprehensions are certainly a very powerful language feature for constructing kernels of concise, effective code.

The personal project I chose to implement using Python was a configuration file builder for which I wanted a graphical user interface. Having a fair amount of past experience with GTK+, I decided to go with PyGTK. This worked out very well. The integration of GTK with Python is extremely well-done, very flexible and easy to use. Many of the issues I had to deal with in the past regarding transferring information between the core app and the GTK API pertaining to data formatting and management just aren't there. Definite kudos to the PyGTK team. So Python and (Py)GTK is a Big Win in my book.

Now although this is rather a minor feature of Python, I've found the ability to return multiple results from a function extraordinarily valuable as it eliminates the need to define and manage parameters that are used for nothing more than passing back two or more results that are produced within a method.

I've done very little with the functional programming features of Python, other than lifting some quick little functions from tutorials or examples that I've needed to do some special-purpose task, like simple filtering. I know the functional programming features are very powerful, and from reading up on them I can certainly see their use, so I look forward to investigating exploiting them in the near future.

Now here's the part where I've yet to see the value.

Dynamic typing.

AIEIEE!! Not the static vs dynamic typing argument!!

I won't get into a full-blown argument, just going to point out where this keeps biting me, which causes me to question whether its value is worth the cost. (And keep in mind that I come from a hard-core strong/static typing background--Ada--so that obviously distorts my perspective :-)

The benefits of dynamic typing seem to revolve around the programmer not having to worry about types, therefore compilation and link errors are reduced so one can get to executing code faster, that when there's a bug manifesting itself during run-time there's more info available for debugging, it's easier to change types to adapt to changing requirements, and you get things like late binding and duck typing.

Okay, those are all true, but a) my code blows up a lot more often, and b) with no explicit type information in the code finding out why it's blowing up takes time, where with static typing the damn thing wouldn't have compiled in the first place--and therefore not have blowed up real good at all.

Here's a method spec:

def setupEventDefinitionsList(self, availableLogEntries,
availableEventDefinitions, eventLogEntries,
eventPrereqEvent, eventEntries, eventNames):

Some of these parameters are dictionaries, some are lists, some are class instances. Which are which? If I change the implementation of this method such that, say, eventLogEntries, is now a dictionary, I won't know that I possibly missed making the corresponding adjustment to the argument in an invoking method until I actually execute that method. Which, if the caller is in a little-used part of the application, could be a long time coming.

Similarly, if I haven't looked at this code for six months, how do I quickly refresh myself with what each of these parameters is, and is for? Maybe I was a conscientious programmer and documented each parameter, but maybe not (and comments tend to rot anyway). If in a new app I want to call this function I can't just look at the signature and tell in what form I need to provide the arguments, I have to review the code itself, either in the body of the method or in others callers, so as to derive what type of argument is expected.

Versus putting my cursor on the type indicator and right-clicking "Show declaration".

function Create_Source_Stream
(Format_Kind : File_Format.File_Format_Kinds;
Filename : String;
Timestamp : Timestamps.Time_Formats;
Timestamp_Kind : Timestamps.Time_Kinds;
Supplementary_Data : Supplementary_Generator_Info)
return Log_Source_Streams.Log_Source_Ref;

Maybe it's simply a matter that I'm not yet thinking "Pythonic" enough, and that with more experience in the language the benefits of dynamic typing will become more obvious to me. Maybe I've not yet immersed myself deeply enough in the language that dynamic typing reveals itself as being critical to certain software development practices. I don't know, for me the jury is still out on this aspect of Python, and so most likely for the rest of the dynamically typed languages.

There's certainly enough clearly beneficial strengths to Python that I will continue to use it for various projects, as I mentioned above it's been very pleasant to use for creating my configuration file builder.

For the really hard-core, more expansive projects though, I'm going to be sticking with Ada or other strongly/statically typed languages (yes, not least because I know them very well) because I find tracking down type-mismatch problems occurring during run-time that could've been trivially caught at compile time very tedious.

Monday, November 3, 2008

Whoof. <snap> <crack>

That's the sound of 62+ million Americans (and hundreds of millions of people around the world) releasing the breath they've been holding, and uncrossing fingers and toes as Barack Obama is projected to be the next President of the United States.

"[I]n no other country on Earth is my story even possible."

"In the unlikely story that is America, there has never been anything false about hope."

Thank you, Barack Obama, for inspiring and leading Americans to take back their country.

It's time to start.

Bi-polar Nation

So within 36-48 hours we'll hopefully know who the next President of the United States will be.

Americans' reactions reactions will likely be split amongst:

Case 1: Huge relief/Inconceivability (with a smattering of gobsmacked)
Case 2: Crushing depression/Whooping

Sunday, November 2, 2008

Spewing for the sake of spewing


Not me, the political campaigns.

I just get this sense during the last week or so of campaign season, when all the negative advertising goes into overdrive with smears, ridiculous distortions, and bald-faced lies based on out-of-context quotes, that it's not really about convincing the remaining "undecideds" any more.

Setting aside the presidential race for a moment, I'm seeing laughably over-the-top attack ads amongst the HR candidates, judicial contests (yes, in Alabama judges are elected, which I think is stupid), and others. Many of these ads are so "out there" that they're not going to be taken seriously by (meaning, influence) anybody.

So it seems to me that this is just spewing vitriol because campaigns just don't know what else to do: they're wired up, tired, angry at having to actually compete against this putz, and so just end up with this visceral need to yell, scream, and throw shit at their opponent.

Maybe it makes the campaign feel good--though tantrums have a tendency to be self-reinforcing--but it just stinks to the rest of us.


Thursday, October 23, 2008

Mr. Lindstrom Drives Off Into the Sunset

Glen Lindstrom, er... MR. Lindstrom, was my high school driving instructor. He had kind of a quirky personality, was very forthright, and pretty much fearless -- which I expect comes in handy for high school student driving instructors. Literally the first time I drove a car, with him in the passenger seat and ready on his set of Driving Instructor Brakes (tm), he had me head out and drive on the freeway! That was the only time I did that during the driving instruction course, everything else was driving around my home town's residential streets, with lots of parallel parking practice. When it finally came time to take my written and driving exams, he was there and was very interested in how I and the other student taking her exam at the same time did. (I got an 87 on the written and 88 driving, I believe you needed 80 to pass).

In checking the obituaries in my home town newspaper on the web, I see that Mr. Lindstrom passed away.

This photo pretty much does him justice, he looks pretty much as I remember him from 30 years ago (though I don't know when this one was actually taken).

What I just learned now, though, from reading his obituary, was that he served in World War 2 on the battleship USS Alabama, which happens to a) be the name of the state in which I now reside (the "Alabama" part) and b) anchors an exhibit a few hours down the road from me in Mobile. The Alabama was quite active in the Pacific theater, and Mr. Lindstrom got his share of medals as a crewman in these campaigns.

He was a good man, worked hard to make his students good drivers, and while his quirkiness sometimes resulted in students making fun of him out of earshot, he deserved a lot more respect, not just from the students, but I see now from all Americans.

Thanks, Mr. Lindstrom, drive safe.

P.S. I've been at fault for only one minor fender-bender, and gotten one speeding ticket in 30 years, so you did good.

Sunday, September 21, 2008

"Fringe" and the "Off" button

I'd seen the ads and so decided to give the new Fox series "Fringe" a try. Since J. J. Adams, the originator of ABC's "Lost" (which I very much enjoy) was one of those behind the new series, I deemed it worth a look.

I knew there was going to be some gore and violence in it--what sci-fi based thriller nowadays doesn't? I'll put up with a limited amount of gore if it's incidental to the show and there's a good storyline going on ("Heroes" was kinda iffy in this regard at first, but then settled down). And I don't have a problem with violence per se so long as it's done smartly; I just watched "No Country for Old Men" last night, and even enjoyed--if that's the right word for it--the brutal "Sin City".

I watched the Fringe premiere, and then the second show of the series. This second episode opens with a prostitute having just gotten impregnated with some sort of abomination, which rapidly grows within her, inflicting excruciating pain, and is then followed by her agonizing death. The next victim is another woman, picked up at a bar, drugged, and then upon awakening subjected to open brain surgery, accessed through her face, and in full conscious awareness.

The episode then broke for a commercial. I stopped playback and cancelled the DVR's recording of the series.

I know it's the stock-in-trade of many crime shows and thrillers, but I have very little tolerance for seeing women, even if they are fictional, being tortured in the name of TV entertainment.

I don't know what rationale the producers of such shows use to defend this little plot device--"Don't be a prostitute", "Don't leave a bar to go to a warehouse with some creepy guy", or "See how monstrous this guy is, think of the catharsis you'll feel when he's caught and justice is served!"


The acts may be fictional, and it's all just "acting", but the images are real, and stick in your brain. There's enough real brutality in the world that there's no need for me to bring high-definition, Dolby Audio, you-are-there in-closeup visuals into my home.

I fiercely oppose censorship, but I do favor the "Off" button, and that's all that Fringe and shows of its ilk are ever going to get from me.

Wednesday, September 10, 2008

The 50 Meg Mouse Driver

I use a nice wireless Logitech VX Nano mouse with my laptop. I'm very happy with it, it of course acts like a mouse, and has a couple nice extra features like "sideways scrolling" and "Document flip" (like Alt-Tab, only better).

I did a Windows update this morning, and then after the reboot I got a Logitech dialog telling me there was an update available. Well, God knows what a Windows update could impact so I figured I'd go get the updated mouse driver...

...and it still had a few thousand more bytes to get.

56+ Meg for a mouse driver and settings tool???

It's a MOUSE! For pointing and clicking on things!

So after fifteen minutes of downloading and installation (most of that being installation) there's only one step left. Altogether now: "Reboot!"

Tuesday, September 9, 2008

The Monty Hall Problem Explained! Clearly explained!

I finally came across a clear explanation of the "The Monty Hall Problem", explaining why you should always change your pick.

The "Monty Hall Problem" is:
[Y]ou are given the opportunity to select one closed door of three, behind one of which there is a prize. The other two doors hide “goats” (or some other such “non–prize”), or nothing at all. Once you have made your selection, Monty Hall will open one of the remaining doors, revealing that it does not contain the prize. He then asks you if you would like to switch your selection to the other unopened door, or stay with your original choice. Here is the problem: Does it matter if you switch?
The obvious answer is "No", since while it was originally a 1 in 3 change of picking correctly, after Monty opens one of the remaining doors the odds merely improve to 50/50, so it doesn't matter if you switch or not.

The thinking that leads you to that conclusion is in fact wrong, and by switching you actually increase your odds of winning to 2 in 3. The link above gives a nice readable explanation of how this works, but I just want to cheat here and give you an example that I think will help you more quickly grasp how making the switch improves your odds.

Suppose that instead of three doors there were a hundred, so your odds of originally picking the right door would be 1/100. So now Monty has Carol or Vanna or whoever open all but one of the remaining doors, leaving just two: the one you chose and one other. The chance that you originally chose the right door was 1 in a 100, but now that there's only two unseen doors do you really think that your odds have somehow magically improved to 50/50? It's the same principle whether you started with a hundred doors, fifty, twenty, or...three.

So, are you going to switch?

Deal or no deal?

(Unrelated side note: Looking at Carol Merrill's bio I see that she was born about 30 miles from where I grew up. Small world.)

Saturday, September 6, 2008

HOWTO: Talk to an Evolutionist Without Being Dismissed as Ignorant and Stupid

Okay, I'm actually serious here. I'm going to try not to get snarky or anything, the intent of that title is just to catch your attention. If you're an adherent of Creationism or Intelligent Design (ID), I am actually going to give you some legitimate advice on how to talk to an evolutionist in such a way that they don't immediately dismiss you as an idiot. Okay, that sounds a little provocative, and I'm sorry, but surely you're aware that one of the most common accusations by evolutionists about those who question their theories is that the questioner is obviously ignorant of evolution and so they're not going to waste their time trying to carry on an intelligent conversation with such a person.

The goal here is to get you past that objection, so that the evolutionist can't just dismiss you out-of-hand and so actually has to answer both your objections to evolutionary theory and your promotion of an alternative view of life's origins.

Evolutionists are People Too

First off, you need to understand (and respect) who and what evolutionists actually are. They're ordinary people, just like everybody else. They're husbands and wives, they live in the city, suburbs, rural areas. Some are Democrats, some are Republicans, Independents, Tories, Conservatives, Liberals, Libertarians, etc. They pay taxes, drive their kids to school, go to Little League games and tennis matches, go on vacation, hike, watch TV, mow their lawn, plant a garden, and on and on and on. They are normal, ordinary people.

They are not all atheists, they are not out to destroy humanity or our morality, they are not trying to erase the distinction between humans and the rest of the animal kingdom. They are not trying to turn us into "biological machines". They are not trying to promote promiscuity, or narcissism, or selfishness, or self-absorption. They are not intellectually deficient, they are not morally deficient, they have not had their minds "clouded by Satan". They are not "coldly rational", devoid of emotion, wonder, and awe. That do not advocate any particular moral philosophy as being a natural outcome of evolution. (Though they, like everyone else, may advocate a particular moral philosophy for other reasons.)

Evolution proponents live, and love, and experience elation, joy, frustration, and depression. They love their family and their country.

Think for a moment: If you talked a Republican or a Democrat into switching to your preferred party, what has really changed in them? They have the same personality, same history, same experience, same skills, but now just a different way of looking at how one should politically engage with our society. Likewise, if you convince an evolutionist of the validity of ID or creationism, what core aspects of their personality, skills, and experience, have actually changed? None. They're still the same person, just now with a different way of looking at our biological and cosmological history.

Look, the bottom line is that an evolutionist is just like you and me, and if you respect them, acknowledge that they rationally came to accept evolution as a guiding principle of the development of life as it exists today, that this made sense to them intellectually, and that it wasn't Satan who podcasted the theory directly into their brain, then you've taken the first step on having an evolutionist respect you enough to at least give you an initial hearing.

"Most of the theories have no concrete evedience [sic]. just like the evolution theory"

The above heading is from an actual comment on a blog post. It pretty much summarizes in a nutshell why evolutionists believe creationists and IDers are ignorant and stupid. Why? Because this is an ignorant and stupid statement. It betrays a breathtaking ignorance of just science in general, without even getting into the particulars of biology or evolution.

So what are we going to do about it here? Well, I'm going to give you the basics on just what a theory really is, which explains why theories are taken very seriously by all scientists--not just the evolutionary biologist types, and which therefore also explains why you can't dismiss evolution as "just a theory".

Look, if you want to be taken seriously in your discussions with an evolutionist, you have to learn to play on their turf, and understand how and why science works the way it does. You can't just stand on the sidelines and yell "You're wrong, the Bible says so!" and expect to be taken in any way seriously. Nor can you claim to be able to point out gaps, inconsistencies, and fallacies if you aren't even aware of the principles and methods (and rationales for them) that are being practiced by biologists. Doing that is the fastest way to get yourself written off as ...ignorant and stupid.


First, let's look at the difference between the way scientists use the term "scientific theory" and the way "theory" is used in casual conversation. If you've paid any attention at all when an evolutionist defends evolution, you'll have heard them claim that there is a difference. Well, there is. It's not just wordplay or defensiveness on their part, there is a difference, and not knowing it, or disbelieving their claim that there's a difference, is the quickest way to get you written off as... well... you know.

There's nothing unusual about the same word being used to mean different things, even if those different meanings are similar. Take "swearing" for example, as in "swearing an oath to tell the truth". If you watch any "reality" TV shows like Survivor or Big Brother, you'll always see the players "swearing" they're telling the truth, or swearing allegiance to another player or their alliance. And you'll also see them regularly breaking these sworn promises. When that happens there's almost always some drama and hurt feelings, and maybe some game-oriented revenge, but that's all that really comes of it. However, if you "swear an oath to tell the truth" in a court of law, and then don't--you can get yourself into REAL trouble, including prison time, because violating that oath is called perjury, and it's a criminal offense. In both cases you're "swearing" to tell the truth, but the import and ramifications differ significantly between the two contexts.

Likewise, saying something is "just a theory" in casual conversation is a far cry from the rigor embodied in the term when used in the scientific context of theories for such things as gravity, relativity, or evolution. And here's why:

In total opposition to our commenter's claim above that most theories have no concrete evidence, all scientific theories start with concrete evidence. Without evidence, without facts, measurements, and observations that have all been objectively acquired, there is no theory.

Facts, measurements, and observations are the "what" of scientific investigation. For example, when I find a fossil up in the hills behind my house, I have these facts:
  • This is a fossil
  • It was found within a layer of limestone
  • There are visible layers of rock above and below the layer in which the fossil was found
  • Limestone is a sedimentary rock comprised mostly of calcite (calcium carbonate)

I really found these in the hills behind my house!

No one, creationist or evolutionist, can argue with the facts. They are simply "what is".

The fundamental thing you have to understand about the definition of "theory" is that a theory is an explanation of the observed facts. It is an attempt to explain how those facts came to be, what relationships exist between those facts, and how those relationships came to be.

Again, a theory is an explanation. It is not a guess, it is not even an "educated guess", it is not some made up idea, it is an explanation of the facts that are sitting right in front of you.

Evolutionists came up with the theory of evolution to explain what biologists were seeing in present day lifeforms and in what was recorded in the fossil record.

There are a couple more things that you must understand about scientific theories in order to deal with them intelligently.

First, they allow one to make predictions about facts that "should" exist, but haven't been observed yet. For example, if geologists date a layer of rock in a cliff to be 50 million years old, and a lower layer of rock to be 100 million years old, their theory of sedimentary deposition would predict that dating a layer of rock anywhere between those two layers would reveal an age somewhere between the two known ones. So if they go out and date a couple more layers, and one turns out to be 60 million years old and another, lower one (but still above the 100 million year layer) is 80 million, then this provides some confirmation of their theory. They don't need to verify that there is a continuous variation from 50,000,001 years old to 99,999,999 years old in that cliff face in order to say they've got a good theory. That the theory explains the layering, and whenever a prediction that was made based on the theory is checked out always conforms to the theory's explanation, indicates that geologists can have confidence in the theory.

Second, as more facts are uncovered, sometimes the associated theory can't explain them. And this means the theory, the explanation, needs to be revised to incorporate the new facts. There's nothing sneaky about this, it's the way science is SUPPOSED to work.

If your car doesn't start in the morning, it might be because no gas is getting to your engine. If you then notice that your gas tank reads 'E', you might call up your boss to explain that you ran out of a gas and you're going to be late to work. You go get some gas, put it in the tank, and try to start your car, and it still doesn't start. So knowing a little something about cars you check the fuel line and discover the fuel filter is clogged. Now you alter your explanation, gas was not getting to your engine not because you were out of it, but because you had a clogged filter. So (and this is the part you need to grasp about how theories change) the fact that gas was not getting to your engine was accurate, but you had to refine your explanation as to why that was (not) happening. No one thinks twice about modifying such explanations as new facts are uncovered. The explanation in this case was on the right track, it just underwent refinement as more facts were uncovered. It would be ridiculous for your boss to wholesale reject your claim that gas was not getting to the engine simply because what you initially thought was the cause turned out to not be the actual cause.

So to summarize:
  • Facts are the "what"
  • Theories are "explanations"
  • Theories always start from the facts and try to explain why those facts are the way they are.
  • Theories can make predictions about as-yet-undiscovered facts that can then be checked.
  • Newly discovered facts can conflict with the current explanation, requiring the explanation--the theory--to be refined. Repeating: This is normal.
  • Scientific theories are powerful tools for understanding how the universe works, from atoms to stars, and are the foundation of our modern technologies.
You should now no longer be ignorant about what a theory is, unlike the commenter that headlined this section.

Some Ignorant and Stupid Critiques Not to Try to Make With Evolutionists

There are some very tired, long debunked critiques that creationists/IDers keep trying to make with evolutionists that do nothing but try the patience of said evolutionists. These particular points have been long dealt with, which pretty much anyone can see for themselves if they'd do 30 minutes of research on the web--looking at resources OTHER than creationist websites. You can almost hear the evolutionist rolling his/her eyes when one of these comes up. And this is a big reason as to why evolutionists regard creationists as ignorant and stupid--very few creationists bother to take the time to learn the least little thing about the scientific theory of evolution before trying to level supposedly devastating critiques against it. If it was that easy to knock evolution down, don't you think it would have long ago been relegated to a footnote in history?

Instead, creationist authors and seminars bring up the same old discredited objections, which (the more patient) evolutionists once again discredit. You end up then with creationists only reinforcing other uninformed creationists' belief that evolution is a frail house of cards while Intelligent Design is a rock-solid framework of origins and biological development. And the evolutionary biologists (justifiably) write the whole lot off as ignorant and stupid.

Ignorant Point #1: There are no transitional forms in the fossil record

Okay, go to wikipedia. In the search box type "List of transitional fossils". Note the page that comes up, "List of transitional fossils".

That particular list is incomplete and merely a first cut at a list. For a really irritating summary of how evolutionary theory was buttressed by the discovery of the fossil of a transitional (between fish and amphibian) creature--not just regarding evolutionary theory's predictions about its transitional form, but also how the theory guided the paleontologists as to where in the world to search for the remains of such a theoretical animal--read up on the tiktaalik, particularly the part about its discovery.

If you can't acknowledge, and aren't ready to deal with evidence for evolution like this, then you needn't waste your, or any evolutionist's, time. This is the kind of evidence with they use to support the theory, and denying or ignoring it just makes you look ignorant and stupid.

Ignorant Point #2: There are gaps in the fossil record

Yes, there are.

Just as there are gaps in your personal life record. Can you provide incontrovertible proof that you were ever 9 years, 2 months, 25 days, 6 hours, and 15 minutes old? Unlikely, because we don't keep a continuous video record of our existence from birth to death. Yet there are photos from your 9th birthday party, and photos from your 10th birthday party, so we have tangible records of those points in space and time, and that, combined with the theory of how time passes in this universe indicates that it is overwhelmingly like you were at one instant 9 years, 2 months, 25 days, 6 hours, and 15 minutes old.

Getting a fossil to survive for millions of years on a planet that is subject to erosion, volcanic activity, and tectonic movement is no mean feat. Not to mention that the original plant or animal had to have been trapped in its fossilizing medium sufficiently gently and quickly so as not to have been almost instantly destroyed by its immediate environment.

Given these limitations it's understandable that the fossil record is going to be sporadic, but "absence of evidence is not evidence of absence". And whenever a fossil is found that fits into one of the known gaps a side-effect of that is that where once there was one gap, now there are two smaller ones. So an evolutionist will tell you that all a gap represents is that a transitional form that fits into that gap has not yet been found--but you can make predictions about what's in that gap that may at some point be testable--reread about the tiktaalik to see how that works.

Ignorant Point #3: If we're descended from monkeys, how come there's still monkeys?

See, this is where that whole "ignorant" thing really comes into play.

Evolutionists do not claim that humans are descended from moneys, yet creationists continue to attribute this claim to them and treat the present-day existence of monkeys as some supposedly devastating critique of evolutionary theory.

Evolution does state that modern humans, and modern monkey species, descended from an earlier primate species. Now this common ancestor may have somewhat resembled a modern-day monkey (hence the bit about being "descended from monkeys") but it does not correspond to any modern-day species of monkey. So, there aren't any contemporaneous primate species from which we (and the monkeys) evolved. Although while evolution claims the descendants of this early primate species evolved (changed) into modern humans and monkeys, there was nothing that actually forced all of its descendants to change one way or another. A line of descent could have remained faithful to the original creature, with evolution driving the changes of just the sibling descendants, thereby leaving a fair representation of that original primate still among us today. But there's no evidence that happened, so it's now just us and the monkeys.

Ignorant Point #4: Evolutionary theory cannot explain the complexity of the circulatory system

Yes, evolutionists say, it actually can.

Ignorant Point #5: The eubacterial flagellum is an irrefutable example of "irreducible complexity"

An individual being unable to conceive how some specific thing, like a bacterial flagellum, could have evolved into existence doesn't make it happening a scientific impossibility.

Ignorant point #6: Bananas were obviously intelligently designed for human consumption

Bananas are not an "Atheist's Nightmare". From the biology department at the University of California

“When humankind first encountered this fruit thousands of years ago we were probably not impressed by the almost inedible giant wild bananas. Historic mutations, rare and accidental, produced seedless bananas through chromosome triplication. Ancient humans focused on these seedless, pollen-less mutants to generate progressively more edible crops. Eventually, edible banana flesh retained only a few vague traces of the viable seeds once carried in the ancestral wild stock. Ancient plant breeders grew edible bananas by grafting sterile mutants onto wild stems. This process was repeated for thousands of years to produce the emasculated, sterile -- and defenceless -- plantation banana that currently feeds millions of people globally.”

Ignorant point #7: Evolution doesn't occur in a jar of peanut therefore the theory is false

Words fail.

So where are you now?

Being not ignorant and not stupid is not easy. If you're unwilling to understand the evidence and the argument for evolution on its own terms, then there's no point or value in your disbelieving it or trying to argue about it, because regurgitating what you heard in some ill-informed seminar or ID book that also shies away from the evidence and theory is going to fail you when you think you're criticizing evolutionary theory. It's very easy to fall into a victimization mode, where you think you're being discriminated against because you believe in God, or the Bible, or whatever.

No, you simply don't know what you're talking about.

So fix that first.

This can be done. Francis S. Collins is a self-professed evangelical Christian, and has authored books on science and faith. Did I mention he's also a world-famous geneticist and led the Human Genome Project?

The problem isn't with what you believe, the problems are with what you don't know, and won't learn. The first problem leaves you ignorant, and the second one makes you stupid.

The ramifications of gaining an informed, intelligent understanding of evolution prior to talking to an evolutionist

If you're still with me, and think you're willing to do the work so you can take a shot at holding an informed, intelligent discussion with an evolutionist about the merits of ID versus evolution, you might find yourself in some unexpected situations, which have associated with them some pretty serious ramifications.

I can tell you right up front that when you understand what a theory is, how it's created, and how it gets refined as more facts are uncovered, you're going to be very impressed with the power of the concept. And you should be, since theories are the foundation for our modern technology and civilization. Whether it's cell phones, television, space travel, weather forecasting, nutrition, antibiotics, CAT scans, and so on and on, the development and advancement of our technological society all trace back to the theories--the explanations--of how things work, and therefore what might be expected when trying, and guidance on how, to make new things

And the thing you're going to find out about sound biological theories, like evolution, is that the evidence for them is every bit as solid as the evidence for physics and chemistry theories. And not only is the evidence there, but the same careful, methodical, analysis, development, and refinement that was used to develop the theories of physics and chemistry is also used to develop and refine the theory of evolution.

I can't emphasize enough what this means for you when discussing creationism or ID with an evolutionist. There's an astounding amount of evidence for evolution, the theories are sound and their development conforms in all ways with the development of the theories on which all of our technology is based. In fact, evolutionary theory is at the heart of biomedical research and development, and is a fundamental concept for the development of modern pharmaceuticals, diagnostics, treatments, prosthetics, and so on.

You have to realize that you're really going to have your work cut out for you when trying to argue that evolution is an intrinsically flawed theory and that Intelligent Design provides a better explanation for the biological world as we understand it today. To put it all in a nutshell: Evolution is an explanation of observed biological and paleontological facts that accurately reflects, explains, and provides reliable information about the biological state of the earth.

This can be a bit harsh at first to acknowledge, but doing so really opens one up to the wondrous variety of life on this planet, and to understand how throughout billions of years and the pressure of natural selection that we've arrived at the amazing diversity of life that we see today. I've found it, belatedly, fascinating. I never used to care for biology, but once I gained a really good understanding of how evolution brought us to this point, and what it tells us about the interconnectedness of life past and present, I'm awed by it.

And I can now hold an intelligent and informed conversation with an evolutionist. Just as you can with me--just don't be ignorant and stupid.

Friday, September 5, 2008

Saturday Night Live Premiere: Has this conversation already taken place?

Lorne Michaels: "Tina, hey, I was wondering..."

Tina Fey: "I've already drafted the sketch."

Lorne: "Thanks, Tina, see ya next week.

Tina: "I'll be there."

Tuesday, August 26, 2008

The Elemental Kickin' the Darkness

I learned the Periodic Table of the Elements by the time I was in the 4th grade and could easily name any element just by looking at its symbol (of course at that time the last known element was element 103, Lawrencium/Lr, so it was easier back then :-)

My fascination with that table and illustrations of it have stuck with me over the years. I came upon a site that sells the table as a beautifully illustrated poster, and also provides a "Create an Element Banner" feature for your choice of word, name, or phrase (if it can be spelled with elements) that you can then purchase, so I couldn't resist:

Monday, August 25, 2008

Are you ready to vote?

Check your registration status and find out everything you need to know to vote on Election Day.

Yes, it's the Obama campaign that's providing this on-line service, but you can vote for anybody you want to at the long as you're registered.

It's the American thing to do.

Tuesday, June 10, 2008

What George the Manager Taught Me About Presidential Qualifications

George was the best manager I've ever reported to, or been around, in my military-industrial complex career. He wasn't a manager in the "Peopleware" sense, i.e. an inspirational, motivational, visionary leader for whom his department would commit to, and accomplish, great things and experience a richness of work and personal life beyond what any reasonable person has any reason to expect from a job.

No, George was a manager in the old school sense, that of being an effective administrator. He wasn't the greatest guy in the world, but the thing is that his department ran well, ran efficiently, and got things done. George knew how to organize his department, plan ahead, acquire the resources, make the deals, and such that were necessary for him and his department to carry out their assignments.

He wasn't the smartest guy in the room, but he knew how to pick 'em, and those are the ones he made into his department leads. His ego didn't require stroking from the leads to reassure him that he was indeed the smartest guy around. George openly stated that his goal was to surround himself with smart people, since from such individuals success is much more likely. He certainly didn't have the technical skills or talent we did, and he knew that to presume that he somehow possessed superior technical insight was, for him, laughable.

He demanded hearing only accurate statuses about our projects, and took what we said at our word, and worked to clear the path to our achieving project success. Whatever we told him needed to be done, he went and made it possible, dealing with all that noisome management and administrative political-type stuff that managers are supposed to deal with day in and day out (which is why too many managers, promoted up from doing techie work, flounder on the managerial tasks and step back into technical whenever they get the chance--it's a lot easier, and less frustrating).

Working in his department was a very positive experience for me, the other leads, and most of those in the department, despite George' personality deficiencies. The fact that our actual work in the company proceeded smoothly, with little drama, with the needed resources, allowed one a sense of accomplishment about their job. Progress was actually getting made, and one got to spend their time doing what they were good at, rather than having to fight with other engineers or departments in order to get their jobs done-George cleared the paths and administered the interactions in all those areas.

Seeing this first hand made it clear to me what it takes to run an organization effectively, and the skill set that it requires.

In this US presidential race I see those organizing and administration skills in full display by the Obama campaign. Seeing Obama's well-organized, disciplined, and foresighted approach to campaigning deeply reverberated with my experience working for George.

The ironic thing is that although I haven't seen George in over a dozen years, I think it's pretty unlikely that he would be an Obama supporter, yet it's the very practices, abilities, and competencies that he exhibited, and demonstrated the importance of, that have impressed me with Obama's demonstrated abilities to meet the demands of being the nation's Chief Executive.

(And just imagine what happens when you combine that kind of executive competence with vision and the fact that he will not infrequently actually be the smartest guy in the room :-)

Friday, June 6, 2008

Presidential Generational Transitions

I was born less than a year after John Kennedy was elected president.

He was the first president of the 20th century to be born in the 20th century, May 29, 1917 to be exact.

He, and then all the subsequent presidents up through the elder Bush, all had the Depression and/or World War II playing a significant role in shaping their personal natures.

And all these presidents were at least 35 years older than me.

So it was a bit jarring at first when Bill Clinton was elected, since he was the first president in my life that was more of my parents generation, than that of my grandparents.

Clinton, and George W. Bush, were shaped for good or ill by the 60s/Vietnam era.

Two of the three candidates competing prior to the recently concluded primaries were also of that era, Hillary Clinton and John McCain.

And now, we're looking at a possible transition to the next generation of presidents. Barack Obama is literally only 7 weeks older than me. We were 8 when the 60s ended. I grew up as a small town kid in that time, and I have only the haziest recollections of Vietnam, hippies, and Nixon. I have no recollection of the assassinations of MLK or Robert Kennedy (although oddly enough I do recall my mom pointing at the TV and telling me the president had been shot when I was a little over 2 years old).

Moving beyond that whole 60s and Vietnam era and mindset is something I have long been looking forward to, and I'm very happy to see that the first candidate of my generation to have a shot at the presidency is one who really is an embodiment of the best that we have to offer.

Obama '08!

Thursday, June 5, 2008

Americans take back America!

On the one hand it seems unbelievable.

But on the other, of course it's believable, we're Americans.

The presidential primary season is over, and we're left with the best candidates from each of their respective parties.

Obama beats the most formidable political machine and brand name of modern times.

And McCain resurrects his campaign from the dead to show that you can't keep a good man down.

This is the result I wanted to see when the primary season began, and I'm still a little startled to see it actually come to be.

The voters of both parties, each one American through and through, decided we were sick of cut-throat politicking and fear-based campaigns, and chose the candidates who had the integrity and vision to remember, and to understand, the core principles of this country, and the hope of its people.

Congratulations Barack and John.

Let's make it a good clean fight.

Thursday, May 22, 2008

JGNAT is coming back!

(If you're not interested in the Ada programming language, then this post has nothing for you :-)

AdaCore has announced in their latest newsletter that JGNAT, their Ada-to-Java Byte Code compiler, is being updated and will be made available in the 2nd quarter of 2008 (see the "In The Pipeline" sidebar):
A collection of add-on tools for interfacing between Ada and
Java is scheduled for release during Q2 2008. They support
mixed-language Ada/Java development, in particular:

- Calling natively-compiled Ada code from Java
- Compiling Ada to JVM bytecodes and communicating between Ada and Java directly.

The toolsuite exploits the Java Native Interface (JNI) for the
first scenario, but automates the generation of the JNI-related
“glue code” to ease the job of the developer. An updated
version of AdaCore’s JGNAT product handles the second
scenario. The tools take advantage of Ada 2005’s new
features to provide an interfacing mechanism that complies
with the Ada standard.
A future version of the toolsuite will support the invocation of
Java methods from natively-compiled Ada code.
The original release was never updated beyond version 1.1p, which I used a fair amount. I felt it was almost, but not quite, production quality. My experience was that it worked pretty well with Java 1.2, tasking broke in 1.3, and was pretty much a non-starter for 1.4.

Robert Dewar, AdaCore's president, commented in 2004 that "the status of JGNAT is that we have kept the sources updated to the minimal extent that they compile, but we no longer support this product and it was never fully completed."

I don't know the impetus behind restarting JGNAT support, but I'm glad to see it happening.

Wednesday, May 21, 2008

New Word: "Antiference"


an-tif-er-uhns, an-tif-ruhns
- noun.

1. A preference against a choice.
2. That which is preferred to be avoided.
3. A manufacturer of aerials and distribution equipment.

Ex. "I don't really have a preference among these projects, but my antiference is the one coding a CORBA app in C++.

Phoenix Descending

The Phoenix Mars probe is scheduled to land this Sunday at 23:38:32 UTC Spacecraft time (23:53:52 UTC Earth received time).

Here's a Phoenix Mars Landing Real-Time Simulation to help you see what has happened, and what is going to be happening and when.

Monday, May 12, 2008

The Lunas Are Back!

North Alabama has suffered through a drought the last two years, with last year's being "exceptional". Because of this the local insect populations appear to have had significantly declined. While this means less of the pesty bugs, it also means fewer sightings of the neater ones.

Like I hadn't see a Luna moth here at all in the last couple years, while in prior years there were always some showing up in the spring.

This year, rainwise, has been different. We're basically getting normal rainfall--though technically the drought is not yet broken--and starting to see some critters that I haven't seen for awhile. I was very happy to again see one of the Lunas:

The big, furry Cecropia moths Polyphemus moths have managed to show up each year, despite the drought, and this year was no different:

Cool, eh?

And I don't know what this guy is, but he's certainly pullin' in Shanghai off the shortwave...

Later this year we should be getting the big "rhinoceros" beetles. Stay tuned...

Thursday, May 8, 2008

Binary Search -- Mmmm, tasty!

I stumbled across Tim Bray's article on binary search, and simply felt compelled to pass it along.

It's well-written, concise, and even if as a software developer you've got binary search down pat, it's still a pleasure to read a well-written explanatory article about something so fundamental to our craft.

So if you need a little refresher on the details of binary search, and why it's so gosh darn useful, or you need to roll your own because you need to make some small variations to the basic algorithm (which was my situation and why I went looking for some articles on this subject), give it a read.

Good technical writing stands the test of time.

Tuesday, May 6, 2008

Send Your Loved Ones Into Space -- And You Too!

A couple of upcoming missions have announced that the public can submit their names, which will then be attached to the spacecraft that is launched into space. I've done this with a couple previous space missions, and it's a cute thing, you can even get a certificate :-)

The two missions that I just became aware of that are doing this are:

Lunar Reconnaissance Orbiter - whose purpose is to "to [find] safe landing sites, locate potential resources, characterize the radiation environment, and demonstrate new technology." Send your name (and those of your family and friends) to the moon!

Kepler Mission - "specifically designed to survey our region of the Milky Way galaxy to detect and characterize hundreds of Earth-size and smaller planets in or near the habitable zone." Submit your name (and a brief message if you want) to be carried along on the spacecraft that may be the first to detect a possibly habitable extra-solar planet.

Tuesday, April 22, 2008

Why the Chart Wasn't Opening

Here's a not atypical experience when porting a humongous (1.3ish MSLOC) legacy application from one platform to another; in this case from SG/IRIX to Linux.

During a simulation run the operator can click on a button that opens up a chart displaying some statistics depicted as a line graph. In the working version of the port that chart wasn't opening up.


Because the chart module never received a "Create Line Graph message".


Because that message is sent only when the simulation's "current time counter" is not 0.0, and it was not getting incremented.


Because no "Timestamp" message had been received.


(At this point I embarked on a Wild Goose Chase -- Marc)

Because the sending process never sent one.


Because when reading a file it turned out the file was unexpectedly empty and so froze up, having thrown an "End_Error" exception.

What did the original version do?

Err..I guess the file is empty there too, but it throws an "Out_Of_Data" exception.


Ah...race condition.

So what's the net effect of the difference between how the two exceptions are handled?

Huh. None. They're both taken to mean "no data", which is a not unexpected condition, and so the exceptions are resolved and processing continues.

-- End of Wild Goose Chase. Backtracking to where I left off:


Because no "Timestamp" message had been received.


Because the sending module is experiencing a SEGFAULT.


Because some data being extracted from a database is getting stomped on with bad, bad values, triggering the segfault.


Compiler bug.


Looks that way. Though 99% of the time that I start to think "compiler bug" it turns out to be a programming error, this is one time it looks legit. A procedure is getting called that does some calling of additional subprograms to retrieve the data from the DB. Down at the bottom an exception is thrown that propagates back up to the calling routine. This is a "no data found" exception that is perfectly legitimate to have occur and propagate back up. When control returns to the controlling procedure, though, some of the local variables have gotten clobbered--even those that are not part of the calling sequence. Everything is fine until that exception is handed up to the calling procedure. So the work-around for this was to catch the exception within that first called procedure, and change the function parameter list to include a "found" flag, which is set according to whether the exception occurred or not. The caller than checks the flag and handles the response as if the exception had occurred.

And then?

The chart still doesn't open.


In a color setting function, the name of the color is passed in and checked against a table that maps each color name to some internal data. That function lower-cases the color name parameter, since all the names in the table are lower case. The function, though, is modifying (via tolower()) the color name within the parameter itself, rather than to a local variable. For some reason trying to overwrite the parameter in place is causing another segfault. This is a less-than-desireable thing to be doing anyway, i.e. modifying the passed-in argument that should only be used as a lookup value, so the function was modified to lower-case the value into a local variable, which was then used for the table lookup.


The chart kinda opens, and then freezes.




Yes, down in the Lesstif code a null dereference is occurring.


Beats the hell out of me on this one. I built Lesstif from source, with debug, so I can find the line of code that's causing the problem but I really don't know what exact sequence of events is leading to this problem (I'm an applications, not a systems, programmer!) It does seem to be happening with the ScrolledList widget, when doing something pertaining to fonts.

What now?

Try exploratory code removal. Comment out the line that sets the font list and see if maybe some sort of default gets used.


Chart correctly opened and displayed, although the text is not italicized like it is on the original platform.

I can live with that.

Wednesday, March 26, 2008

Decades of Spam

I have some contact-the-author email accounts that are provided in README files that accompany some open source software I've released, and which I knew would sooner or later get scraped up by spambots. They were, and now I get anywhere from 20-100 spams a day on them. The Gmail filter is pretty good so I rarely see more than one every couple weeks that gets through. Still, because every now and then a legitimate email comes in and sometimes gets marked as spam I have to take a quick look at the spam jail pretty much daily and make sure that nothing got caught that should have gotten through.

And I wonder, how long is this going to go on? Is this something I and every other email user that needs to provide a publicly accessible email address going to have to deal with...for decades?? Geeze that's depressing.

About the only thing more depressing in this matter is the poor slob whose job it is to write those ridiculously lame come-on one-liners for "enlargement" products. That's a soul-killing job if there ever was one.

Monday, March 24, 2008

The Toilevator

One thing I've noticed over the last decade or so is the increasing likelihood that some mundane item that one thinks ought to exist, more often than not does exist. At least in the areas of household items, tools, and home improvement type stuff.

That said, I give you...the Toilevator.

No, it's not for me. But thanks for asking.

Monday, March 17, 2008

Thursday, March 13, 2008

Otters Should Not Be Allowed to Design Software

I got nothing against otters.

They're cute, playful, inquisitive, and so on. We should take joy in their simple life, and protect their habitat.

Neither they nor their human analogues, however, should be allowed to design software.

When you're porting a large software system from one platform to another you spend a lot of time dealing with the design and implementation..uh..quirks of the original builders. Sometimes it's just stylistic stuff like typedef'ing (C) or renaming (Ada) every single freakin' standard type name. Other times, though, you'd swear that otters had been tasked with coming up with the design.

So the part I'm porting now has a central control process and a GUI process that communicates via sockets. All well and fine.

The latest issue I've been dealing with has to do with the operator clicking on a field in a table to change it, which pops up a menu of valid entries, one of which is selected and then the "Done" button is clicked. Somewhere, though, in the update processing chain the value was getting trashed, causing the update to fail.

In other words, run-of-the-mill porting issues.

So I traced through the code and verified that the operator's selection was getting properly packaged up into a message and sent out through the socket. I followed it right up to the socket write, so there was no doubt.

I then went to the recipient of the message, the central control process, and verified that the message was being properly received and decoded.

The next thing that's done after receiving the message is calling a function called Update_Table(). The invalid data error is being detected inside this function. However, the data from the message I just read in is not being passed into Update_Table. WTF? Why is it failing then?

So I dig down into Update_Table and see that what it's doing is going out to query for the data in the table row that's about to be updated. But it's not getting this data from a database. Nor is it accessing some internal data structure model. It's sending out a message.

To the GUI process.

And so now I go back to the GUI process and start tracing from where that message is received. So is the GUI process maintaining some data store itself that it maintains and both displays to the operator and keeps for queries from the controlling process? Why, no, no it doesn't. Instead it goes and gets the data out of the graphical widget that's displaying it. If the value is a number, it converts the displayed string representation of the number back to a number, otherwise it passes it back as a string.

So not only does the central controlling process not have control of the data, it's outsourced that responsibility to the GUI, and that in turn is using the display widget as its data store.

Whoever came up with this bright idea is a complete, raving, ... otter.

Imagine, in a distributed system that does in fact utilize a database for data storage you can lose all your active data if the GUI crashes.

(Oh, the problem turned out to be a data alignment mismatch due to the change in word sizes between the different platforms.)