Static Wikipedia February 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Web Analytics
Cookie Policy Terms and Conditions Objective Caml - Wikipédia

Objective Caml

Un article de Wikipédia, l'encyclopédie libre.

Objective Caml
Image:OCaml.png
Développeur INRIA
Dernière version 3.09.3
Date 15 septembre 2006
Paradigme multiparadigme : impérative, fonctionnelle, orientée objet
Dialectes JoCaml
Influencé par Caml Light, Standard ML
Système d'exploitation Multi-plate-forme
Licence Q Public License (compiler)
LGPL (library)
Site Web http://caml.inria.fr/

Objective Caml (OCaml) est la principale implémentation du langage Caml, créé par Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy et leurs collaborateurs en 1996. Ce langage de la famille des langages ML est un projet open source dirigé et maintenu essentiellement par l'INRIA. OCaml est le successeur de Caml Light. L'acronyme CAML provient de Categorical Abstract Machine Language, mais les versions récentes de Caml ont abandonné la machine abstraite.

Sommaire

[modifier] Fonctionnalités et utilisations

Caml est un langage qui permet aussi bien la programmation impérative que la programmation fonctionnelle. Objective Caml étend les possibilités du langage en permettant la programmation orientée objet et la programmation modulaire. Pour ces raisons, on dit que Caml est un langage multi-paradigme.

Caml dispose d'une boucle d'interaction permettant d'exécuter des lignes de code comme dans un langage de script, d'un compilateur de code intermédiaire (ou bytecode), comme c'est le cas pour Java (technologie) ainsi que d'un compilateur de code natif pour de nombreuses architectures, parmi lesquelles IA32, IA64, PowerPC, AMD64, Sparc, Alpha, HP/PA, MIPS et StrongARM. Ce dernier est réputé pour son efficacité, comparable à celle des compilateurs C++.

[modifier] Principales caractéristiques

[modifier] Modules

Le langage OCaml possède une trentaine de modules consacrés à des types de donnés ou à des usages particuliers. Ainsi, les modules Array et List donnent accès aux fonctions de traitement des tableaux et des listes, le module Str permet d'utiliser des expressions rationnelles, etc..

[modifier] Typage

OCaml est un langage à typage statique et automatique avec synthèse de types.

[modifier] Filtrage

Le filtrage (pattern matching) est un élément essentiel du langage Caml. Il permet d'alléger le code grâce à une écriture plus souple que des conditions classiques, et l'exhaustivité fait l'objet d'une vérification. Objective Caml, à la différence de Caml-Light, propose un contre-exemple lorsqu'un filtrage incomplet est décelé. Par exemple, le code suivant provoque une erreur :

  #let rec fibonacci = function
     | 0 -> 1
     | n when n > 1 -> fibonacci (n - 1) + fibonacci (n - 2) ;;
  Characters 20-107:
     Warning P: this pattern-matching is not exhaustive.
     Here is an example of a value that is not matched:
  1

[modifier] Gestion de la mémoire

OCaml dispose, comme Java, d'une gestion automatisée de la mémoire, grâce à un ramasse-miettes incrémental générationnel.

[modifier] Préprocesseur

Les distributions Caml comportent un préprocesseur indépendant nommé camlp4 (pour Caml PreProcessor-Pretty-Printer), qui autorise d'importants remaniements syntaxiques.

[modifier] Utilisation

Bien que désigné comme le successeur du Pascal dans l'enseignement de la programmation dans les classes préparatoires en France, et utilisé dans de nombreuses universités françaises et étrangères (Etats-Unis et Japon notamment), le langage Caml n'est pas très utilisé dans le milieu industriel, malgré quelques succès tels que Unison, Astrée, Coq, mldonkey ou encore GeneWeb.

[modifier] Présentation du langage

Pour comprendre la suite, il faut savoir ce qu'est un langage fonctionnel fortement typé. Résumons en disant que Caml (et ici OCaml) ne fait "que" créer des fonctions où les valeurs d'entrée et de sortie sont parfaitement déterminés à la compilation, avant toute exécution.

[modifier] Les types prédéfinis

Les différents types élémentaires de Caml sont les booléens (type bool), les entiers (type int), les réels (type float) et les chaînes de caractères (string), comme dans la plupart des langages de programmation. Un autre type, le type unit, symbolisé par un couple de parenthèses "()", joue à peu près le même rôle que void en C. Pour classer plusieurs valeurs, on dispose également de listes (type list), de tableaux (type array sous OCaml et vect sous Caml-Light) et de n-uplets.

Il est à noter que les différents types présentés ci-dessus peuvent être combinés. Ainsi, on peut par exemple créer des listes d'entiers, dont le type est donc int list, ou des tableaux de chaînes de caractères, dont le type est alors float array sous OCaml et float vect sous Caml-Light.

