loading...
Cover image for Découverte de OCaml

Découverte de OCaml

sroccaserra profile image Sébastien Roccaserra Updated on ・3 min read

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.

Discussion

pic
Editor guide