1. Language Evaluation
In general, your answers were reasonable. Some answers did not go into enough detail. "XXX is reliable" is not a sufficient answer for this question. I was also surprised to see that few of you gave specific examples (I didn't penalize you; I was just surprised). A few of you used criteria that we didn't discuss but that came from the white paper for a specific language.
If you care, about half of you did Java, and a few did Pascal. Other languages covered included Basic, Maple, C, and Common Lisp.
2. Iteration vs. Recursion
Most of you wrote Java programs to answer this question. A few used Pascal and one used C. There were a surprisingly large variety in your answers. The C program showed no difference when optimization was turned on. One person reported that the recursive method took 2/3 of the time of the iterative method. Most reported that the recursive method was slower than the iterative method, with a few finding it taking 3 times as long as the iterative method.
Even though this was a short program, I expected to see good coding habits, including comments, appropriate variable names, and modularity. I noted some of these problems on your individual assignments.
I frequently saw little real thought put into the testing. For example, some people timed input and output in addition to computation and many timed only one call to each method, which is often so quick as to give unreliable timings. The better tests called each version repeatedly, often with different parameters. The best tests showed some consideration of appropriate parameters, including randomly generated parameters. if you used randomly generated parameters, it was important to ensure that both methods were called with the same parameters.
Almost no one attempted to consider which inputs are particularly hard for a GCD algorithm. A typical example of 12 and 8 requires only two steps to find the GCD. It is not clear that randomly generated numbers require significantly more steps.
What are the worst pairs we can use? The Fibonacci numbers. Note that the GCD algorithm, when given two subsequent Fibonacci numbers, will produce the Fibonacci sequence in reverse. Since we never reduce the pair by more than one times the smaller number, we will have particularly many repetitions.
A few of you neglected to comment on your results or to suggest which method was clearer. Surpisingly, those who found recursive faster noted that the iterative method was clearer and vice versa.
3. Semantics of For
There are a number of issues you need to consider in describing the
for statement and many of you neglected one or more of
these issues. Some particularly important points include:
to vs. down to. Some of you
suggested that down to was automatically used whenever
the first bound was greater than the second.
step. Of particular concern is what happens
when the step does not evenly divide the difference between the bounds.
Note that the original Pascal did not include step for
just this reason.
to
form). However, this description is not correct when used with
subrange variables. For example, in
var x: 1..100; for x = 1 to 100 do begin ... endit is illegal for
x to have the value 101.
4. Coercion in Pascal
There were a variety of terms used to describe this problem. Most of you indicated that it violates uniformity.
Why is it a bad idea to convert reals to integers? A number of you noted that it loses precesion, but one would have to assume that a real converted to an integer would lose its fractional portion. A more significant problem is that we have to formally define what the conversion means for a wide variety of situations. In particular, truncation is dangerous, since approximation is often used for real numbers. Hence, we might find that the following code prints 1 instead of 0.
var i,j: integer; var r: real; i := some large integer; r := i; j := r; write(i-j);It is also likely that we will encounter similar problems when rounding. Even when there is no fractional part, this may happen if the representation of reals uses fewer bits for the non-exponent part.
Importantly, real numbers and integers may cover different ranges (with real numbers traditionally covering wider ranges). By assigning reals to integers, we will need to worry about overflow.
Is there a better solution? Perhaps to require the same specifications
in both direction. That is, don't coerce integers to reals. Rather,
add a realify method (with a better name).
5. Simplifying a Language
Your ideas were generally good here. However, the criticism of "removing feature X forces us to rewrite existing code" is not a particulary deep one, as it applies to any change. A more useful comment would have been on decreased functionality, writability, or any other criterion. A few criticism showed little understanding of the purpose of the feature that you were removing; generally removing something because you don't understand why it's there is a bad idea. ("Hmmm, I don't think we need this large beam in the middle of this building.")
6. Extending a Language
Again, the ideas here were fairly interesting. A few of you neglected to reflect on the last part of the question: "What needs to be stated about the feature for those implementing or using the language to understand it unambiguously?" [Modified from Louden, p. 59, q. 7]
Disclaimer Often, these pages were created "on the fly" with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.
Source text last modified Mon Feb 2 10:45:29 1998.
This page generated on Wed Feb 4 09:52:34 1998 by SiteWeaver.
Contact our webmaster at rebelsky@math.grin.edu