Practice Final Exam Questions

Reviewed by Editorial Team
The ProProfs editorial team is comprised of experienced subject matter experts. They've collectively created over 10,000 quizzes and lessons, serving over 100 million users. Our team includes in-house content moderators and subject matter experts, as well as a global network of rigorously trained contributors. All adhere to our comprehensive editorial guidelines, ensuring the delivery of high-quality content.
Learn about Our Editorial Process
| By Gorin
G
Gorin
Community Contributor
Quizzes Created: 1 | Total Attempts: 137
| Attempts: 137 | Questions: 11
Please wait...
Question 1 / 11
0 %
0/100
Score 0/100
1. [8 points] Which of the following is true of the promises we studied and defined using my-force and my-delay in Racket?

Explanation

Evaluating (my-force (my-delay (lambda () e))) always produces the same result as evaluating e: This statement is true because the my-delay function delays the evaluation of the expression inside it until it is forced with my-force. Therefore, when we force the delayed expression, it will be evaluated and produce the same result as evaluating e directly.

Evaluating (my-force (my-delay (my-delay (lambda () e)))) will not evaluate e: This statement is also true because the my-delay function delays the evaluation of the expression inside it. However, when we force the delayed expression twice, it will only evaluate the inner delay once and not evaluate e.

Submit
Please wait...
About This Quiz
Practice Final Exam Questions - Quiz


These are the instructions that will also be on the real final, but of course this is just a practice final:You have 90 minutes to complete the exam.... see moreOnly your first submission will count toward your grade. You may use any course materials (videos, slides, reading notes, etc. ). You may use the ML, Racket, and Ruby REPLs. You may use text editors. You may use the standard-library documentation for the languages. You may not use the discussion forum. You may not use other websites related to programming. (Sites like dictionaries for translating English words are okay to use. ) see less

2. [5 points] Which of the following Racket functions correctly takes a stream s and returns a stream that repeats each stream element from s twice? So, for example, calling the function with the stream that generates 1 2 3 ... would return a stream that generates 1 1 2 2 3 3 ...

Explanation

The correct answer is the first option, which is (define (twice-each s) (lambda () (let ([pr (s)]) (cons (car pr) (lambda () (cons (car pr) (twice-each (cdr pr)))))))). This function correctly takes a stream and returns a stream that repeats each element from s twice. It does this by defining a lambda function that takes a stream and uses cons to create a new stream that repeats each element twice. The function recursively calls itself with the cdr of the original stream to continue generating the repeated stream.

Submit
3. [8 points] Let e be a Racket expression. Consider these two versions of function f:
(define (f) ; call this version A
   (let ([x e])
       (if x x 42)))
(define (f) ; call this version B
   (if e e 42))
Check the box below if and only if there exists any e such that the statement is true. Note different choices below can be true by choosing a different e for each, but in the code above we mean the same expression e wherever e appears.

Explanation

The answer "Calling version A is equivalent to calling version B" is correct because both versions of the function f have the same logic and will return the same result. The answer "Version A and version B both always return 42" is also correct because in both versions, if the value of e is truthy, it will be returned, otherwise, 42 will be returned.

Submit
4. [16 points] In this problem, suppose we add record subtyping and function subtyping to ML. Because ML records are immutable (there is no way to assign to a field after a record is created), depth subtyping is sound for records. So assume record subtyping supports width, permutation, and depth, and that function subtyping supports contravariant arguments and covariant results. For each of the function calls below, check the box if and only if the function call should type-check assuming these variables have the types indicated:
(* assume these variables are bound to functions with the given types; they are used below *)
val f1 : { a:int, b : { c:int, d:int } } -> { a:int } = ...
val f2 : { a:int } -> { a:int, b : { c:int, d:int } } = ...
val f3 : { a:int, b : { c:int, d:int } } -> { a:int, b : { c:int, d:int } } = ...
val f4 : (({ a:int, b : { c:int} } -> { a:int }) * int) -> { a:int } = ...
val r1 : { a:int } = { a = 1 }
val r2 : { a:int, b : { c:int} } = { a=1, b = { c=2 } }
val r3 : { a:int, b : { c:int, d:int}, e:int } = { a=1, b = { c=2, d=3}, e=4 }
val r4 : { a:int, b : { c:int, d:int, e:int }} = { a=1, b = { c=2, d=3, e=4} }

Explanation

not-available-via-ai

Submit
5. [5 points] Which of the following programming problems would lead to a solution using double dispatch in Ruby if the programmer wanted to maintain a "full" commitment to OOP?

Explanation

The correct answer is to provide classes that represent each of the "essential" amino acids, each with a method resultOfCombining that takes an argument that is another "essential" amino acid and returns the protein resulting from combining the two amino acids. This problem would lead to a solution using double dispatch in Ruby because the result of combining two amino acids depends on the specific combination of amino acids involved. By using double dispatch, the method can determine the appropriate combination based on the types of the two amino acids, allowing for a more flexible and extensible solution in an object-oriented manner.