Toutefois, contrairement à la plupart des autres langages, il n'est pas nécessaire d'attribuer un type aux variables que l'on utilise. En effet, Caml dispose d'un algorithme de synthèse de types qui lui permet de déterminer le type des variables à partir du contexte dans lequel elles sont employées. Toute incohérence de type provoque une erreur et fait échouer la compilation.

[modifier] Variables

Le code peut être entré simplement à la suite de l'invite "#" qui figure en début de ligne. Par exemple, pour définir une variable x contenant le résultat du calcul 1 + 2 * 3, on écrira :

  # let x = 1 + 2 * 3 ;;

Après avoir saisi et validé cette expression, Caml détermine le type de l'expression (en l'occurrence, il s'agit d'un entier) et affiche le résultat du calcul :

  val x : int = 7

On peut être tenté d'effectuer toutes sortes de calculs. Cependant, il faut prendre garde à ne pas mélanger les entiers et les réels, ce que l'on fait couramment dans de nombreux langages, car ceci provoque une erreur lors de la compilation :

  #2.3 + 1 ;;
    Characters 0 - 3:
     2.3 + 1.;;
     ^^
    This expression has type float but is here used with type int

Cet exemple simple permet de se faire une première idée du fonctionnement de l'algorithme de synthèse de types. En effet, lorsque nous avons écrit "2.3 + 1", nous avons ajouté le réel 2.3 et l'entier 1, ce qui pose problème. En fait, pour effectuer ce calcul, nous devons nous assurer que tous les nombres ont le même type, d'une part, et employer la loi de composition interne + appliquée aux réels, notée "+." en Caml. Nous aurions donc dû écrire :

  #2.3 +. 1.0 ;;
  - : float = 3.3

[modifier] Fonctions

Les programmes sont souvent structurés en procédures et en fonctions. Les procédures sont composées d'un ensemble de commandes utilisées plusieurs fois dans le programme, et regroupées par commodité sous un même nom. Une procédure ne renvoie pas de valeur, ce rôle étant dévolu aux fonctions. De nombreux langages disposent de mots-clefs distincts pour introduire une nouvelle procédure ou une nouvelle fonction ("Procedure" et "Function" en Pascal, "Sub" et "Function" en Visual Basic, etc...). Caml, quant à lui, ne possède que des fonctions, et celles-ci se définissent de la même manière que les variables. Par exemple, pour définir l'identité, on peut écrire :

 # let id = function x -> x ;;

Après saisie et validation de l'expression, l'algorithme de synthèse de types détermine le type de la fonction. Cependant, dans l'exemple que nous avons donné, rien ne présage du type de x, aussi la fonction apparaît-elle comme polymorphe (à tout élément de l'ensemble 'a, elle associe une image id(x) qui est élément de l'ensemble 'a) :

 val id : 'a -> 'a = <fun>

Toutefois, il existe des cas dans lesquels le polymorphisme n'est pas recherché. On introduit alors une contrainte quant au type de la variable. Ainsi, dans notre exemple, nous pourrions écrire

  #let id = function (x : int) -> x ;;

Sous ces conditions, la fonction identité n'est plus polymorphe. Elle ne s'applique qu'aux entiers et possède le type suivant :

  int -> int = <fun>

En fait, la syntaxe que nous venons de présenter est inutilement lourde. Nous pouvions en effet nous contenter de ceci :

  # let id (x : int) = x ;;

Cette notation se révèle la plus commode lorsque les fonctions acceptent plusieurs arguments, comme c'est le cas ici :

  #let somme = function x -> function y -> x + y ;;
  #let somme x y = x + y ;;

[modifier] Fonctions d'ordre supérieur

Les fonctions d'ordre supérieur sont des fonctions qui prennent une ou plusieurs fonctions en entrée et/ou renvoient une fonction. La plupart des langages fonctionnels possèdent des fonctions d'ordre supérieur. Concernant Caml, on peut en trouver des exemples dans les fonctions prédéfinies des modules Array, List, etc.. Par exemple, la fonction suivante :

  Array.map (fun i -> i * i) [|0 ; 1 ; 2 ; 3 ; 4 ; 5|] ;;

donnera le résultat suivant :

  - : int array = [|0 ; 1 ; 4 ; 9 ; 16 ; 25|]

En fait, la fonction map prend en argument la fonction anonyme qui, à tout entier i, associe son carré, et l'applique aux éléments du tableau, construisant ainsi le tableau des valeurs élevées au carré.

[modifier] Curryfication

La fonction somme que nous venons de définir va nous permettre d'introduire une autre notion propre aux langages fonctionnels et tout particulièrement à Caml, la curryfication. La curryfication consiste à voir une fonction à n arguments comme la composition d'une fonction à n - 1 arguments avec une fonction à un argument. Ainsi, pour définir la fonction succ qui détermine le successeur d'un entier, nous pouvons nous contenter de la définition suivante :

  # let succ = somme 1 ;;

