2024 November 19,

CS 251: Exam C Practice

Carleton College, Fall 2024, Dr. Joshua R. Davis, , CMC 324, x4095

Exam C is scheduled for Saturday November 23, 8:30 AM – 11:00 AM, in our usual room. It should be about the same length as Exam A and Exam B, or maybe one page longer. I reserve the right to ask questions about the earlier parts of the course. In fact, I'm planning to ask one or two such questions. But mostly the exam will be focused on recent material, that wasn't tested on Exam A or Exam B. Here is a brief outline of the topics we're covering these days.

For the OOC mini-project, you are not expected to know the details of using the variable-arity machinery of stdarg.h. You are not expected to understand the details of the regular expressions used in precompiler.py. You are not expected to have the example classes Integer, Double, String, and Approximation memorized, but you are expected to vaguely know what they do. Unless I'm forgetting something, everything else is fair game.

You are permitted, but not required, to bring a crib sheet of notes. Here are the rules.

  1. You must write/draw/type the sheet yourself. (The intent of this rule is for you to incur the educational value of making the sheet.)
  2. It's one standard (8.5 x 11 inches, A4, or smaller) sheet of paper. You may use both sides. It must be on paper, not an electronic device. (The intent of this rule is for you not to have a huge amount of material, such as an entire book, or a large object, such as a poster.)
  3. No sharing sheets during the exam. (The intent of this rule is to prevent communication among students.)

Follow not just the rules but also their intents. When in doubt about whether something is allowed, ask me. :)

During reading days and exam days I will have the following office hours (and not my usual ones):

Here are some study questions for Exam C. I might add more later. When I refer to OOC, I am referring to the final version (hCosmetic).

A. Of the five kinds of polymorphism that we have discussed, which ones does OOC exhibit?

B. In OOC, what does new do, before it calls initialize? Why is that work done in new rather than in initialize?

C. In OOC, the struct that defines instances of a subclass must have, as its first member, the struct that defines instances of the superclass. Why?

D. Imagine an Array class for OOC, that contains arbitrary objects and is resizable. Does it have a superclass? What methods does it have? Write the method that sets the object at index i of the array. Be careful!

E. In OOC, suppose that we end up with a deep class hierarchy, where ClassZ subclasses ClassY, which subclasses ClassX, ..., which subclasses ClassA, which subclasses Object. And none of these classes override Object's retain method. And an instance of ClassZ is retained. What is bad about this situation? How could we improve OOC to handle this issue? Specifically, I'm thinking of writing a function close(), which takes as input a Class that has already been built, and modifies it in kind of an expensive way, so that subsequent uses of the class do not exhibit the issue. What does close() do?

F. What is the biggest fundamental weakness of reference counting, as a strategy for managing graphs of objects in memory? Has this weakness been exhibited by any of the code that we've written in the OOC mini-project? If so, then which code? If not, then describe new code that would exhibit this weakness.

G. In Python, classes are objects; they are instances of the class type. In OOC, classes are not objects; they are not instances of any class. What would it take, to make a class for them? Is it a small or large amount of work? (And does it seem useful to you?)

H. In OOC, suppose that I have an object myObject of class MyClass, which has a method myMethod. This myMethod takes as input self (of course) and another object and returns as output self. Will the first line of code below precompile? If so, to what? If not, why not? Answer the same questions for the second line of code below, too.

(myObject^myMethod(myObject))^myMethod(myObject);
myObject^myMethod(myObject^myMethod(myObject));

I. In Objective-C, method names are precompiled to selectors, which are integers. So, in a sense, method names themselves are syntactic sugar. Whoah. Anyway, how would adding this feature to OOC improve OOC?

J. Suppose that I give you an example tail-recursive function. How do its local frames look, if tail recursion is not optimized? And how do they look if it is optimized?

K. Suppose that I give you an example recursive function. Is it tail recursive? If not, then rewrite it to be tail recursive, or explain why that can't be done. (In general, this rewriting can be very difficult. I would only ask it only for a small example that I considered doable.)

L. In Assignment P, I make three distinctions about function-like entities:

Draw a Venn diagram indicating how they relate to each other. For example, is every keyword built-in? Is every keyword not built-in? Is every primitive a function? And so forth. (It might help if you first clearly define each of the three distinctions.)

M. One of my goals for Exam C is to check that all students have been fully engaged with the Scheme interpreter project. You can expect at least one question about the implementation of a Scheme feature in Assignments I–P. Here's an example: What's the difference between a primitive function and a non-primitive function? Your answer should include discussion of local frames created during function application.

N. ...