# Welcome to Recitation! This semester's 3110 recitations will be structured as hands-on labs. These labs will supplement the lecture and give you hands-on experience. * You are expected to complete all of the labs. If you finish early, you may leave. If you don't finish early, you should finish up yourself *before the next recitation*. * Labs are a good source of exam questions! At least one of the problems from at least one of the labs will be on at least one of the exams! * Working together is a great idea. You may share your solutions with anyone you worked with during recitation, but please do not share them with others (even your friend who you usually work with but couldn't make it to a particular recitation) * We need feedback! These labs are new course material, and we want to make them as useful and fun as possible. If anything isn't going well, please discuss it with your recitation TA so that we can fix it. On to the first lab... # Welcome to OCaml! None of this lab is meant to be tricky. If you are having trouble, please ask a TA or a friend immediately. ## Starting OCaml * Start the 3110 virtual machine (VM). * In the terminal window, type `utop` to start the interactive OCaml session. It is also called a *top-level* or a *REPL* (read-eval-print-loop). Press Control-D to exit the top-level. ## Types and values You can enter expressions into the OCaml toplevel. End an expression with a double semi-colon `;;`. OCaml will then evaluate the expression, tell you the resulting value, and its type. For example: ``` utop # let x = 42;; val x : int = 42 ``` Let's dissect that response from utop: * `x` is the identifier to which the value was bound. * `int` is the type of the value. * `42` is the value. You can pronounce the entire output as "`x` has type `int` and equals `42`." You can also enter expressions without binding them to any name: ``` utop # 42;; - : int = 42 ``` What is the type and value of each of the following OCaml expressions? * `7 * (1+2+3)` * `"catch-" ^ string_of_int (22)` Hint: type each expression into the top-level and it will tell you the answer. Note: In OCaml, the type `string` was historically a mutable data type, but the language is in the process of correcting that design decision and making it an immutable data type. As part of that process, OCaml 4.02 introduced a type `bytes` and made it a *synonym* with `string`. While they are synonyms, they are fully replaceable by each other. For example, the REPL is free to print `bytes` in its output in place of `string`. The `string` type is, for now, still mutable. But the [`String` module][string] functions that exploit mutability have been marked as deprecated. **You should not use those deprecated functions.** [string]: http://caml.inria.fr/pub/docs/manual-ocaml/libref/String.html ## OCaml expressions See the [table of all operators in the OCaml manual](http://caml.inria.fr/pub/docs/manual-ocaml/expr.html#sec138). * Write an expression that multiplies `42` by `10`. * Write an expression that divides `3.14` by `2.0`. * Write an expression that computes `4.2` raised to the seventh power. ## if expressions The expression `if e1 then e2 else e3` evaluates to `e2` if `e1` evaluates to `true`, and to `e3` otherwise. if 3 + 5 > 2 then "yay!" else "boo!";; Unlike if/then/else **statements** that you may have seen in imperative languages, if/then/else **expressions** in OCaml are just like any other expression; they can be put anywhere an expression can go: 4 + (if 'a' = 'b' then 1 else 2);; let x = if true then 1 else 2 in x + x;; Note: just because this is possible doesn't mean that it's good style. Always consider the readability of your code. **Exercise**: try writing some `if` expressions of your own. ## Writing OCaml functions An OCaml function can be defined at the top-level using syntax like this: ``` utop # let increment x = x+1;; val increment : int -> int = <fun> ``` Let's dissect that response: * `increment` is the identifier to which the value was bound. * `int -> int` is the type of the value. This is the type of functions that take an `int` as input and produce an `int` as output. Think of the arrow `->` as a kind of visual metaphor for the transformation of one value into another value&mdash;which is what functions do. * The value is a function, which the top-level chooses not to print (because it has now been compiled and has a representation in memory that isn't easily amenable to pretty printing). Instead, the top-level prints `<fun>`, which is just a placeholder to indicate that there is some unprintable function value. **Note: `<fun>` itself is not a value.** You can call functions with syntax like this: ``` utop # increment 0;; - : int = 1 utop # increment(21);; - : int = 22 utop # increment (increment 5);; - : int = 7 ``` Note how OCaml is flexible about whether you write the parenthesis or not, and whether you provide whitespace or not. One of the challenges of first learning OCaml can be figuring out when parentheses are actually required. So if you find yourself having problems with syntax errors, one strategy is to try adding some parentheses. Now write some functions of your own: * Define a function that computes the cube of a floating-point number. Test your function on a few inputs. * Define a function that computes the cube root of a floating-point number. Test your function on a few inputs. * Define a function that computes the area of a circle, given the radius of the circle. For the area of a circle, you need the mathematical constant \\(\pi\\). For this exercise, obtain it with a *nested let expression* like the following: ``` let area r = let pi = acos (-1.) in ... ``` Replace the elipsis (`...`) with your own code. Note that you can use `pi` in that code. Also note that you can enter multi-line expressions in utop. We've used a `let..in` expression above. It binds a value to a name for use in a limited scope. For example, `let x = 2 in x + x` binds `x` to the value `2` in the scope of the expression `x+x`. ## Roulette Develop a function `roulette` that implements generates a random outcome for a [spin of a roulette wheel](https://www.youtube.com/watch?v=wZVRex2-Fwc). In developing this function, you might also find it helpful to begin using a text editor (such as `emacs`, `vim`, or `subl`) to edit your code. For example, in one terminal window you could type `subl roulette.ml` to begin editing an OCaml source file in the Sublime text editor, and in another terminal window you can type `utop` to open the OCaml top-level. You can then type `#use "roulette.ml";;` at the top-level prompt. Note that you must type the `#` in `#use`. Edit your source code in Sublime, save it, then re-`#use` the file in utop to load your revised code. A *roulette wheel* is partitioned into *pockets*, which are numbered 0 through 36. Each pocket is also *colored*. In the ranges 1 to 10 and 19 to 28, odd numbers are red and even are black. In the ranges 11 to 18 and 29 to 36, odd numbers are black and even are red. The pocket numbered 0 is green. When `roulette` is called, it should return a string such as `"10 black"` or `"36 red"` or `"0 green"`. Note that `roulette` does not need any meaningful input. In OCaml that can be expressed as follows: ``` let roulette _ = ... ``` The underscore `_` is OCaml syntax here indicating that `roulette` does not use its input. The ellipsis `...` is not actually OCaml syntax; the code you write should replace it. To call this type of function, you may write `roulette ()`. In this case, the parentheses are mandatory. Here are some example spins: ``` utop # roulette ();; - : string = "10 black" utop # roulette ();; - : string = "0 green" utop # roulette ();; - : string = "36 red" ``` Hints: * First, develop a version of `roulette` that returns only the number, not the color of the pocket. For generating random numbers, look at the [OCaml standard library](http://caml.inria.fr/pub/docs/manual-ocaml/stdlib.html) to find a module that would be useful. * Second, extend your implementation to also return the color. You will find it helpful to use a nested let expression, and perhaps to define some helper functions to determine whether numbers are even or odd.