Final Review A: Questions

RFa.1.

Given the below pair of Erlang function definitions, what is the value of g([5, 7, 11])?

f(_, []) -> [];
f(X, [H | T]) -> [H + X | f(X, T)].

g([]) -> [];
g([H | T]) -> [H | f(H, g(T))].
RFa.2.

The below Smalltalk code creates an array with three numbers (2, 3, 5) and then adds the numbers together.

nums := Array with: 2 with: 3 with: 5.
total := 0.
nums do: [:x | total := total + x].
total

A programmer comes along and suggests removing the nums variable and instead combining the first and third lines as follows.

total := 0.
Array with: 2 with: 3 with: 5 do: [:x | total := total + x].
total

What is wrong with this fragment, and how can it be repaired to execute correctly while still combining the first and third lines?

RFa.3.

Recall that once created, a Smalltalk block may be called using its value:value: method. For instance, “[:x :y | x + y] :value 5 :value 7” is 12. Complete the below Smalltalk method for the Array class so that it performs a reduce akin to Haskell's foldl function; for instance, “nums reduce: [:x :y | x + y] start: 0” should manage to find the sum of all numbers in nums.

fold: block start: init
RFa.4.

What distinguishes the * and *. operators in OCaml?

RFa.5.

Consider the following two OCaml object definitions and function definition.

let a = object
    method transform x = 2 * x
end;;

let b = object
    method square x = x * x
    method transform y = self#square y + 5
end;;

let transform2 x z = x#transform (x#transform z);;

OCaml is strongly typed: On compiling transform2 it will infer the function's type immediately. Nonetheless, both “transform2 a 3” and “transform2 b 3” will execute. Describe how the type of transform2 allows this even though there is no explicit link between transform2, a, and b.

RFa.6.

What is displayed by the following Dart code?

var callbacks = [];
for (var i = 0; i < 3; i++) {
    callbacks.add(() => print(i));
}
for (var j = 0; j < 3; j++) {
    var c = callbacks[j];
    c();
}
RFa.7.

Scala actors and Dart isolates are similar in that both entities can send and receive messages. What distinguishes them?

RFa.8.

What is returned by q(1, -2, -3) based on the following Go function definition?

func q(a, b, c float64) (x, y float64) {
    d := math.Pow(b * b - 4 * a * c, 0.5);
    x = (-b + d) / (2 * a);
    y = (-b - d) / (2 * a);
    return;
}
RFa.9.

Go uses both := and = for assignment statements: both “x := 3” and “x = 3” are valid ways to assign the value 3 to x. What distinguishes them?

Final Review A: Solutions

RFa.1.
[5, 12, 23]
RFa.2.

In the initial program, we used the Array class object's with:with:with: method, which created an individual Array object. We then used the do: method of that created object.

In the second fragment, the Smalltalk interpreter reads this as executing a with:with:with:do: method for the Array class object. The Array class object does not have such a method. The solution is to insert parentheses so that do: is still called on the value returned by with:with:with.

(Array with: 2 with: 3 with: 5) do: [:x | total := total + x].
RFa.3.
fold: block start: init
    cur := init.
    self do: [:x | cur := block value: cur value: x].
    cur.
RFa.4.

The * operator is for multiplying integer values, while *. is for multiplying floating-point values.

RFa.5.

The type of transform2 is object method transform : int -> int end -> int -> int”. This allows transform2 to receive any object that supports a transform method that takes an int parameter and returns an int. Both a and b have such a method, so we can validly pass either a or b as the first argument to transform2.

RFa.6.
0
1
2
RFa.7.

In Scala, the different actors run within the same memory space, and you can easily create two different actors that both access the same memory; it is up to the programmer to ensure that the actors access shared memory legally. In Dart, each isolate runs within its own memory space, which makes two isolates accessing the same memory impossible. (Erlang's actors work in different memory spaces as well.)

RFa.8.

It returns the pair of values 3 and −1.

RFa.9.

We use := to simultaneously declare and initialize a variable (with the variable's type inferred from the righthand value), whereas = assigns to a previously declared variable. Thus x = 3 is legal only if x has previously been declared, whereas x := 3 is only legal if the variable x has not previously been declared in the scope.