Source

John Whitington, OCaml from the Very Beginning, Chapter 1: Starting Off

Contents

Question 1

What are the types of the following expressions and what do they evaluate to, and why?

1
2
3
4
5
6
7
8
9
10
11
12
13
let _ =
    assert (17 = 17);                            (* 17 → int *)
    assert (11 = 1 + 2 * 3 + 4);                 (* 1 + 2 * 3 + 4 → int *)
    assert (1 = 800 / 80 / 8);                   (* 800 / 80 / 8 → int
                                                   `/` performs int division *)
    assert (400 > 200);                          (* 400 > 200 → bool *)
    assert (not (1 <> 1));                       (* 1 <> 1 → bool *)
    assert (true || false);                      (* true || false → bool *)
    assert (not (true && false));                (* true && false → bool *)
    assert (not (if true then false else true)); (* bool *)
    assert ('%' = '%');                          (* '%' → char *)
    assert ('a' <> 'b');                         (* 'a' and 'b' → char *)
    ;;

Question 2

Consider the evaluations of the expressions 1 + 2 mod 3, (1 + 2) mod 3, and 1 + (2 mod 3). What can you conclude about the + and mod operators?

Conclusion: mod has higher precedence than +.

1
2
3
4
5
let _ =
    assert (1 + 2 mod 3 = 1 + (2 mod 3));
    assert ((1 + 2) mod 3 = 0);
    assert (1 + (2 mod 3) = 3);
    ;;

Question 3

A programmer writes 1+2 * 3+4. What does this evaluate to? What advice would you give him?

Advice: if what you want is the product of 1+2 multiplied by 3+4, parenthesize the addition expressions to prevent the multiplication from being performed first due to the higher precedence of the multiplication operator *.

1
2
3
4
5
let _ =
    assert (1 + 2 * 3 + 4 = 1 + (2 * 3) + 4);
    assert (1 + 2 * 3 + 4 = 1 + 6 + 4);
    assert (1 + 2 * 3 + 4 = 11);
    ;;

Question 4

The range of numbers available is limited. There are two special numbers: min_int and max_int. What are their values on your computer? What happens when you evaluate the expressions max_int + 1 and `min_int

  • 1`?

4611686018427387904 is 2^62 so this reflects implementation for a 64-bit system. min-int -1 is equivalent to max_int and max_int + 1 is equivelant to min_int.

1
2
3
4
5
6
let _ =
    assert (min_int = -4611686018427387904);
    assert (min_int -1 = max_int);
    assert (max_int =  4611686018427387903);
    assert (max_int + 1 = min_int);
    ;;

Question 5

What happens when you try to evaluate the expression 1 / 0? Why?

As expected, Exception: Division_by_zero is raised.

Question 6

Can you discover what the mod operator does when one or both of the operands are negative? What about if the first operand is zero? What if the second is zero?

1
2
3
4
5
let _ =
    assert (-4 mod  3 = -1);
    assert (-4 mod -3 = -1);
    assert ( 0 mod  2 =  0);
    ;;

2 mod 0 raises Exception: Division_by_zero.

Question 7

Why not just use, for example, the integer 0 to represent false and the integer 1 for true? Why have a separate bool type at all?

If type safety is a priority, then it makes sense to have a Boolean type instead of using some other type to represent a Boolean value.

Question 8

What is the effect of the comparison operators like < and > on alphabetic values of type char? For example, what does ’p’ < ’q’ evaluate to? What is the effect of the comparison operators on the booleans, true and false?

As in other languages, here presumably alphabetic values of type char are represented as character code point values and it is those code point values that are being compared:

1
2
3
4
5
let _ =
    assert ('a' < 'z');
    assert ('z' > 'a');
    assert ('p' < 'q');
    ;;

As for Boolean values, presumably this reflects the common representation of true using 1 and false using 0?

1
2
3
4
5
let _ = 
    assert (true  <> false);
    assert (true   > false);
    assert (false  < true);
    ;;

Execute this file

$ codedown ocaml < 2022-12-15-basics.md | grep . | ocaml -stdin