[UMN logo]

CSCI 5106: Programming Languages
Spring 2006, University of Minnesota
Homework 5


Posted: March 21, 2006
Due: Before class on April 4, 2006


Note: The three programming problems in this assignment are to be done in the language C. In each case you must


Problem 1

  1. Define a type that is capable of representing lists of integers of arbitrary length. Unlike in Homework 1, you must use a linked list structure in the representation and not an array.

  2. Define a function called append that takes two lists of integers and returns a new list that is the result of appending the two given lists.

  3. Define a function called map that takes a function on integers and a list of integers represented using the type you described in the first part and that returns the list of integers obtained by applying the given function to each element of the given list. For example, if the function was one that squares integers and the given list of integers is 3,5,7, then the value returned should be the list 9,25,49. There are a variety of functions on integers that you can use to test your type and your definition of map.

  4. Define a function called printlist that can take a list of integers and display it to the terminal. One possible format for the display may be like that of ML or Prolog: the sequence of elements separated by commas and enclosed by square brackets as illustrated below:
           [1,2,3,7,6]
    
    This format is not fixed in stone. You can choose any other that you find convenient but make sure to explain it. Also note that this function will come in handy during testing.
If you have not programmed much in C, you may wonder when doing the third part if you can really pass functions as parameters. The answer is you can do this by using pointers to the function. For example consider the following code:
   typedef  int (*CmpFunType)(int i, int j);

   int afunction(int a, int b, CmpFunType Comp)
   { return (*Comp)(a,b); }

   int lss(int a, int b)
   { return (a < b); }
The first line here defines CmpFunType to be a type corresponding to a pointer to a function that takes two integers as arguments and returns an integer as a result. The header of the function afunction indicates that this function takes two integers and an object of CmpFunType as arguments. The last of these is evidently expected to be a pointer to a comparison function. Relative to these definitions, the expression afunction(3,5,&lss) evaluates to 1 (standing for true) and the expression afunction(5,3,&lss) evaluates to 0 (standing for false). Notice the use of * in the definition of afunction to dereference the pointer to the function, and of & in the calls to extract the address of the lss function. You can actually leave the dereferencing and the address extraction operators out and C will interpret the code as if they are there, but the code I have given you makes what is going on transparent. You can find more information on this kind of use of pointers to functions in the online guide to programming in C.

As a solution to this problem, you must provide a program containing the definitions of the type and the functions asked for and also tests of the functions.


Problem 2

Lists are, of course, not restricted to having only integer values for their elements. They could, for instance, have strings as their elements as well.
  1. Using the union type constructor, define a single type called StrorIntType that could be used for representing integers or strings.

  2. Using the type you have described in the first part, generalize the type declaration in Problem 1 to one that is capable of storing lists of either integers or strings.

  3. Modify the function you defined for appending lists in Problem 1 so that these will now work on either integer lists or string lists using the representation you have just devised.

  4. Similarly modify the function for printing lists. In this case, note that the function will have to be sensitive to the type of list element. One convenient way of realizing this is to pass to it as an extra argument a pointer to a function for printing an element. Doing it this way will make the progression to the printing function needed in the next problem most easy.

  5. Similarly modify the function map that you defined in Problem 1 so that this now works with either integer or string lists and can return either integer or string lists as a result. The function on integers/strings that is provided as input would likely have to be `packaged' as one that takes a StrorIntType and returns a StrorIntType. As one test for your function, use it on a list of strings to return a list of the lengths of each of these strings.
You may wonder how to represent strings in C. If you include the string library by placing the line
  #include  <string.h>
at the beginning of file containing your program, you will get to use the type string for representing strings. You also get to use the function strlen that takes a string as an argument and returns its length as well as many other useful functions on strings. Some of these are described in the section on the string library in the online guide to programming in C.


Problem 3

In Problem 2, we assumed that we knew beforehand all the types of data for which we needed lists and these were actually finite in number. Suppose now that we do not know this. This would happen if, for instance, you wanted to construct a library implementation of the list type that a user may later employ with an element type of his/her choosing.
  1. Define a type that is capable of representing lists of arbitrary types of elements. Hint: You will have to somehow reduce all elements to the same size and also `forget' their types for this to work in C.

  2. Modify the function you defined for appending two lists to deal with lists represented in the present fashion.

  3. Similarly modify the printlist function. Note that in this case you really will have to pass in a function that can be used to print each element. Since printlist does not know the type of the elements in the list argument beforehand, it will have to have a formal function argument that can print any type of element. When using printlist in a specific case, you will have to cast the relevant function to this more general type. You can find information on how to do this kind of type casting in the online C programming guide.

  4. (Extra Credit) Modify the definition of map so that it now works on lists whose element type may be arbitrary. As one suggestion of a test, you might use it on a list of lists of integers to return a list of their lengths.


Problem 4

Problems 1, 2 and 3 represent different ways of realizing a list data structure in C. Even though we defined a type for only integer lists in Problem 1, we could use the same method also to define a type for string lists and so on. In Problems 2 and 3 we attempted to build some of the polymorphism directly into our types. Briefly critique the different approaches to realizing list structures. Some things to comment on are flexibility, efficiency (that could include space and time), type safety, etc. This is not an exhaustive list. Your grade will depend on how creatively you think, how many valid points you make and how well you express your thoughts.


Last updated on March 21, 2006 by gopalan@cs.umn.edu