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
- provide explicit and well marked answers to the questions asked,
and
- turn in a complete program with test runs.
Problem 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.
- 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.
- 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.
- 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.
- Using the union type constructor, define a single type
called StrorIntType that could be used for representing
integers or strings.
- 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.
- 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.
- 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.
- 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.
- 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.
- Modify the function you defined for appending two lists to deal
with lists represented in the present fashion.
- 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.
- (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