As a mechanical engineer, my experiences with analysis programs are in the areas of structural stress, fluid dynamics, heat conduction, and thermal/hydraulic system simulation. Such programs present the technical software developer with a number of unique problems, not least of which is providing a user-friendly interface. That's because even though program users tend to be computer literate, input data can be voluminous and tedious (and error prone) to prepare. Also, the user typically makes many runs with only slight changes; as design optimization is often accomplished by repeated analysis. Another consideration is that both input and output must be stored and presented in a manner that allows independent verification and validation by a checker or some official entity. Finally, the information output from one program may be required as input by another.
Another big headache is that modern (i.e., graphical) user interfaces tend to be hardware or system-software specific. What is needed is a universal interface that frees the developer from the nuances of different types of machines and operating systems, while at the same time representing a standard that machine-specific routines can work with.
A solution I have arrived at for making such technical programs more user-friendly and modularized is called MEL. MEL (which stands for MEtaLanguage data processor) is a set of input/output (I/O) utilities that provides a standard interface between the program and the user. It can translate input data written in "pseudo-English" (Example 1) and makes it available to the program as variables (Example 2). It can also take program variables (Example 3) and translate them into pseudo-English (Example 4). Effort was taken in providing data objects that could easily be incorporated into almost any engineering analysis program (Example 5).
You should find the MEL interface useful in developing your own technical programs. Firstly, the pseudo-English look of MEL means that I/O will be more readable and comprehensible to the user (or checker). Secondly, MEL is object oriented in that it provides a structured and encapsulated I/O interface (more about this later). Thus, your development time will be reduced and future changes can be made to your program more easily. Thirdly, MEL's grammar is simple and unambiguous, with both input and output formats being identical. This means output from one program may serve directly as input to another. Finally, MEL can read and write data directly to a file so that a permanent record of a run and its results are available.
DESCRIPTION OF MEL:
The smallest unit of pseudo-English I/O in MEL is called a "descriptor." Its purpose is to describe something, either data or a command, to a program. The general format for descriptors is much like function calls in typical programming languages. An I/O unit consists of a descriptor name (somewhat like a function name), followed by a parameter list, followed by an end-of-unit symbol (the semicolon). For example, consider the following MEL descriptor which could be used as part of the input to a piping network analysis program I have written:
pipe, length = 100 (ft), diameter = 6 (in);
This is a "pipe" descriptor whose parameters are "length" and "diameter". The values assigned to these parameters would be 100 and 6, and in units of feet and inches, respectively. Although the tokens (names and parameters) making up descriptors are customized by the developer for each individual application program, the above grammar remains the same for all programs using MEL. (For more, see Examples 1 and 4.)
The format for MEL was chosen for its simplicity, while allowing for as much flexibility as possible without introducing ambiguity. I won't list all of the details here, but let me just say: tokens may be abbreviated (shortened, as long as they remain uniquely identifiable), a default parameter order will be assumed if parameter names are missing, comments may be included by enclosing them in double quotes, parameter values may be labeled as "unknown," etc. The point was to make programs incorporating MEL as convenient to the user as possible.
INCORPORATING MEL:
In order to incorporate MEL into one of your own programs you must first create a "dictionary" for both input and output that defines the proper spelling, number, and types (integer, array, etc.) of data associated with each descriptor and parameter. This is done by customizing the mel.h header file which you then include in your application source code file. (Note that by simply changing spellings in the dictionary you could go from pseudo-English to "pseudo-French" or some other "pseudo-language.") The task of defining dictionaries has been made as painless as possible by giving complete instructions and an example program on the MEL diskette. (MEL is available through the CUG library. The diskette contains MEL source code, header file, documentation and instructions, an example program, and a conversion factor routine. Since a listing of all MEL routines would run over 50 pages, a complete listing has not been included with this article.) You will also need to prepare documentation defining the dictionaries to the user and explaining what the tokens mean. This can be included with your other user documentation.
To obtain data from a descriptor you must first read it, and then extract the data. One way of doing this is shown in Example 2. An example of outputing data is shown in Example 3. If you wish to allow the user to input data with different units, conversion to internal units will be required (ASTM, 1982). Included on the MEL diskette is a routine that can convert between more than 150 different units. Additional units and conversion factors can easily be added to the source code.
HOW MEL WAS DEVELOPED:
An early decision was to write MEL in C. FORTRAN is the traditional language for scientific programs; however, engineers like myself are beginning to realize that there is more to technical software development than simply correctly coding a complex algorithm. ANSI C has a number of significant nonnumerical advantages over FORTRAN (Kempf, 1987). C is a popular and standardized language that, in my opinion, allows for more flexible structured programing and data encapsulation techniques to be applied (also see Jeffery, 1989). C has more operators and program control constructs than FORTRAN. C allows indirection (pointers) where FORTRAN does not. C more easily interfaces to existing system software since much of this software is itself written in C. Also, C is a popular language for unconventional computer architectures such as parallel processors (Lusk, 1987) and neural networks. (Let me also mention some of C's shortcomings, which are related to its relative naivete for scientific purposes. Dynamic array dimensioning in C is convoluted (Press, 1988). C does not have the numerical library that FORTRAN does. And finally, C does not allow operator overloading for data structures (complex numbers for example) nor does it have an exponentiation operator. However, I do not think these defects in C are not difficult to overcome.)
Another decision was to "objectify" MEL. (Object oriented programing is certainly the latest fad, and the arguments its adherents present for its advantages have not yet been disproven. They may even be true. Partly as an experiment to form my own opinion, the design of MEL incorporates the object oriented paradigm.) Since C was not designed as an object oriented language, but, nevertheless, is a very flexible one, there were many ways in which I could have expressed the concept. I chose to make use of C's preprocessor to restrict the visibility of public type, function, and data declarations to just those objects your application program may need at a certain place. To see, in a general manner, how this was done consider Example 5. (The private type, function, and variable data needed by the MEL routines themselves are not shown in the