Caml comprend cette écriture comme la définition d'une fonction restreinte à un argument à partir d'une fonction plus générale à deux arguments. Il apparaît alors de façon très nette qu'il n'y a pas de différence syntaxique nette entre les valeurs les fonctions en Caml.

[modifier] Récursivité

La récursivité consiste à rédiger une fonction qui fait référence à elle-même, sur le modèle de la récurrence mathématique. En Caml, les fonctions récursives sont introduites à l'aide du mot-clef rec. Par exemple, pour définir la factorielle, nous pouvons écrire :

  #let rec factorielle n =
     if n = 0 then 1 else n * factorielle (n-1) ;;

[modifier] Fonctions mutuellement récursives

Les fonctions mutuellement récursives sont très utilisées pour définir des fonctions simples comme "pair" et "impair" :

  #let rec pair = function
      | 0 -> true
      | n -> impair (n - 1)
  and impair = function
      | 0 -> false
      | n -> pair (n - 1) ;;

L'écriture que nous avons proposée ci-dessous consiste à raisonner de la façon suivante : savoir si n est pair revient à savoir si (n - 1) est impair. Cet autre problème revient à savoir si (n - 2) est pair, et ainsi de suite. On peut aussi utiliser de telles fonctions pour des tris comme le tri par insertion :

  
  let rec trier = function
    | [] -> []
    | t :: q -> inserer t (trier q)
  and inserer e = function
    | [] -> [e]
    | t :: q -> if t > e then e :: t :: q else t :: (insere e q) ;;
  

[modifier] Définitions internes

Il est possible de définir des variables ou des fonctions à l'intérieur d'une fonction. On utilise pour cela la syntaxe suivante :

  #let factorielle n =
      let rec auxiliaire resultat = function
         | 0 -> resultat
         | n -> auxiliaire (n * resultat) (n - 1) 
      in auxiliaire 1 n ;;

Cette écriture est un exemple de récursivité terminale. Le programme est analogue à une boucle.

[modifier] Exemples de code

[modifier] Hello world

Ce célèbre programme d'introduction s'écrit tout simplement :

  #let hello_world = 
     print_string "Hello world !" ;;

On peut ainsi se rendre compte, comme nous l'écrivions précédemment, que hello_world est une fonction, même si son écriture donne à penser qu'il s'agit d'une procédure. En effet, la valeur renvoyée est ici unit.

[modifier] Manipulation de listes

Les listes sont très utilisées en programmation, en particulier pour les traitements récursifs. Pour construire une liste, plusieurs écritures sont possibles :

  #1 :: 2 :: 3 :: [] ;;
  #[1 ; 2 ; 3] ;;

Ce faisant, on obtient une liste d'entiers, que Caml note de la façon suivante :

  - : int list = [1 ; 2 ; 3]

Pour connaître la longueur d'une liste sans utiliser la fonction du module List définie à cet effet, on peut écrire :

   
  (* Longueur d'une liste *)
  let rec longueur = function
    | [] -> 0
    | t :: q -> 1 + longueur q ;;
  

Lors de l'analyse de cette fonction par l'algorithme de synthèse de type, il apparaît que la liste peut contenir n'importe quel type de données, de sorte que la fonction possède le type suivant :

  val longueur : 'a list -> int = <fun>

[modifier] Arbres et types récursifs

Pour définir un arbre binaire de type quelconque, on se sert d'un type récursif. On peut ainsi avoir recours à l'écriture suivante :

  type 'a arbre = Feuille | Branche of ('a arbre * 'a * 'a arbre) ;;

Cet arbre se compose de branches qui se ramifient à souhait, et se terminent par des feuilles. Pour connaître la hauteur d'un arbre, on utilise alors :

 
  let rec hauteur = function
       | Feuille -> 0
       | Branche(branche, _, branche') -> 1 + max (hauteur branche) (hauteur branche') ;;
  

[modifier] Recherche de racine par dichotomie

 let rec dicho f min max eps =
   let fmin = f min and fmax = f max in
     if fmin *. fmax > 0.
     then failwith "Aucune racine"
     else if max -. min < eps then (min, max) (* retourne un intervalle *)
     else let mil = (min +. max) /. 2. in
       if (f mil) *. fmin < 0.
       then dicho f min mil eps
       else dicho f mil max eps ;;
 (* Approximation de la racine carrée de 2 *)
 # dicho (fun x -> x *. x -. 2.) 0. 10. 0.000000001;;
 - : float * float = (1.4142135618, 1.41421356238)

[modifier] Liens externes

Portail de l'informatique – Accédez aux articles de Wikipédia concernant l’informatique.
Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2006 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu