CSCI 2041

ADVANCED PROGRAMMING PRINCIPLES

intro Ocaml: types, bindings, and conditionals

OCaml programs

Expressions

An Ocaml program is a sequence of expressions or declarations that are evaluated one after another.

Ocaml programs are compiled into code – either byte code or native code – that evaluates the expressions.

Class and labs use a “toplevel” REPL (read-eval-print-loop) – utop – to interactively evaluate expressions.

Utop history files and lecture code are posted in notes2041-f20 github repo.

Simple expressions

Every expression belongs to a single type. If its evaluation terminates normally, the result is a value of that type.

  • unit: ()
  • int: 0,1,-1,23,-4611686018427387904,…
  • string: "","ohai world", "I CAN HAZ CAPS",…
  • bool, char, float

Ocaml has standard operations on these basic types:

  • int: +,-,*,/,…
  • float: +., -., *., /., **

Hickey ch. 2 lists more

Errors

Compiling a malformed expression will result in a syntax error:

(1+1

Compiling an expression that has the wrong type will result in a type error:

1 +. 3

This is different from a runtime error:

if b then 1/0 else 13

Many programs that cause runtime errors in e.g. python, Java, cause type errors in OCaml.

Bindings

let expressions

let declarations bind a name to a value for the rest of a program:

let name = value

let x = "a string"

let expressions bind a name for use in an expression:

let name = value in expr

let y = 7*7 in y+1

such expressions are valid expressions, so they can be nested:

let y = 7*7 in
  let x = 4 in x+y

scope

The scope of a binding is the program text in which it can be used:

let y = 2 in
  let x = y*y in
    if x > 3 then
      "bazinga!"
    else
      "boooring"

A name appearing outside of its scope is “unbound” and will cause a compiler error:

# let s = 42 / voldemort ;;
Error: Unbound value voldemort

Types

The result of the expression let name = value in expr is expr, so the type of the expression is the type of expr:

let y = 42 in "hello!"
let b = true in 6.02e23
let x = 5 in
  let y = x*2 in y = 10
let a = 0.1 in
  let b = 2 in a < b

(Assuming name has the type of value)

Conditionals

ifthen..else

The expression if cond then then else else evaluates cond, and if it is true, evaluates then, otherwise else.

Since the expression must belong to a single type, both then and else must have the same type.

if "a" = "a" then 0 else 1000
let s = 71 in if s > 65 then 'S' else 'N'
if 3 < 7 then "hooray!" else ()

Comparisons

OCaml defines the comparisons <, >, <=, >=, and = between expressions of the same type.

Unpleasant surprise for Java/C programmers:

  • == means “the same object in memory”
  • a != b means not (a == b).

For value inequality, use <>.

"a string" = "a " ^ "string"
"a string" == "a " ^ "string"
"a string" != "a " ^ "string"
"a string" <> "a " ^ "string"

Functions

OCaml also has functions. They are applied to an argument to produce a result:

  • The expression string_of_float 3.14159265 applies
    • function string_of_float to
    • argument 3.14159265 : float to compute the
    • result "3.14159265" : string
  • read_int () applies function read_int to argument () : unit to compute a result of type int.

The type of a function has the form t1 -> t2, where t1 is the type of argument the function expects, and t2 is the type of result it returns, so

  • string_of_float : float -> string
  • read_int : unit -> int

cs2041.org

// reveal.js plugins