Programming Languages (CSC-302 98S)

[Instructions] [Search] [Current] [Changes] [Syllabus] [Handouts] [Outlines] [Assignments]


Assignment Four: Control Structures

Assigned: Wednesday, March 4, 1998
Due: 11am, Friday, March 13, 1998

1. Parameter Passing

Devise a function, callby() in a generic imperative language that determines which calling strategy the language uses and returns a string corresponding to the calling strategy. You should feel free to use variables and helper functions.

It is likely that your function will have a structure like the following (which determines whether something is call-by-value).

function callby returns String
begin
  // Variable declarations
  int x = 3;
  // Call a function, affecting some but not all of the variables
  helper(x);
  // Determine the type of calling strategy by the effect on the
  // variable.
  if (x == 4) then
    return "call-by-value";
  else if ... then
    ...
  else
    return "call-by-???";
  end if
end callby
function helper(int param) returns nothing
begin
  param = 4;
end

2. Guarded Control

Often, we learn of a structure in one language that we'd like to use in another language. Some of us find the nondeterminism of guarded conditionals interesting, and might want to use it in our favorite languages.

Show how one might simulate guarded conditionals in a language of your choice. That is, come up with generic code that has the same effect as a guarded conditional. The structure should permit a number of guard/statement pairs (represented as you deem best) and execute some statement (not always the first) with a true guard.

You may make reasonable modifications to the semantics of guarded conditionals. For example, you don't need to have the program crash and burn if none of the guards hold. You may also choose whether or not all guards are evaluated. In all cases, you should make it clear what you decide.

3. GOTO Considered Essential

[This problem is modified from problem 12 on pp. 240-241 of Louden's Programming Languages: Principles and Practice.]

Dan has suggested that "all these control structures are a way for mathematicians to restrict what we programmers know how to do" (paraphrased and made somewhat more extreme). Others clearly feel the same way.

In responding to the original "GOTO considered harmful" article, a researcher named Rubin suggested the following code as a motivation for using GOTO.

  for i := 1 to n do begin
    for j := 1 to n do
      if x[i,j] <> 0 then goto REJECT;
    write("First all-zero row is: ',i);
    break;
REJECT:
  end;

4. Confusing Assignments

Substitute expressions for alpha and beta in the following so that the code will print Aagh. Neither of your expressions should have side-effects (except for the standard assignment statement side-effect of assigning to the l-value of the left-hand-side).

alpha = beta;
if (alpha != beta) then
  print "Aagh";
end

5. Iterative Merge Sort

The traditional merge sort algorithm has the following form:

function mergeSort(Vector v) returns Vector
begin
  // The empty vector is sorted
  if (v.length == 0) then return v;
  // A vector of size 1 is sorted
  if (v.length == 1) then return v;
  // Split the vector in half
  mid = v.length / 2;
  // Sort the two halves
  first = sort(v.subVector(0,mid));
  second = sort(v.subVector(mid+1,last));
  // And merge them together
  return merge(first,second);
end

An opponent of recursive algorithms might complain that this is a doubly-inefficient use of memory, as we're using extra memory for the merges and for the recursive calls.

In the language of your choice, rewrite this function so that it does no recursive calls, but still follows the same basic method of sorting (merging sorted subvectors to produce larger sorted subvectors). Turn in an appropriate example to demonstrate that it works correctly.

6. Initializations and Declarations

[Taken from the notes of John Stone.]

Some programming languages require initializations to accompany variable declarations. Summarize the principal arguments for and against such a requirement.

Extra Credit: Iterative Quicksort

For many algorithms that involve repetition, there is a straightforward translation between the imperative and recursive versions of the algorithm. However, this is not always the case. Consider the famous quicksort algorithm, which is traditionally expressed as:

Rewrite this algorithm in the language of your choice so that it has no recursive calls. You will, of course, need to fill in more details.


[Instructions] [Search] [Current] [Changes] [Syllabus] [Handouts] [Outlines] [Assignments]

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 Mar 9 16:32:11 1998.

This page generated on Mon Mar 9 16:35:20 1998 by SiteWeaver.

Contact our webmaster at rebelsky@math.grin.edu