DEV Community

Cover image for Découverte de OCaml
Sébastien Roccaserra
Sébastien Roccaserra

Posted on • Edited on

Découverte de OCaml

Cette semaine j'avais envie d'explorer un nouveau langage. Je souhaitais avoir un typage fort et des fonctions currifiées par défaut : j'ai essayé OCaml, et j'ai été agréablement surpris.

Kata Bowling en OCaml

Pour découvrir le langage, je me suis lancé sur une implémentation du kata bowling :

type roll = Roll of int

type frame = Frame of int
let next (Frame n) = Frame (n + 1)

let rec score ?(f=Frame 1) = function
  | [] -> 0
  | [Roll x; Roll y; Roll z] when is_last_frame f ->
      x + y + z
  | r1 :: (Roll y as r2) :: (Roll z as r3) :: rest when is_strike r1 ->
      10 + y + z + score ~f:(next f) (r2 :: r3 :: rest)
  | r1 :: r2 :: (Roll z as r3) :: rest when is_spare r1 r2 ->
      10 + z + score ~f:(next f) (r3 :: rest)
  | Roll x :: Roll y :: rest ->
      x + y + score ~f:(next f) rest
  | [_] -> failwith "wrong number of rolls"
and is_strike = (=) @@ Roll 10
and is_spare (Roll x) (Roll y) = 10 == x + y
and is_last_frame = (=) @@ Frame 10
Enter fullscreen mode Exit fullscreen mode

Le répo github est ici, la liste des commits montre le cheminement :

Ce que j'ai apprécié

  • Quand on connait un peu Haskell, on se sent vite à la maison
  • La documentation en français
  • Il y a des guidelines et des cheatsheets pour démarrer
  • Le paradigme fonctionnel et le pattern matching
  • En OCaml, il n'y a que des expressions
  • Ne pas avoir à répéter le nom de la fonction pour chaque pattern
  • Le pattern matching implicite avec function
  • Les paramètres nommés et avec valeurs par défaut (voir ci-dessus, ?(f=Frame 1))
  • Je n'ai pas essayé, mais je suis curieux de l'aspect orienté objet
  • L'inférence de type et le typage fort, c'est chouette d'être aidé par un compilateur
  • Avoir une erreur de compilation par défaut pour les patterns non exhaustifs et les variables non utilisées
  • Le système de build (dune), je n'ai pas eu de mal à le prendre en main (pour ce tout petit projet)
  • C'est facile de lancer les tests en mode watch (dune runtest -w)
  • Installer des libs avec opam, ça fonctionne
  • C'est facile de visualiser les erreurs de compilation à la volée dans Vim
  • Les sources de gros projets sont dispos pour s'inspirer (JaneStreet et Mirage par exemple)
  • OCaml a des variantes plus ou moins populaires, comme F# (une base de OCaml sous .NET), et Reason / ReScript.

Ce que j'ai moins apprécié

  • On ne peut pas suivre la step down rule (définir la fonction appelante au dessus de la fonction appelée) si j'ai bien compris <-- en fait si, avec and, voir la fonction is_strike ci-dessus
  • Devoir répéter le pattern pour chaque guarde when
  • Des symbols un peu plus présents qu'en Haskell (:: pour :, @@ pour $, les ~ devant les paramètres nommés)
  • Le ;; pour finir une instruction dans le repl

Kata Bowling en Haskell

Pour explorer les ressemblances, j'ai fait le même kata en Haskell :

module Bowling (score, Roll(..)) where

data Roll = Roll Int
  deriving (Eq)

data Frame = Frame Int
  deriving (Eq)
next (Frame n) = Frame (n + 1)

score = score' $ Frame 1
score' f xs = case xs of
  [] -> 0
  r1@(Roll x):r2@(Roll y):r3@(Roll z):rest
    | isLastFrame f ->
      x + y + z
    | isStrike r1 ->
      10 + y + z + score' (next f) (r2:r3:rest)
    | isSpare r1 r2 ->
      10 + z + score' (next f) (r3:rest)
  Roll x:Roll y:rest ->
    x + y + score' (next f) rest
  [_] -> error "Wrong number of rolls"
  where
    isStrike = (==) $ Roll 10
    isSpare (Roll x) (Roll y) = 10 == x + y
    isLastFrame = (==) $ Frame 10
Enter fullscreen mode Exit fullscreen mode

Le répo github est ici, la liste des commits montre le cheminement :

Conclusion

Je suis content d'avoir découvert OCaml, je pense en refaire plus tard, par exemple pour explorer l'orientation objet. Ou peut-être découvrir F# pour explorer encore un autre langage de ce type ?

Note : je ne suis un expert ni en OCaml, ni en Haskell. Je suis preneur d'avis pour améliorer tout ça.

Top comments (0)