Submit
6. [12 points] This question uses this Ruby code, where ... is assumed to be some correct code not relevant to the question.
class A
  def m1
    self.m2()
  end
  def m2
    ...
  end
end
module M
  def m3
    self.m4()
  end
end
class B < A
  def m2
    ...
  end
end
class C < A
  include M
  def m4
    ...
  end
end
class D < B
  include M
end 
For each Ruby expression below, check the box if evaluating the expression would lead to a method-missing error.

Explanation

Evaluating the expression B.new.m3 would lead to a method-missing error because class B does not define the method m4, which is called in the m3 method of module M. Evaluating the expression D.new.m1 would also lead to a method-missing error because class D inherits from class B, which does not define the method m1. Evaluating the expression D.new.m3 would also lead to a method-missing error because class D includes module M, which defines the method m4 that is called in the m3 method.

Submit
7. [10 points] For each of the following, check the box if and only if it is an accurate description of an advantage of static typing over dynamic typing.

Explanation

Static typing provides an advantage in the scenario where a function or method is designed to only accept values of a specific type. In such cases, there is no need to include a run-time type test within the function or method body, making it more convenient to implement. Additionally, if the return type of a function or method is changed, the static type-checker can identify all the callers that still assume the old return type, allowing for easier identification and resolution of potential issues.

Submit
8. [5 points] Suppose a MUPL interpreter implements lexical scope for function calls incorrectly by evaluating the function body using the environment where the function is called rather than where it is defined. Which of the MUPL programs below is a good test for this bug because (eval-exp ...) will produce the wrong answer if ... is replaced with the MUPL program. A few relevant Racket struct definitions for MUPL are repeated here as a convenient reminder:
(struct var  (string) #:transparent)               ;; a variable, e.g., (var "foo")
(struct int  (num) #:transparent)                  ;; a constant number, e.g., (int 17)
(struct fun  (nameopt formal body) #:transparent)  ;; a recursive(?) 1-argument function
(struct call (funexp actual) #:transparent)        ;; function call
(struct mlet (var e body) #:transparent)           ;; a local binding (let var = e in body) 

Explanation

The MUPL program (mlet "f" (mlet "x" (int 0) (fun #f "y" (var "x"))) (mlet "x" (int 1) (call (var "f") (var "x")))) is a good test for the bug because it involves nested function definitions and variable bindings. If the interpreter incorrectly evaluates the function body using the environment where the function is called rather than where it is defined, the value of "x" inside the inner function will be incorrect and the result will be wrong.

Submit
9. [12 points] Check a box if and only if it is an accurate description of Racket.

Explanation

not-available-via-ai

Submit
10. [14 points] Check the box if and only if the statement is true.

Explanation

In Ruby, a method can use yield to call the block provided by the caller even if the method did not indicate that it expected a block. This means that a method can still execute a block of code even if the caller did not explicitly pass a block to the method.

Ruby has a notion of subclassing but no notion of subtyping. This means that Ruby supports the concept of creating a new class that inherits properties and methods from a parent class, but it does not have the concept of subtyping, which is the ability to treat an instance of a subclass as an instance of its superclass.

Dynamic dispatch means that a call like self.foo in a method defined in class A could call code in a subclass of A that the writer of the class A code does not know exists. This means that when a method is called on an object, the appropriate implementation of the method is determined at runtime based on the actual type of the object, allowing for polymorphism and flexibility in object-oriented programming.

Submit
11. [5 points] Suppose we change ML so that its type system works as follows: If a function takes a tuple with n pieces, then you can call that function with any tuple with m pieces as long as m >= n. (At run-time, the extra tuple components would be evaluated before calling the function and then ignored by the function body.) We do not change what the ML type system is supposed to prevent except for this particular change of allowing tuples that are "too big" for function calls. Which of the following is true?

Explanation

not-available-via-ai

Submit
View My Results

Quiz Review Timeline (Updated): Nov 16, 2023 +

Our quizzes are rigorously reviewed, monitored and continuously updated by our expert board to maintain accuracy, relevance, and timeliness.

  • Current Version
  • Nov 16, 2023
    Quiz Edited by
    ProProfs Editorial Team
  • Dec 11, 2015
    Quiz Created by
    Gorin
Cancel
  • All
    All (11)
  • Unanswered
    Unanswered ()
  • Answered
    Answered ()
[8 points] Which of the following is true of the promises we...
[5 points] Which of the following Racket functions correctly takes a...
[8 points] Let e be a Racket expression. Consider these two...
[16 points] In this problem, suppose we add record subtyping and...
[5 points] Which of the following programming problems would lead to a...
[12 points] This question uses this Ruby code, where ... is...
[10 points] For each of the following, check the box if and only if it...
[5 points] Suppose a MUPL interpreter implements lexical scope for...
[12 points] Check a box if and only if it is an accurate description...
[14 points] Check the box if and only if the statement is true.
[5 points] Suppose we change ML so that its type system works as...
Alert!

Advertisement