Intro to OCaml



Intro to OCaml

0 0


intro-to-ocaml


On Github jamiis / intro-to-ocaml

Intro to OCaml

I'm Jamis

jamismanwaring@gmail.com | github.com/jamiis | @jamisjohnson

OS X Install

$ brew update           # mmmm
$ brew install ocaml    # should include compiler and other fancy tools
$ brew install opam     # ocaml package manager
$ opam install utop     # fancy repl (aka toplevel). works in emacs if that's the way you swing
If you are running Windows then uh idk. You have bigger problems than downloading ocaml.
  • Objective Categorical Abstract Machine Language ... kind of.
  • Created at the French research institution INRIA in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy.
  • OCaml unifies functional, imperative, and object-oriented programming under an ML-like type system. -Wikipedia

Highlights

  • Static type system makes runtime type mismatches impossible
  • Type inference gives a feel of a dynamically typed language
  • Foreign function interface for linking with C and FORTRAN
  • Parametric polymorphism aides in writting highly expressive, terse functions
  • Exhaustive pattern matching warns you when cases haven't been covered
  • Native compilers for IA-32, AMD64, Power, SPARC, ARM, and ARM64

"Ocaml in 1 Slide"

Thank you professor Edwards
let rec map f = function    (* pass functions *)
    | [] -> []              (* pattern matching *)
    | head :: tail ->       (* case splitting *)
        let r = f head in   (* polymorphic *)
        r :: map f tail     (* prepend using cons operator *)
# List.map;;
val map : (’a -> ’b) -> ’a list -> ’b list
# (* note how types are inferred *)

# List.map (fun x -> x + 3) [1;5;9];;
- : int list = [4; 8; 12]

# let add5 = List.map (fun x -> x + 3);;
val add5 : int list -> int list = <fun>

# add5 [1;2;3;4;5];;
- : int list = [6; 7; 8; 9; 10]

Types

type op = Add | Sub | Mult | Div
type expr = Lit of int | Binop of expr * op * expr
# let one = Lit(1);;
val one : expr = Lit 1

# let two = Lit(2);;
val two : expr = Lit 2

# let three = Binop(one, Add, two);;
val three : expr = Binop (Lit 1, Add, Lit 2)

Memoize

code from real world ocaml
let memoize f =
    let table = Hashtbl.Poly.create () in
    (fun x ->
      match Hashtbl.find table x with
      | Some y -> y
      | None ->
        let y = f x in
        Hashtbl.add_exn table ~key:x ~data:y;
        y)

let rec fib i = if i <= 1 then 1 else fib (i - 1) + fib (i - 2)

Memoize

code from real world ocaml
# memoize;;
val memoize : ('a -> 'b) -> 'a -> 'b = <fun>

# fib;;
val fib : int -> int = <fun>

# let fib = memoize fib;;
val fib : int -> int = <fun>

# time (fun () -> fib 40);;
Time: 4.90749s
- : int = 165580141

# time (fun () -> fib 40);;
Time: 0.00286102ms
- : int = 165580141

Complex Pattern Matching

let rec uniq = function
    | ([] | [_]) as l -> l
    | x :: ((x2::_) as xs) ->
        if x = x2 then uniq xs else x :: uniq xs
# uniq;;
- : 'a list -> 'a list = <fun>
(* mmmmmm parametric polymorphism *)

# uniq [1;2;3;3;3;4;4;3;3;3;3;5;5];;
- : int list = [1; 2; 3; 4; 3; 5]

# uniq ["hello";"hello";"world";"!";"!"];;
- : string list = ["hello"; "world"; "!"]

Ecosystem

  • ocamldep - Dependency generator
  • ocamlopt - Native code compiler
  • ocamlc - Byte code compiler
  • ocamldebug - OCaml source-level replay debugger
  • opam - Package manager
  • utop - Imporved toplevel interpreter (ocaml is the standard interpeter)
  • Core - Jane Street Capital's standard library overlay
  • merlin - Context sensitive code completion for vim and emacs
  • ocamllex - Lexer generator
  • ocamlyacc - Parser generator

Facebook

Flow - a static type checker for JavaScript

Facebook

Flow - a static type checker for JavaScript

/* @flow */
function foo(x) {
    return x * 10;
}
foo('Hello, world!');
$> flow
hello.js:5:5,19: string
This type is incompatible with
  hello.js:3:10,15: number

Install

opam install flowtype

Jane Street

All you need is love and

Real World OCaml

Thanks MLH!