EMZETT.
Login

Kurz: OCaml (1996, INRIA Frankreich) ist eine funktionale Sprache aus der ML-Familie mit statischem Typsystem und Typinferenz: Typen werden fast immer automatisch erkannt, trotzdem fängt der Compiler viele Fehler vor dem Start ab.

Teil des Kurses OCaml

Kapitel 1 von 8 im Kurs OCaml. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Was ist OCaml?

OCaml (1996, INRIA Frankreich) ist eine funktionale Sprache aus der ML-Familie mit statischem Typsystem und Typinferenz: Typen werden fast immer automatisch erkannt, trotzdem fängt der Compiler viele Fehler vor dem Start ab. OCaml ist multiparadigmatisch (funktional, imperativ, objektorientiert) und erzeugt sehr schnellen Maschinencode.

Eingesetzt wird OCaml bei Jane Street (Finanzhandel), in Coq (Beweisassistent), im ursprünglichen Rust-Compiler, in Flow, Infer und ReScript. Seit OCaml 5 gibt es echte Parallelität (Domains) und Effekthandler.

Ausführen

ocaml hallo.ml            # als Skript starten
ocamlfind ocamlopt -package str hallo.ml -o hallo   # nativ übersetzen
dune init project demo    # Projekt mit dem Build-System dune
dune build && dune exec demo
utop                      # komfortable interaktive Konsole
opam install <paket>      # Paketmanager

Das erste Programm

let () =
  print_endline "Hallo, Welt!";
  Printf.printf "1 + 2 = %d\n" (1 + 2);
  print_string "ohne Zeilenumbruch";
  print_newline ()

Ausgabe:

Hallo, Welt!
1 + 2 = 3
ohne Zeilenumbruch

let () = ... ist der übliche Einstiegspunkt: Ein Ausdruck vom Typ unit. Mit ; werden Ausdrücke nacheinander ausgeführt.

Werte, Typen und Operatoren

In OCaml gibt es keine Variablen im Sinne von Veränderlichkeit: let bindet einen Namen an einen unveränderlichen Wert.

let () =
  let x = 42 in
  let pi = 3.14159 in
  let name = "OCaml" in
  let ok = true in
  let c = 'z' in
  Printf.printf "%d %.2f %s %b %c\n" x pi name ok c;
 
  (* Ganzzahl- und Fließkomma-Operatoren sind verschieden *)
  Printf.printf "%d %d %d %d\n" (7 + 2) (7 - 2) (7 * 2) (7 / 2);
  Printf.printf "%d %d\n" (7 mod 2) (- 7 mod 3);
  Printf.printf "%.2f %.2f\n" (7.0 /. 2.0) (2.0 ** 10.0);
  Printf.printf "%d\n" (int_of_float 3.99);
  Printf.printf "%.1f\n" (float_of_int 3 +. 0.5);
 
  (* Vergleiche *)
  Printf.printf "%b %b %b %b\n" (1 < 2) (1 = 1) (1 <> 2) ("a" < "b");
  Printf.printf "%b %b\n" (true && false) (true || false);
  print_endline (string_of_int 12 ^ " und " ^ string_of_float 1.5 ^ " und " ^ "Text")

Ausgabe:

42 3.14 OCaml true z
9 5 14 3
1 -1
3.50 1024.00
3
3.5
true true true true
false true
12 und 1.5 und Text

Achtung

+ ist nur für int, +. für float. Zahlen werden nie stillschweigend umgewandelt. = vergleicht strukturell (Werte), == physisch (Speicheradresse).

Typen sichtbar machen

Im Interpreter zeigt OCaml jeden Typ. Mit Annotationen schreibst du sie selbst:

let doppelt (x : int) : int = x * 2
let begruessung : string = "Hallo"
 
let () =
  Printf.printf "%d %s\n" (doppelt 21) begruessung

Ausgabe:

42 Hallo

Ein Typfehler wird schon beim Übersetzen gemeldet:

let () = print_endline (1 + 2)

Fehlermeldung:

This expression has type int but an expression was expected of type
         string

Lokale Bindungen und Blöcke

let () =
  let a = 10 in
  let b = a * 2 in
  let summe = a + b in
  Printf.printf "%d\n" summe;
  let wert =
    let x = 3 in
    let y = 4 in
    x * y
  in
  Printf.printf "%d\n" wert;
  (* 'let ... and ...' bindet gleichzeitig *)
  let p = 1 and q = 2 in
  Printf.printf "%d\n" (p + q)

Ausgabe:

30
12
3

Merke

  • OCaml ist funktional, statisch typisiert und nutzt Typinferenz
  • let bindet unveränderliche Werte, let ... in begrenzt sie lokal
  • + - * / für int, +. -. *. /. für float; keine automatische Umwandlung
  • Ein Programm besteht aus Ausdrücken; let () = ... ist der Startpunkt

Übungsaufgabe

Berechne die Fläche eines Kreises mit Radius 2,5 und gib sie auf zwei Nachkommastellen aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Weiter: Funktionen und Kontrollfluss

Alle Kapitel: OCaml im Überblick