CSC 123/252 Scary Test A scary test will make you study really hard for the real test. Give yourself about 50 minutes to complete the test. 1. Explain the difference between the F# functions f and g below: let f x0 = fun y -> let mutable x = x0 x <- x+y x let g x0 = let mutable x = x0 fun y -> x <- x+y x Determine the output of let f1 = f(2) let g1 = g(2) printfn "%d" (f1(1)+f1(1)); printfn "%d" (g1(1)+g1(1)); 1b. which of the above functions can be written in Gnu C? Explain. 2. Someone has invented a new language called C** that's claimed to be the best ever. The syntax certainly looks familiar: int x = 1; // declares and initializes global variable int f(int y) { return y+1; } // define function with argument y void MAIN() // MAIN must be in all capitals! { int x = 2; // declares "local" variable inside main stdout << f(x) << endl; // fantastic new way to print! // this will print 3 in C** } But you didn't find any documentation on whether this language uses static or dynamic scoping. Devise an experiment (write a program in C**) to find out. That is, write one program that will behave differently depending on the scoping rule. Be clear as to how to interpret the result of your experiment. 3. Explain why or why won't the following JAVA generic class compile class A { static T x; } // will this compile? 4. Explain why Object[] A = new String[4]; should or should not compile (regardless of whether it does) 5. Determine the output of the following Java program class A {} class B extends A {} public class goodquestion { public int f(A x) { return 1; } public int f(B x) { return 2; } public static void main(String[] args) { A n = new B(); goodquestion gq = new goodquestion(); System.out.println( gq.f(n) ); }//main } 6. Given the following definition of linked lists in F#: type List<'T> = Nil | Cons of 'T*List<'T>;; Write a tail recursive function to find the length of a list. 7. Given two Option objects a and b, explain what, if anything, is wrong with the following: a |> Option.bind (fun x -> b |> Option.map (fun y -> x+y)) |> Option.iter (printfn "sum is %d") 8. In F#, a possibly infinite stream of values can be represented by a function of type unit -> Option<'T>. For example, the following creates a stream of odd values up to 99. The stream ends when None is returned. let odds() = let mutable n = 1; fun () -> if n>99 then None else n <- n+2; Some(n-2) 8a. Write a function take_while that modifies streams by taking a predicate and returning only those values of the stream that satisfy the predicate. You may not call the Option.get function. For example, odds() |> take_while (fun x -> x<10) should return the stream 1 3 5 7 9 The function must work on any stream and any predicate. 8b. (harder) Write a function foreach that takes an "action" of type 'T -> unit, and a stream of type unit -> Option<'T> and calls the action function on each value returned by the stream, until the stream ends. odds() |> foreach (printf "%d ") should print 1 3 5 7 9 11 ... 9. Given type Number = Integer of int | Rational of int*int let times a b = match (a,b) with | (Integer x, Integer y) -> Integer (x*y) | (Integer x, Rational(n,d)) -> Rational(x*n,d) | (Rational(a,b), Rational(c,d)) -> Rational(a*c,b*d) | (Rational(n,d), Integer x) -> Rational(x*n,d) let inverse a = match a with | Integer x when (x<>0) -> Some(Rational(1,x)) | Rational(n,d) when (n<>0) -> Some(Rational(d,n)) | _ -> None Write a function divide that divides one Number by another by multiplying the number with the inverse of the other number, if it exists. The function should also return an Option. You may not use Option.get 9b. Challenge: write the function without pattern matching (use map/bind).