So far, you have explored three different paradigms of PL: imperative, functional, and object oriented. There are certain classes of problems which are suitable for each of paradigms. That's the programmers eyeview. As a programmer you know the choices you have in choosing a language. What about the designer? What choices do they have? What are the implications once the decisions are frozen? This assignment gives you an idea of desiger's choices. An important requirement of a designer is the ability to "foresee" user's requirements. Can you?
In this assignment we'll consider a specific problem physicists,
for example, face in programming. Consider the calculation of
voltage given current and resistance. Everybody knows that
voltage = current*resistance. Only a physicist
remembers that each of these quantities carries a unit with
it. If the current is in milliamperes and the resistance is in
gigaohms, then the voltage is in megavolts. If physicists
program in any language, they have to keep track of the units
themselves. As you can see, this can become tedious if you are
working with hundreds of such variables, each with its own unit.
The user wants some help from the language in keeping track of the units.
This is the user's perception of the problem. Many times, users have only a vague idea of what they want. A successful designer should have a much better idea of the problem than the user. In the case of PL design, you have to worry about the following: what does "keeping track of units" mean? It can mean some of the following.
Once you have decided on the extent of language support, you have to decide on actual language syntax and semantics. The following are some of the issues involved.
One way of treating dimensioned quantities is to consider them as variables with units.
float v (millivolt), i (microampere);Here
v is associated with the unit millvolt and
i is associated with microampere. This is the
imperative paradigm.
Another way is to treat them as classes. You can have a class
Voltage defined as below.
class Voltage {
private float v;
private String unit = "Volt";
/* rest of the class */
}
What does the programmer see? Which of the following is a more covenient way to declare and use 5 pounds?
float w = 5 lb; // imperative syntax
float w = 5 (lb); // another imperative syntax
Weight v = new Weight(5, "lb"); // Java syntax
Weight v(5, "lb"); // C++ syntax
What about expressions? In the following expressions, the constant
3 with some unit (lb, oz, or
Volt) is added to w.
w1 = w + 3 (lb);
w1 = w + 3 (oz);
w1 = w + 3 (Volt);
(One of the expressions has a unit mismatch.)
What about temporary variables? Temporary variables are useful for making large expressions readable. For example, instead of writing
a = ((b+c)*d)/e;
the programmer can write
t = (b+c)*d;
a = t/e;
which is hopefully more readable.
Should temporary be declared with actual units or can they be declared to
have "temporary" units? If a variable has temporary
units, the compiler/runtime calculates its actual units.
float tmp = 5 (V) / 5 (mA); // no need to "declare" the units of "tmp"
// the units of "tmp" are inferred
float resistance (ohm) = tmp + 10 (ohm); // start checking units
Data structures: What types of arrays are permitted? Only weight arrays or weight and voltage arrays? Can weight arrays mix pounds and kilograms?
Functions: Can functions specify the units of their arguments and returned value?
I/O: How are the values read and written to files? Is unit checking/conversion done at input?
Now we come to the most difficult part of language design: the meaning of language constructs and the division of labor. Suppose we have the following code fragment.
w1 = 10 (oz); w2 = 10 (kg); w3 (lb) = w1 + w2;Should the above fragment be considered syntactically meaningful? If yes, who does the conversion of units? The compiler or the runtime? Each has its advantages.
Another important issue is the specification of conversion formulas. How does the
programmer add to this background information? Suppose the programmer
wants to introduce a new monetary unit shekel and provide
a conversion to dollar, how can it be done?
Since the language is meant for numerical calculations, you should carefully consider the compilation and runtime costs of each of the features you introduce.
The above list is illustrative of the examples and issues you should consider
in designing a new language which supports units. You can add
more examples and issues. Infact, the best way to start is to list
down lot of different examples and study the requirements. You can
try the command man units and look at the file
/usr/share/lib/unittab
to get an idea of units involved in real problems.
This is what you do:
You should submit a report of at least 20 pages discussing the above and other issues in detail.
You should submit the report and self-evaluation form to Renata Teixeira on Mar 10 between 6:00 - 7:00 PM at APM 3349D.