***Erlang programming - What does the test() method return in the following programs? Part I) for(Max,Max,F) -> [F(Max)]; for(I, Max, F) -> [F(I)|for(I+1,Max,F)]. test() -> L = for(1,10,fun(X) -> 1 end), lists:map(fun (X) -> x*2 end, L). Answer: [2,2,2,2,2,2,2,2,2,2] Part II) % same for() definition as above test() -> L = for(1,10,fun(X) -> X end), lists:fold_left(fun(A,X) -> A+X end, 0, L). Answer: 55 - Consider the following Java code: interface Shape { double area(); } class Circle implements Shape { final double radius; Circle(double radius) { this.radius = radius; } double area() { return Math.PI * radius * radius; } } class Rectangle implements Shape { final double height, width; Circle(double height, double width) { this.height = height; this.width = width; } double area() { return width * height; } } class Square implements Shape { final double side; Square(double side) { this.side = side; } double area() { return side * side } } Part I) Write equivalent code in Erlang. In particular, you want to write the following functions: new_circle(R) returns a circle (represented as you like) with radius R new_rectangle(W,H) returns a rectangle with width W, height H new_square(S) returns a square with width and height S area(Shape) returns the area of the given shape, assumed to have been created by one of the constructors above Answer: new_circle(R) -> {circle,R}. new_rectangle(W,H) -> {rectangle,W,H}. new_square(S) -> {square,S}. area({circle,R}) -> 3.1459 * R * R; area({rectangle,W,H}) -> W * H; area({square,S}) -> S * S. Part II) The Java code could be simplified a little by using inheritance, replacing the definition of class Square with the following: class Square extends Rectangle { Square(double side) { super(side,side); } } How can you effect a similar change in the Erlang code above; that is, change the implementation of new_square and area to reuse the code you wrote to handle rectangles. Answer: new_circle(R) -> {circle,R}. new_rectangle(W,H) -> {rectangle,W,H}. new_square(S) -> new_rectangle(S,S). area({circle,R}) -> 3.1459 * R * R; area({rectangle,W,H}) -> W * H. Part III) Write the code for your last answer OCaml. How does it compare to the Java and Erlang code? Can you give reasons for the differences in the amount of code? What do you gain in the Java and Ocaml cases for all the extra code you write? What do you lose in the Erlang case for not having to write as much? Answer: Here's the Ocaml code: type shape = Circle of double | Rectange of double * double let circle r = Circle r let rectangle w h = Rectangle(w,h) let square s = Rectangle (s,s) let area s = match s with Circle r -> 3.14159 *. r *. r | Rectangle (w,h) -> w *. h This is pretty close to the Erlang code, but we must declare a type for shapes first. The area function uses OCaml's pattern matching syntax, which is slightly different from Erlang's. Thus the only real difference is the need for a type declaration. However, in Ocaml, you will identify programs with type errors before you run them, e.g., where you pass 1.0 to area, instead of a shape. The same is true of the Java program. On the other hand, the Java program is a lot more verbose, since you have to write more of the types down; in Ocaml many of them are inferred. Java's object-oriented style does not work as well with this example either: you end up spreading the area() function around to three different places in the program, so there is a lot of duplicated boilerplate. On the other hand, you get a more object-centric view, and perhaps that helps you understand the program better.