CSCI 330: Spring Final Exam
Sections S18N01-S18N02 (Dr. Wessels)

Question Mark
1. strengths/weaknesses of lisp and C++
[10 marks]
 
2. common lisp and imperative languages
[10 marks]
 
3. variadic functions
[10 marks]
 
4. higher order functions in C++
[10 marks]
 
5. regular expressions as a datatype
[10 marks]
 
6. type-safe unions
[10 marks]
 
7. smart pointers and memory management
[10 marks]
 
8. nested subroutine definitions
[10 marks]
 
9. typechecking and function pointers
[10 marks]
 
10. user defined data types
[10 marks]
 
Exam Total (Best 9)

[90 marks]

 

 

Question 1: lisp vs C/C++, part I [10]

(i) Describe things that are easy to do in common lisp but difficult to do in C++, and provide a lisp code segment illustrating the idea.

(ii) Describe things that are easy to do in C++ but difficult to do in common lisp, and provide a C++ code segment illustrating the idea.

Question 1 cont.

Question 2: lisp vs C/C++, part II [10]

Of the three traits/features listed below, which would you regard as common lisp's greatest advantage over typical imperative languages, explain why, and provide a lisp code segment illustrating your point:

  1. homoiconicity (the ability to treat all its own source code as data, using the same representation)
  2. its read function
  3. its support for both functional and imperative programming

Question 2 cont.

Question 3: lisp vs C/C++, part III [10]

In the labs this semester we considered approaches for implementing variadic functions in lisp (&res), C (the stdargs library), and C++ (templates). Compare the strengths and weaknesses of each of the three approaches. (Short examples are provided below using sum functions).

; lisp version
(defun sum (first &rest other)
   (let ((tmp 0))
      (cond
          ((not (numberp first)) 'err)
          ((null other) first)
          (t (setf tmp (sum other))
             (if (numberp tmp) (+ tmp first) 'err)))))

/* C version */ double sum(int count, ...) { va_list args; va_start(args, count); float total; total = va_arg(args, double); for (int i = 1; i < count; i++) { total += va_arg(args, double); } va_end(args); return total; }
// C++ version template<typename T> T sum(T x) { return x; } template<typename T, typename... Args> T sum(T first, Args... args) { return first + sum(args...); }

Question 3 cont.

Question 4: [10]

In the labs this semester we considered approaches for implementing a funcall-like higher order functions in C++ (example shown below). Compare the strengths and weaknesses of this approach to the funcall that is provided as part of common lisp.

// funcall for functions on one arguments
template <class T1, class T2>
T1 funcall(T1 (*f)(T2), T2 x)
{
   return (*f)(x);
}

// funcall for functions on two arguments
template <class T1, class T2, class T3>
T1 funcall(T1 (*f)(T2,T3), T2 x, T3 y)
{
   return (*f)(x, y);
}

Question 4 cont.

Question 5: [10]

Regular expression handling is a built-in feature of many scripting languages (e.g. bash, perl, ruby), but it is supplied via a library in many compiled languages (e.g. C, C++, Java).

(i) Discuss the advantages and disadvantages of supplying regular expression handling as a built-in part of a high level language.

(ii) Discuss reasons why scripting languages in particular tend to include regular expression handling as a built-in part of the language.

Question 5 cont.

Question 6: [10]

In lectures, we briefly considered unions as a datatype, specifically as they are provided in C/C++ (a short example is provided below).

(i) Explain how/why C/C++ unions are not "type safe", and provide a code example illustrating your point.

(ii) Discuss the advantages and disadvantages of having such similar syntax between structs and unions.

union Date {
   std::string asStr; // represented as string, e.g. "Dec. 31, 1999"
   int asDDMMYY[3];   // represented using 3 ints, e.g. { 12, 31, 1999 }
   int asJulian;      // represented using single int in range 1..366, e.g. 365
};

Date someday;
someday.asJulian = 207;

Question 6 cont.

Question 7: [10]

Discuss the issues that "smart pointers" are meant to address, and the ways in which the templated shared_ptr and weak_ptr classes in C++ succeed and fail to address these issues.

Question 7 cont.

Question 8: [10]

Some programming languages permit nested function declarations (declaring one function inside the body of another). Suppose this were permitted in C, such as with the example shown below. Discuss the language design and implementation issues associated with such a capability.

int f(int x, int y)
{
   // local functions g
   void g(int a)
   {
       // does something with parameter a
   }

   // body of f, presumably calls g at some point
}

Question 8 cont.

Question 9: [10]

Discuss the strengths/weaknesses of the C/C++ syntax used for function pointers, and how it supports compile-time type checking.

 

Question 10: [10]

Some compiled languages provide the user with the explicit ability to define new named data types (e.g. C's typedef).

(i) Provide some specific examples of instances in which typedefs are useful for a programmer.

(ii) Discuss the language design/implementation issues associated with incorporating typedefs into a language.