David D. Thornburg, Associate Editor
Compilers, Interpreters, And Flow: Conclusion
Over the past two columns I've explored some ways in which programming with an interpreter or compiler can influence the nature and complexity of the programs we write. As this is written, I'm approaching the end of a Logo-based programming course that I've been teaching to graduate students at Stanford. (Yes, Virginia, there is Logo after second grade!) Because I wanted my students to have access to a high-speed runtime language, I elected to use a Logo compiler in this course.
As was mentioned last month, the speed improvements in compiled programs have a lot to do with the program's ability to maintain a sense of "flow" with the user. But, just as the compiler's benefits are directed toward the user, interpreters provide quite a few benefits to the programmer-especially if the programmer is just learning to use the language. When computer languages are taught in school, the assignments and lectures usually structure the learning process for the students, and the work at the keyboard tends to reinforce what has already been learned rather than encourage new discoveries. It is when learning a new language on your own that an interpreter is of tremendous value.
Instead of studying a new language in a book before trying to create programs, I usually jump in with both feet and start sloshing around, trying to get something to work. In educational circles, this experimental learning style is called discovery-based learning. In the realm of videogames, people like Bernie DeKoven call it "learning by dying." One of the reasons videogames can be learned without referring to extensive manuals is that you can usually figure out what caused you to lose your turn or one of your "lives," so you can avoid that mistake the next time.
A well-designed interpreter and program editor could allow people to master new programming languages in this way. (This approach could also be applied to education in general, but that's a topic for another column.)
One example of this is Macintosh Pascal. Mac Pascal contains both an interpreter and a powerful program editor that allows beginners to learn this language in a highly interactive and self-paced fashion. Those of you who know Pascal may think that the "sloshing around" style of learning is ill-suited to a language whose structure is more like a faceted jewel than a lump of clay. But I believe the rigid structure imposed on Pascal programs makes an "intelligent" editor and program interpreter of tremendous value.
The program editor automatically indents program lines and boldfaces Pascal keywords, making the listing very easy to scan. Furthermore, if the interpreter detects an error as the program is running, helpful "bug detection" tools point out the line with the problem and provide as much help in fixing the problem as possible.
This interaction between the interpreter and program editor encourages the programmer to try new constructs and ideas, safe in the knowledge that "bad grammar" will be detected and clearly identified.
The interaction between the interpreter and program editor does not stop here. You can also execute programs line by line, place "stop signs" at various locations in the program to help debug the code, and even create windows to show the values of certain variables as the program runs.
Normally, Pascal doesn't allow you to execute single-line programs. But Macintosh Pascal does, so you can type fragments of Pascal code to see how they behave. This makes the language far easier to learn. Fortunately, Mac Pascal is being adapted for the Apple IIe and IIc computers as well, thus bringing this style of Pascal programming to a far larger audience.
The Best Compromise
The choice between an interpreter or a compiler, then, depends on the application and the point of view. From the user's perspective, compiled programs have the advantage of execution speed. For programmers, interpreters have more advantages. Since most programs involve both users and programmers, this suggests that widely used programming languages should be available in two forms-an interpreter for creating and testing programs, and a compiler to produce the final product.
Furthermore, it's essential that these modules be compatible with each other's source code. Programmers should be able to take a program that was written and debugged with the interpreter and drop it into the compiler to generate the highly efficient runtime code for the user.
As progress continues along these lines, we'll see a trend toward application programming in increasingly higher-level languages. No longer will programmers have to learn machine language to build industrial-strength programs. Anyone who knows how to write in high-level languages will be able to create efficient programs of all types for their own use, as well as for the use of others.
David Thornburg welcomes letters from readers, but regrets that he cannot personally answer all his mail. Correspondence should be sent in care of COMPUTE!.