# 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.**
## 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 =
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—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
``, which is just a placeholder to indicate that there is some
unprintable function value. **Note: `` 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
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`.
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"
* 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.