I slid into the bench-style driver's seat and took the hard thin wheel with both hands for a moment. Then, one twist of the key, and from under the hood came a roar so familiar it close to brought tears to my eyes.
Shakespeare has returned.
Welcome back, old friend.
It's been 18 years since I've driven a Chevelle, but there's one in my garage again. White '69 Malibu 307 V8, with a sharp turquoise interior and lots more chrome than my original bottom-of-the-line '68. While the new Shakespeare has 95,000 miles on him, beneath his dents, a pinched rear bumper, and 23 years of Arizona dirt lies not a particle of rust.
And the old familiar spirit is there. I feel it on the curves taken under power--the smooth assurance of GM's most beautiful Chevy. It was there before, and it's there again.
Shakespeare and I went a lot of places together--to college, to Washington in April of '71 to protest the madness in Vietnam, to the mouth of the St. Lawrence to photograph a solar eclipse, to see a ghost (I'll tell that story some day), to work, and finally to the junkyard when there was practically nothing left.
If you want to know all about how a boy became a man, ask his first car. Fortunately for me and a lot of other ex boys, cars keep their secrets well.
I expect to take a lot of ribbing about Shakespeare--sure, yeah, another balding Boomer searching for his lost youth in a fast car. Go ahead and laugh--I find pieces of my lost youth all over the place, and I enjoy them unapologetically, from the position of power that comes of making it to 39 intact, self-employed, and debt-free. I take what works, and leave behind what doesn't. You can't go home again, but you can sometimes pick up your roots cheap on the classic roots market.
And hey, roots grow too.
I gave up Basic for Pascal in 1981, after a brief fling with Forth that left me trying to put my socks on over my shoes. Basic was pretty crude back then, but it was appropriate technology: It worked, and worked without undue complication on the memory-poor machines we could build 15 years ago.
But with the explosion of memory sizes in the mid-eighties came an explosion of interest in true compilers. We seized on Pascal and C because we could--the machines were abruptly able to support the "monstrous" 50K or 60K code files that compilers produced. Basic became a compiler in time, and took its place with them, but always as the poor-cousin "kiddie language" that true hackers tried to wipe from their memories like bugs from their bumpers.
Until very recently, straight-line native code compilers have ruled. This is now changing, once again because the machines we use are changing. Instead of a mostly empty 640K bottle with DOS lying at the bottom like your last slug of Coke, the machine is now an 8-Mbyte web with Windows lurking in the middle somewhere, putting tendrils down into anything and everything and controlling it all.
For ten years computing has been bound by the speed of the CPU and the amount of memory we had. Now, with 16-Mbyte, 33-MHz machines common-place, (and 486s on the desks of the avant garde) we're bound more and more by the computational overhead of the platform than by any other single factor. Windows demands that things be done just its way--and all code, however efficient, is forced to crawl through the same identical maze. I would argue that any application that spends the majority of its time making Windows API calls is interpreted, regardless of how the responsible code generator operates. So for Windows work, does it matter whether code is compiled or interpreted?
Not much. Really.
This is why, after an ice age lasting close to ten years, interpreters are finding their place in the sun once again. They're not the same crude text or token interpretation systems we saw in the original Basics. There's generally some level of compilation to intermediate code going on, and if you really need raw to-the-metal speed, there's almost always a provision to drop into straight-line compiled C code or (better yet) pure assembly code.
I haven't provided much coverage of Windows development in this column, in part because I've been watching the Windows tools market to see what trends emerge, and in part because I'm still doing the research--anyone who tells you that understanding the Windows platform is easy is probably intending to run for Congress. This new trend toward interpreters under Windows is the first clear trend I've seen, and it's worth a closer look.
In broad terms, the last several columns have been about event-driven programming. I've tested a lot of event-driven programming systems lately, and against their many benefits I have to remind you that event-driven programming is a serious eater of cycles. A broadcast event under Turbo Vision, for example, sets off an explosion of procedure calls that ultimately reaches every single object in the application with an event loop. Even a focused event must travel from the application to the focused object, which is a longer path more often than a shorter one.
It's absolutely valid to think of an event-driven application as an interpreter of events, where the internal structure of the code resembles that of our primordial Basic interpreter far more than it resembles the sleek optimized straight line executables produced by products such as TopSpeed Modula-2.
Furthermore, Windows virtually requires that an application be event-driven, because Windows itself is event-driven. This forces the internal structure of Windows applications into pretty much the same mold, and makes the code-performance issue utterly different than what it is for traditional programming under DOS.
I'm saying all this to make you understand that you don't automatically create fast Windows applications by using C or C++. Windows application performance depends overwhelmingly on difficult issues such as segment tuning and memory management that are language-independent and depend far more on the implementation of the language rather than on the language itself. In other words, with Windows in control, you can write faster applications with a good Basic than with an indifferent C.
So if you're contemplating moving to Windows, don't assume that you have to use C or C++. There's a wonderful smorgasbord of structured languages available for Windows, probably including the language you're currently using under DOS. Porting same-language code to Windows from DOS isn't easy--but it's certainly easier than trying to learn a new language and then port the code, say, from Pascal under DOS to C under Windows.
One of my early favorites among the new Windows languages is Visual Basic. Microsoft has done a good job hiding most of the internal Windows machinery that SDK-based development forces you to look in the eye, and the language's few lapses are quickly being filled by enthusiastic third-party developers.
In its logistics, Visual Basic has a lot in common with Borland's Object Vision, which I discussed in detail last month. Both products provide sophisticated Integrated Development Environments (IDEs) essential for application development--essential in that you no longer have the option of sneering at the IDE and doing all your work from the command line.
Both products are form-based. A form is simply a window in which something happens, and it escapes me why we don't just call them windows and be done with it. The term "forms" implies that there is something special about them, which there isn't.
An application may have any reasonable number of forms, which may invoke one another as required. Both products allow you to design your forms with on-screen drawing tools, using drag-and-drop strategies to choose controls from a tool-selection menu of some sort and position those controls on your form.
Both products allow you to define actions that components within the application will take in response to certain events such as mouse clicks, or getting or losing the focus. In Object Vision this is done in a very innovative fashion by creating a graphical "event tree" that plots a logic path to be taken when an event kicks off some action on the part of some application component.
Event trees are sharp, and the concept has a rich future, but as they exist today, OV's event trees are incomplete and somewhat limiting. For example, there's no way at all to iterate within an event tree. You can branch based on logical tests, but you can't loop, and this makes it agony to build certain kinds of action into your OV programs.
Visual Basic has no such limitations. You create responses to VB events in good old-fashioned Basic code, with all the control structures you're used to having. You can define and use variables freely, and unlike Object Vision (where you have only visible fields and not true variables, and where everything is irritatingly global), the forms metaphor provides a scoping mechanism that allows you to decide what should be local and what should be global.
Visual Basic lacks the sophisticated, built-in database features of Object Vision, but the third-party market is filling in that gap quickly, through database engine products in the form of Windows DLLs. You can, in fact, call Borland's Paradox Engine from Visual Basic if you choose, and I've been playing with more than one SQL database engine to good effect.
Visual Basic lacks some necessary system-access features. It's impossible, for example, to make DOS calls or sniff around in the DOS data areas in low memory. Most of the time we do this to find things out about the system (such as the number and types of drives installed, or how much free space is left on them) and if VB is going to be hard nosed about system access, it really ought to provide a way to query the system for any conceivable information a program might need to know--dangerous or not.
Alas, PEEK and POKE are gone, but Visual Basic remains Basic, with some of Basic's old bad habits. Reference a variable name that hasn't been declared, (which I do frequently by misspelling the name of a declared variable) and VB simply creates a new variable with that name. Mercifully, these unwanted variables are local to the form in which they are referenced. Would that they were local to the procedure instead!
Which brings us to an area in which Basic's roots have definitely grown: Locality and scope. VB has it all over Object Vision in this regard, which is especially near and dear to my heart. Scope is the soul of structured programming, after all; the very first thing I investigate in a new language is how it implements scoping and locality. Scoping in VB is closely tied to the physical organization of VB programs, which is much more complex than Basic programs of yore.
VB organizes applications under development as projects, and provides hidden machinery to manage the files that comprise a project. The project has a name, and this name is eventually applied to the .EXE file when you're finished developing interactively and want to bundle the project's components together into a single executable.
Each project consists of one or more form, windows that accept or display information. You attach objects to forms to interact with the user. These are usually controls such as buttons, text boxes, combo boxes, and so on, but also include static text and some innovative things like timers; forms themselves are considered objects as well. (You can't embed a form within a form, however.)
Forms may contain data definitions and procedure definitions. Nearly all objects generate events under some circumstances, and the event handlers for these events must be written within the form containing the objects that generate the events. The form already contains do-nothing stub event handler procedures for every possible event the form or its objects may generate, and you can add Basic statements to any or all of these event handlers at will.
A project may also incorporate modules, files of data definitions and procedures that are not directly called by events, nor associated explicitly with any form or object.
You can create new procedures inside a form, even if those procedures have nothing to do with handling events. This isn't generally a good idea, although it works. The rule is simple: Place code you intend to reuse inside modules; code inside forms should consist of event handlers only.
I've sketched it out in Figure 1. Forms contain objects, event handlers, and variable definitions; modules contain only Basic procedures and variable definitions. Event handlers can and should call procedures in modules to do most of their work. In other words, if a button-click event is supposed to recalculate a mortgage table, the recalculation should be written as a procedure in a mortgage module, not as part of a button event handler!
Procedures in modules can call procedures in other modules. It makes good structured sense to keep this (or any) intermodule coupling to a minimum.
I haven't shown anything at a truly project-global level in Figure 1. Visual Basic allows as an option a single global module in any given project, but the global module may contain only variable, constant, or type definitions. (Yes, Visual Basic allows programmer-defined types. Roots grow too!) I think it's wise to use the global module for nothing but constant or type definitions.
Forms and modules may both contain local variables visible from any procedures defined within those forms or modules. A procedure itself may define a local variable visible only within that procedure. Procedures may not, however, contain local procedures.
It's enough locality to be useful, and not so much (as in Pascal's unlimited nestability) as to be confusing. A variable may be defined only where it needs to be known: Within a procedure, to be used by that procedure only; within a form or module, to be shared by that form or module's procedures, or (in dire need) within the global module, where anything in the entire project can use or abuse it.
This is a lot more structure than I'm used to having in Basic, but it's a fine feeling indeed. The VB design process is straightforward: Sketch out your user interface. I still use paper for my first pass or two, because on paper I can sketch out connections between UI elements and modules. When you've decided on the number of forms and the distribution of visible objects across them, start drawing your forms.
It sounds silly, but you should do the interface first because it feels good, and gives you a sense of getting somewhere. It may also indicate that your forms are ugly or inconvenient before you spend a lot of time connecting the UI objects to fleshed-out event handlers. But once I have my UI reasonably defined, I take a piece of paper and sketch out a simple cause-effect diagram for events. I show, for example, a button marked "Recalculate" with an effect of calling the routine that amortizes a mortgage into a mortgage table. The cause-effect diagram may help you get a handle on what should be in which modules.
You may not identify every event that needs servicing until you're well into development. Events can be like that. The nice part is that Visual Basic has stubbed out all possible events harmlessly, so in most cases all that happens is...nothing. You figure out what event you missed, and you flesh it out.
Visual Basic shares a knotty problem with every single event-driven development system I've examined: Debug support is more suited to old-style, non-event driven code. VB has most of the debugging features of Turbo Pascal, although they're not as neatly packaged. You can set breakpoints, and you can singlestep, either by code line or by procedure call (for instance, T ace Into or Step Over). You can open an immediate window that accepts output from a special debug object using a Print method. It's the poor cousin of the Turbo Pascal watch, in that you have to explicitly place the Debug. Print statement in your program code.
Debugging works tolerably well, if only because VB is a blacker box than Turbo Vision, and its internals are (thankfully!) neither alterable nor visible. Still, I keep feeling that there is some conceptual breakthrough to be made on the fundamental mechanisms of debugging event-driven code. Some bright person is gonna make some money when he or she hits on just the right idea. You could do worse than be that person.
The more I work in Visual Basic, the better I like it. People have carped about its limitations, but I've found on probing that many of them are simply pining for access to the waydowndeep Windows API calls. I keep reminding myself that the only thing possibly worse than not getting what you want is getting it, but some people never seem to learn that particular lesson.
Windows is a handful. If you're interested in Windows internals, by all means use tools such as QuickC Windows, Turbo Pascal for Windows, Turbo C++ for Windows, or Borland C++. Keep in mind that in Tom Swan's terrific 800-page book Turbo Pascal for Windows Programming, he spends not a single page teaching Pascal! The entire book is essentially about calling the Windows API.
Hey man, but what if I just want to write a mortgage calculator? Then, m'boy, stand tall and use Visual Basic.
I've come across an obscure little book that's been very helpful and lots of fun in my pursuit of Visual Basic. It has its flaws (mostly on the production end of things) but it's useful and different enough to recommend, especially because you won't see it in the stores. It's VB=MC{2}, by J.D. Evans, Jr. and published by ETN Corp.
The book is basically a printed lecture by the author on the use of Visual Basic in application development. I call it a "lecture" because it reads as though it were given from the podium before an audience: chatty, complete with informal diction and an occasional joke. ("Now, thinking is something that makes my head hurt and is something to be avoided at all costs--this is a Southern trait and is most definitely inherited.") This joke to the contrary, it is an extremely thoughtful book that traces the author's logic in working through the Visual Basic design process and building an SQL query design tool. Thoughtful--but ugly, uninterrupted by technical figures aside from a small handful of screen shots. The author italicizes every third word for emphasis, which of course means all italicized words lose emphasis and simply look weird.
About half the book is VB source code, which is included on a diskette as part of the package.
Despite its flaws, the book is valuable because it reflects the author's real-world experience with VB, and contains a lot of heuristics that I found useful. Mr. Evans points out that complex forms run more slowly than simple forms and that extremely complex forms don't always run correctly (something you're not likely to see in Microsoft's documentation); that you should not put nonevent code into a form, and many other similar things. The discussion on what to put in event code vs. module (nonevent) code is worth the price of admission.
Like a lot of other good things, VB=MC{2} is quirky, but it contains reality-centered advice I haven't seen anywhere else, and a lot of solid VB source code.
It's really not my job to talk about C stuff in this column, but I've been playing with another very slick, event-driven product that is essentially Visual C++. It's called VZ Programmer, and it works in much the same way as Visual Basic: You draw an interface, and then connect the interface elements to interpreted C++ functions. It works about as quickly as Visual Basic, and while the documentation is not terrific, the visual metaphor and toolsets are somewhat richer and more versatile.
The company is out there and selling product, so evidently an interpreted C++ is not anathema. Let me therefore yell: Hey already, when is somebody going to do me up a Visual Pascal?
Visual Basic Microsoft Corp. One Microsoft Way Redmond, WA 98052-6399 206-882-8080 $199.00
VB=MC{2} by J.D. Evans ETN Corp. RR 4 Box 659 Montoursville, PA 17754-9433 460 pages, $29.95 (disk $9.95)
VZ Programmer VZ Corp. 175 S. Main St., Ste. 1550 Salt Lake City, UT 84111 801-595-1352 $595.00
Copyright © 1992, Dr. Dobb's JournalBack to Basic
Crawling Through the Same Maze
Events and Interpreters
Visual Basic
Scope and Program Organization
Locality
The Visual Basic Development Process
The Bug Problem
A Blacker Box
VB=MC{2}
A Visual C++
Products Mentioned