# Lab 2: Introduction to OCaml *CSci 2041: Advanced Programming Principles, Spring 2017* **Due:** Friday, January 27 at 5:00pm. You should be able to complete lab work during the lab. But occasionally some work may not get completed, thus this due date. # Introduction ### Goals of this lab: + In this lab you will write a few functions in OCaml to begin the process of learning how best to use it. + You will create a file named *lab_02.ml* in a *Lab_02* directory inside your individual class repository. Since we use some scripts in grading different aspects of your work it is critical that you name your directories and files exactly as specified. # Getting started. In your individual repository, make a directory named *Lab_02* and change into it: ``` % mkdir Lab_02 % cd Lab_02 ``` Create an empty file with the name *lab_02.ml*: ``` % touch lab_02.ml ``` It is in this file that you will put your solutions to the programming problems below. In a separate terminal window, run ``utop`` (the system used in lecture) or ``ocaml`` to start the OCaml interpreter. To load the contents of your file type ``` #use "lab_02.ml" ;; ``` at the ``#`` prompt. As you edit your file you'll need to do this again each time to load your changes. # OCaml programming Some of the functions that you are asked to solve below are similar to ones we've solved in class. These can be found in ``simple.ml`` in the ``code-examples`` directory of the public repository. Open another tab in your browser and you can see that file [here](https://github.umn.edu/umn-csci-2041S17/public-class-repo/blob/master/SamplePrograms/simple.ml). ### #1 Circle area, version 1 Write a function named ``circle_area_v1`` with the type ``float -> float``. This function should take as input the **diameter** (not the radius) of a circle and compute its area. For this version, do not use any nested let-expressions or function calls; only use literals like ``3.1415`` and floating point operators such as ``*.``, ``+.``, or ``/.``. For example, ``circle_area_v1 2.5`` should evaluate to about ``4.90``. ### #2 Circle area, version 2 Now write another version of this function, this time named ``circle_area_v2`` with the same type as ``circle_area_v1``. This version, however, must use a nested let-expression to define the constant ``pi`` to have the appropriate value. If there are any computations that are duplicated (perhaps computing the radius from the diameter provided as input) use a nested let-expression to give that sub-computation a name and use it accordingly in the computation. ### #3 Product of a list of elements In lecture, we wrote a function to compute the sum of all the values in a list of integers. It had the type ``int list -> int``. Write a similar function named ``product`` that computes the product of the values in a list of integers. It will have the same type as the sum function. For example, ``product [2; 3; 4]`` should evaluate to ``24``. ### #4 Sum of differences For this problem, you are to write a function that again has the type ``int list -> int``. It must be called ``sum_diffs`` and it will compute the sum of the differences between all successive pairs of numbers in the list. For example, ``sum_diffs [4; 5; 2]`` will evaluate to ``2``. You just write a recursive list-processing function for this task, despite the fact that some arithmetic simplification of the computation (in the case above it would be (4-5) + (5-2)) would let us do the computation in just one subtraction operation. Write the function so that it carries out the operation naively and computes the difference between each successive pair of numbers. You may assume that this function will only be passed lists of length 2 or more, so you don't need patterns to handle, for example, the empty list. Instead, our "base case" will be a pattern that matches a 2-element list, like the following: ``` | x1::(x2::[]) -> x1 - x2 ``` This pattern has something more complex than a simple name to the right of the ``::`` cons constructor. It has another nested pattern that matches a list of one element. Together, this pattern only matches lists with exactly 2 elements. Note that the parenthesis are not required here; they only make it explicit that the cons constructor is right associative. You will also need and another pattern that matches lists of 2 or more elements. This second pattern will need to bind 2 elements of the list some names so that your expression can compute their difference. It will be similar to the one above, but you need to figure out the details. Don't hesitate to discuss this problem with your fellow students or your TAs. ### #5 2D points and distance between them Tuples in OCaml are simple data structures for holding a few values of possibly different types. For example, we might represent points on a plane using two floating point values in a tuple. This type is written ``float * float``. A function that returns ``true`` if a point is in the "upper-right" quadrant of a plane might be implemented as follows: ``` let upper_right (x,y) = x > 0.0 && y > 0.0 ``` This function has the type ``float * float -> bool``. Implement a function named ``distance`` with type ``float * float -> float * float -> float`` to compute the distance between two points (each represented as a tuple of 2 ``float`` values). You may find the ``sqrt`` function useful in this function. ### #6 Triangle perimeter This problem asks you to compute the perimeter of a triangle. For a triangle with 3 corners named p1, p2, and p3, the perimeter is the distance from p1 to p2 plus the distance from p2 to p3 plus the distance from p3 back to p1. Implement a function named ``triangle_perimeter`` with type ``float * float -> float * float -> float * float -> float`` to do this. *This concludes lab 02.* **Due:** Friday, January 27 at 5:00pm. You should be able to complete lab work during the lab. But occasionally some work may not get completed, thus this due date. Note that these changes must exist in your repository on github.umn.edu. Doing the work, but failing to push those changes to your central repository cannot be assessed.