CS 331 Spring 2025 > Exam Review Problems, Set D
CS 331 Spring 2025
Exam Review Problems, Set D
This is the fourth set of exam review problems.
Problems
Review problems are given below. Answers are in the Answers section of this document. Do not turn these in.
Answers
- Overloading happens when a single name in a single namespace refers to multiple entities.
- Here are two examples.
- In Haskell, operators other than ones defined in the standard can be overloaded. In C++, only standard operators can be overloaded.
- Also in Haskell, functions can be overloaded on their return types. That is, we can write two functions that have the same name and the same parameter types, but which differ in their return types. In C++, functions can be overloaded only on the number, types, and passing methods of their parameters.
- The scope of an identifier is the code from which the identifier is accessible.
- An identifier has a scope.
- Here is a Lua function definition.
In the above code, the scope of the identifierfunction ff() local n n = 42 return n end
n
is the body of the function, that is, the three indented lines between “function ff()
” and “end
”.
- An expression is an entity that has a value.
- In Lua, the expression “
1+2
” has typenumber
.
- A literal is a representation of a fixed value in source code. The value itself is represented, not an identifier bound to the value, and not a computation whose result is the value.
- Many examples are possible.
Here are several.
"abc"
is a Lua literal of typestring
. (It is also a Haskell literal of typeString
.)[[abc]]
is a Lua literal of typestring
.42
is a Lua literal of typenumber
. (It is also a C++ literal of typeint
.)#t
is a Scheme literal of Boolean type.
- Binding is associating a variable with a value. Once this is done, the variable is said to be bound.
- A variable that is not bound is said to be free.
- In Prolog, we can check whether a variable is bound
using the predicates
var
/1 andnonvar
/1. When passed a bound variable, the former fails, while the latter succeeds. When passed a free variable, the reverse happens.
- A thunk is a reference to code whose execution computes a value.
- In Haskell, the implementation of lazy evaluation typically involves thunks. A thunk is used as a placeholder for a value that has not been computed yet. When the value is needed, the code referenced by the thunk is called, and the thunk is replaced by the resulting value.
- Reflection is the ability of a computer program to deal with its own code: examining the code, looking at its properties, possibly modifying it, and executing the modified code.
- The Scheme programming language offers excellent support for reflection. It does this primarily with macros.
- Scheme is based on the programming language Lisp.
- What sets Scheme apart from most List implementations is its minimalist design philosophy.
- Scheme has dynamic typing.
- Scheme’s typing is implicit.
- Scheme has a fixed set of types.
- Scheme types do not apply to variables; only values have types.
-
#t
. This is the Boolean true literal.#\b
. This is the'b'
character literal."x"
. This is a string of length 1 holding the'x'
character.1/2
. This is an exact rational number literal with value 1/2.;ab
. This is a comment.
-
- A Scheme function (that is, procedure) definition
is generally introduced by
define
orlambda
. However, these are not keywords in Scheme. - True. Scheme has first-class functions.
- Scheme’s first-class identifiers are called symbols.
- True. Scheme allows for lambda functions.
- False. By default, Scheme does eager evaluation.
- Lazy evaluation can be done in Scheme using promises.
A promise is created with the macro
delay
. It is evaluated using the procedureforce
.
- A Scheme function (that is, procedure) definition
is generally introduced by
- A Scheme atom is a single value that does not involve any of the constructs used to form lists.
- Scheme has two non-atom types: pair and null.
- Scheme has no special syntax for binary operators.
The ordinary syntax for procedure calls is used.
For example, to check whether two numbers
a
andb
are equal, we would do “(= a b)
”. - We covered two Scheme conditional flow-of-control constructs.
One is macro
if
, which takes a condition and two expressions. If the condition is truthy, then It evaluates and returns the first expression; otherwise it evaluates and returns the second expression. The second is macrocond
, which takes one or more two-item lists, each containing a condition and an expression. It evaluates the conditions in order, stopping when one is truthy, and then evaluating and returning the corresponding expression. The last condition may be replaced byelse
, which counts as truthy. - In Scheme,
#f
(Boolean false) is falsy. All other values are truthy.
- We covered two Scheme conditional flow-of-control constructs.
One is macro
- In Scheme, a single quote suppresses evaluation.
- A single quote is an abbreviation for a two-item list beginning
with
quote
. For example, “'abc
” is an abbreviation of “(quote abc)
”.
- Names of Scheme predicates commonly end in a question mark
(
?
). - One example is the predicate
number?
. This takes one argument and returns#t
(Boolean true) if the argument is of a number type. (Many other answers are possible, such as Scheme type-checking predicates likenull?
,promise?
, and others, along with other standard predicates:list?
,even?
, etc.)
- Names of Scheme predicates commonly end in a question mark
(
- The normal way for Scheme to evaluate a list is, first, to evaluate each list item, and, second, to call the value of the first item as a procedure, with the values of the other items as its arguments.
- The exception to the normal list evaluation rule is when the first item is a macro. In this case, the other items are passed to it unevaluated.
- Scheme
eval
evaluates the expression passed to it. eval
does its work twice, because it is a procedure. First, the argument is evaluated as part of the normal evaluation rule for lists. Theneval
is called, and the result is evaluated again.
- Scheme
- We can use local variables in Scheme with the macro
let
(and its variants, likelet*
). This takes a list of two-item lists and an expression. Each two item list is a symbol and an expression. Each symbol is set to the value of its expression—thus binding a local variable—and then the expression is evaluated with each symbol having its value. - If we insert a symbol as the first argument in a
let
, then that symbol becomes the name of a local procedure. Calling this procedure restarts thelet
; the values of the various local variables are arguments.
- We can use local variables in Scheme with the macro
- When given a nonempty list, Scheme
car
returns its first item.cdr
returns a list of all the other items. - Scheme
car
andcdr
each take a pair.car
returns its first item (“left child pointer”), whilecdr
returns its second item (“right child pointer”).
- When given a nonempty list, Scheme