IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

La version 5.0.0 d'OCaml, le langage de programmation multi-paradigme est disponible,
Elle apporte le support du parallélisme en mémoire partagée et les gestionnaires d'effets

Le , par Bruno

20PARTAGES

9  0 
OCaml, anciennement connu sous le nom d'Objective Caml, est l'implémentation la plus avancée du langage de programmation 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. L’équipe en charge du langage de programmation multi-paradigme, OCaml, a annoncé la disponibilité de la version 5.0.0 du langage dans un post publié le 16 décembre. « Nous avons le plaisir de fêter les anniversaires de Jane Austen et d'Arthur C. Clarke en annonçant la sortie de la version 5.0.0 d'OCaml ».

OCaml est le successeur de Caml Light, auquel il a ajouté entre autres une couche de programmation objet. L'acronyme CAML provient de Categorical Abstract Machine Language, un modèle de machine abstraite qui n'est cependant plus utilisé dans les versions récentes de OCaml.

OCaml est utilisé dans des projets aussi divers que le logiciel de synchronisation de fichiers Unison, l'assistant de preuves formelles Coq ou la version Web de Facebook Messenger. Les facilités de traitement symbolique du langage permettent le développement d'outils de vérification statique, comme le projet SLAM pour des pilotes Windows écrits par Microsoft, ou ASTRÉE pour certains systèmes embarqués des Airbus A380.


Le point fort de cette nouvelle version majeure d'OCaml est le support tant attendu du parallélisme en mémoire partagée et des gestionnaires d'effets. Ce support multicore est l'aboutissement de plus de 8 ans d'efforts et a nécessité une réécriture complète de l'environnement d'exécution d'OCaml. Par conséquent, OCaml 5.0.0 devrait être une version d'OCaml plus expérimentale que les versions habituelles d'OCaml.

Dans cette version, le compilateur natif ne prend en charge que les architectures x86-64 et arm64. En termes de systèmes d'exploitation, Linux, les BSD, macOS et mingw64 sous Windows sont pris en charge.

Les responsables en charge du langage prévoient de restaurer la prise en charge de la plupart des architectures et systèmes d'exploitation précédemment pris en charge, et de résoudre les problèmes connus restants au cours de l'année prochaine. OCaml 5 en tant que langage est entièrement compatible avec OCaml 4 jusqu'aux caractéristiques de performance de vos programmes. En d'autres termes, tout code qui fonctionne avec OCaml 4 devrait fonctionner de la même manière avec OCaml 5. Les exceptions actuellement connues à cette règle sont

  • la suppression de nombreuses fonctions et modules dépréciés depuis longtemps ;
  • les modifications apportées à l'API d'exécution interne ;
  • les performances des éphémères sont actuellement (et temporairement) fortement dégradées.

Caml est un langage fonctionnel augmenté de fonctionnalités permettant la programmation impérative. OCaml étend les possibilités du langage en permettant la programmation orientée objet et la programmation modulaire. Pour toutes ces raisons, OCaml entre dans la catégorie des langages multi-paradigme. Il intègre ces différents concepts dans un système de types hérité de ML, caractérisé par un typage statique, fort et inféré.

Le système de types permet une manipulation aisée de structures de données complexes : on peut aisément représenter des types algébriques, c'est-à-dire des types hiérarchisés et potentiellement récursifs (listes, arbres…), et les manipuler aisément à l'aide du filtrage par motif. Cela fait de OCaml un langage de choix dans les domaines demandant la manipulation de structures de données complexes, par exemple les compilateurs. Le typage fort, ainsi que l'absence de manipulation explicite de la mémoire (présence d'un ramasse-miettes) font de OCaml un langage très sûr. Il est aussi réputé pour ses performances, grâce à la présence d'un compilateur de code natif.

Possibilités de programmation parallèle dans OCaml

La bibliothèque standard d'OCaml expose des primitives de bas niveau pour la programmation parallèle. Il est recommandé aux utilisateurs d'utiliser des bibliothèques de programmation parallèle de plus haut niveau telles que domainslib. OCaml distingue la concurrence et le parallélisme et fournit des mécanismes distincts pour les exprimer. La concurrence est l'exécution superposée de tâches alors que le parallélisme est l'exécution simultanée de tâches.

En particulier, les tâches parallèles se chevauchent dans le temps, mais les tâches concurrentes peuvent ou non se chevaucher dans le temps. Les tâches peuvent s'exécuter simultanément en se cédant le contrôle les unes aux autres. Alors que la concurrence est un mécanisme de structuration des programmes, le parallélisme est un mécanisme permettant d'accélérer l'exécution de vos programmes.

Domaines

Les domaines sont les unités de parallélisme en OCaml. Le module Domain fournit les primitives pour créer et gérer les domaines. De nouveaux domaines peuvent être créés à l'aide de la fonction spawn.

Code ocaml : Sélectionner tout
1
2
3
Domain.spawn (fun _ -> print_endline "I ran in parallel") 
I ran in parallel 
- : unit Domain.t = <abstr>


La fonction spawn exécute le calcul donné en parallèle avec le domaine appelant. Les domaines sont des entités lourdes. Chaque domaine correspond à une rélation 1:1 à un thread du système d'exploitation. Chaque domaine possède également son propre état d'exécution, qui comprend des structures propres au domaine pour l'allocation de la mémoire. Ils sont donc relativement coûteux à créer et à démanteler. Il est recommandé que les programmes ne génèrent pas plus de domaines que de cœurs disponibles.

Joindre des domaines

Utilisons le programme pour calculer le nième nombre de Fibonacci en utilisant la récursion comme exemple courant. Le programme séquentiel pour calculer le nième nombre de Fibonacci est donné ci-dessous.

Code ocaml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
(* fib.ml *) 
let n = try int_of_string Sys.argv.(1) with _ -> 1 
  
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2) 
  
let main () = 
  let r = fib n in 
  Printf.printf "fib(%d) = %d\n%!" n r 
  
let _ = main ()


Le programme peut être compilé et évalué comme suit.

$ ocamlopt -o fib.exe fib.ml
$ ./fib.exe 42
fib(42) = 433494437
$ hyperfine './fib.exe 42' # Benchmarking
Benchmark 1: ./fib.exe 42
Time (mean ± sd): 1.193 s ± 0.006 s [User: 1.186 s, System: 0.003 s]
Range (min … max): 1.181 s … 1.202 s 10 runs


Nous constatons qu'il faut environ 1,2 seconde pour calculer le 42e nombre de Fibonacci. Les domaines créés peuvent être joints à l'aide de la fonction join pour obtenir leurs résultats. La fonction de jonction attend que le domaine cible se termine. Le programme suivant calcule le nième nombre de Fibonacci deux fois en parallèle.

Code ocaml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
(* fib_twice.ml *) 
let n = int_of_string Sys.argv.(1) 
  
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2) 
  
let main () = 
  let d1 = Domain.spawn (fun _ -> fib n) in 
  let d2 = Domain.spawn (fun _ -> fib n) in 
  let r1 = Domain.join d1 in 
  Printf.printf "fib(%d) = %d\n%!" n r1; 
  let r2 = Domain.join d2 in 
  Printf.printf "fib(%d) = %d\n%!" n r2 
  
let _ = main ()


Le programme génère deux domaines qui calculent le nième nombre de Fibonacci. La fonction spawn renvoie une valeur Domain.t qui peut être jointe pour obtenir le résultat du calcul parallèle. La fonction join bloque jusqu'à ce que le calcul soit terminé.

$ ocamlopt -o fib_twice.exe fib_twice.ml
$ ./fib_twice.exe 42
fib(42) = 433494437
fib(42) = 433494437
$ hyperfine './fib_twice.exe 42'
Benchmark 1: ./fib_twice.exe 42
Time (mean ± sd): 1.249 s ± 0.025 s [User: 2.451 s, System: 0.012 s]
Range (min … max): 1.221 s … 1.290 s 10 runs


Comme on peut le voir, calculer deux fois le nième nombre de Fibonacci a pris presque le même temps que de le calculer une fois grâce au parallélisme.

Domainslib : une bibliothèque pour la programmation parallèle imbriquée

Essayons de paralléliser la fonction Fibonacci. Les deux appels récursifs peuvent être exécutés en parallèle. Cependant, la parallélisation naïve des appels récursifs en créant des domaines pour chacun d'eux ne fonctionnera pas car elle crée trop de domaines.

Code ocaml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(* fib_par1.ml *) 
let n = try int_of_string Sys.argv.(1) with _ -> 1 
  
let rec fib n = 
  if n < 2 then 1 else begin 
    let d1 = Domain.spawn (fun _ -> fib (n - 1)) in 
    let d2 = Domain.spawn (fun _ -> fib (n - 2)) in 
    Domain.join d1 + Domain.join d2 
  end 
  
let main () = 
  let r = fib n in 
  Printf.printf "fib(%d) = %d\n%!" n r 
  
let _ = main () 
fib(1) = 1 
val n : int = 1 
val fib : int -> int = <fun> 
val main : unit -> unit = <fun>


$ ocamlopt -o fib_par1.exe fib_par1.ml
$ ./fib_par1.exe 42
Fatal error: exception Failure("failed to allocate domain")


OCaml a une limite de 128 domaines qui peuvent être actifs en même temps. Si l'on tente de créer plus de domaines, une exception sera levée.

Parallélisation de Fibonacci à l'aide de domainslib

La bibliothèque standard d'OCaml ne fournit que des primitives de bas niveau pour la programmation concurrente et parallèle, laissant les bibliothèques de programmation de haut niveau être développées et distribuées en dehors de la distribution du compilateur de base. Domainslib est une telle bibliothèque pour la programmation parallèle imbriquée, qui est illustrée par le parallélisme disponible dans le calcul récursif de Fibonacci. Utilisons domainslib pour paralléliser le programme récursif Fibonacci. Il est recommandé d'installer domainslib en utilisant le gestionnaire de paquets opam.

Domainslib fournit un mécanisme async/await pour lancer des tâches parallèles et attendre leurs résultats. En plus de ce mécanisme, domainslib fournit des itérateurs parallèles. A la base, domainslib a une implémentation efficace de la file d'attente de détournement de travail afin de partager efficacement les tâches avec d'autres domaines. Une implémentation parallèle du programme Fibonacci est donnée ci-dessous.

Code ocaml : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(* fib_par2.ml *) 
let num_domains = int_of_string Sys.argv.(1) 
let n = int_of_string Sys.argv.(2) 
  
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2) 
  
module T = Domainslib.Task 
  
let rec fib_par pool n = 
  if n > 20 then begin 
    let a = T.async pool (fun _ -> fib_par pool (n-1)) in 
    let b = T.async pool (fun _ -> fib_par pool (n-2)) in 
    T.await pool a + T.await pool b 
  end else fib n 
  
let main () = 
  let pool = T.setup_pool ~num_additional_domains:(num_domains - 1) () in 
  let res = T.run pool (fun _ -> fib_par pool n) in 
  T.teardown_pool pool; 
  Printf.printf "fib(%d) = %d\n" n res 
  
let _ = main ()


Le programme prend le nombre de domaines et l'entrée de la fonction Fibonacci comme premier et deuxième arguments de la ligne de commande respectivement.

Commençons par la fonction principale. Tout d'abord, un pool de domaines sur lesquels les tâches parallèles imbriquées seront exécutées est mis en place. Le domaine invoquant la fonction run participera également à l'exécution des tâches soumises au pool. La fonction parallèle Fibonacci fib_par dans la fonction run est invoquée. Enfin, nous démolissons le pool et imprimons le résultat.

Pour des entrées suffisamment grandes (n > 20), la fonction fib_par génère les appels récursifs gauche et droit de manière asynchrone dans le pool en utilisant la fonction async. La fonction asynchrone renvoie une promesse pour le résultat. Le résultat d'un calcul asynchrone est obtenu en attendant la promesse à l'aide de la fonction await. L'appel de la fonction await se bloque jusqu'à ce que la promesse soit résolue.

Pour les petites entrées, la fonction fib_par appelle simplement la fonction Fibonacci séquentielle fib. Il est important de passer en mode séquentiel pour les problèmes de petite taille. Sinon, le coût de la parallélisation sera plus important que le travail disponible.

Les résultats observés dépendent du nombre de cœurs disponibles sur la machine cible. L’exemple est écrit sur un MacBook Pro Quad-Core Intel Core i7 de 2.3 GHz avec 4 cœurs et 8 threads matériels. Il est raisonnable de s'attendre à une performance d'environ 4x sur 4 domaines pour des programmes parallèles avec peu de coordination entre les domaines, et lorsque la machine n'est pas sous la charge. Au-delà de 4 domaines, l'accélération sera probablement moins que linéaire.

Gestionnaires d'effets

Les gestionnaires d'effets sont un mécanisme de programmation modulaire avec des effets définis par l'utilisateur. Les gestionnaires d'effets permettent aux programmeurs de décrire des calculs qui effectuent des opérations à effet, dont la signification est décrite par des gestionnaires qui englobent les calculs. Ils sont une généralisation des gestionnaires d'exceptions et permettent aux mécanismes de flux de contrôle non-locaux tels que les exceptions résumables, les threads légers, les coroutines, les générateurs et les E/S asynchrones d'être exprimés de manière composable.

Les gestionnaires d'effets dans OCaml 5.0 doivent être considérés comme expérimentaux. Les gestionnaires d'effets sont exposés dans la bibliothèque standard comme une enveloppe fine autour de leurs implémentations dans le runtime. Ils ne sont pas supportés comme une fonctionnalité du langage avec une nouvelle syntaxe.

Le bout de codeci-dessous défini un effet (c'est-à-dire une opération) qui prend un argument entier et renvoie un résultat entier. Nous nommons cet effet Xchg.

Code ocaml : Sélectionner tout
1
2
3
4
5
open Effect 
open Effect.Deep 
  
type _ Effect.t += Xchg: int -> int t 
let comp1 () = perform (Xchg 0) + perform (Xchg 1)


L'effet d'échange Xchg est déclaré en étendant le type variante extensible prédéfini Effect.t avec un nouveau constructeur Xchg : int -> int t. La déclaration peut être lue intuitivement comme « l'effet Xchg prend un paramètre entier, et lorsque cet effet est exécuté, il retourne un entier ». Le calcul comp1 exécute l'effet deux fois en utilisant la primitive perform et retourne leur somme. L'effet Xchg peut être géré en implémentant un gestionnaire qui renvoie toujours le successeur de la valeur offerte :

Code ocaml : Sélectionner tout
1
2
3
4
5
6
7
try_with comp1 () 
{ effc = fun (type a) (eff: a t) -> 
    match eff with 
    | Xchg n -> Some (fun (k: (a, _) continuation) -> 
        continue k (n+1)) 
    | _ -> None } 
- : int = 3


try_with exécute le calcul comp1 () sous un gestionnaire d'effet qui gère l'effet Xchg. Comme mentionné précédemment, les gestionnaires d'effets sont une généralisation des gestionnaires d'exceptions. Comme pour les gestionnaires d'exception, lorsque le calcul exécute l'effet Xchg, le contrôle saute au gestionnaire correspondant. Cependant, contrairement aux gestionnaires d'exception, le gestionnaire reçoit également la continuation délimitée k, qui représente le calcul suspendu entre le point d'exécution et ce gestionnaire.

Le gestionnaire utilise la primitive continue pour reprendre le calcul suspendu avec le successeur de la valeur offerte. Dans cet exemple, le calcul comp1 exécute Xchg 0 et Xchg 1 et reçoit les valeurs 1 et 2 du gestionnaire respectivement. Par conséquent, l'expression entière est évaluée à 3.

Il est utile de noter que nous devons utiliser un type abstrait local (type a) dans le gestionnaire d'effets. Le type Effect.t est un GADT, et les déclarations d'effet peuvent avoir différents paramètres de type pour différents effets. Le paramètre de type a dans le type a Effect.t représente le type de la valeur retournée lors de l'exécution de l'effet. Du fait que eff a le type a Effect.t et du fait que Xchg n a le type int [C=OCaml]Effect.t, le vérificateur de type déduit que a doit être int, c'est pourquoi nous sommes autorisés à passer la valeur entière n+1 comme argument pour continuer k.

Un autre point à noter est que le cas fourre-tout | _ -> None est nécessaire lors de la gestion des effets. Ce cas peut être lu intuitivement comme « transmettre les effets non gérés au gestionnaire externe ».

Instructions d'installation

Le compilateur de base peut être installé comme un commutateur opam avec les commandes suivantes :

Code : Sélectionner tout
1
2
opam update 
opam switch create 5.0.0
Il peut aussi être intéressant de vérifier le nouveau support du parallélisme en installant la bibliothèque domainslib avec

opam install domainslib

Source : OCaml

Et vous ?

Quel est votre avis sur le langage OCaml ?

A-t-on véritablement besoin du langage OCaml ? Où y a-t-il des besoins pour ce langage ?

Où se trouvent les pistes d'amélioration ?

Voir aussi :

C++ se classe mieux que Java pour la première fois dans l'histoire de l'indice de Tiobe, Java ne figure même plus dans le top 3 des langages les plus populaires

Rune, un langage de programmation systèmes, inspiré de Python et présenté comme étant rapide, de l'avis de certains développeurs, une bibliothèque aux langages existants aurait été préférable

Les petits langages sont-ils l'avenir de la programmation ? Oui, selon Christoffer Ekeroth, développeur d'applications web et de systèmes distribués

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de bbalet
Membre actif https://www.developpez.com
Le 23/12/2022 à 12:42
Je me suis toujours demandé si ocaml avait une autre utilité que la torture des étudiants de L3.
1  0 
Avatar de floyer
Membre averti https://www.developpez.com
Le 20/12/2022 à 16:35
En tant que language, je trouve Ocaml vraiment pas mal. Son côté multiparadigme en fait un outil intéressant, et le typage statique un langage sûr pour des gros projets. Le préprocesseur (ppx) permet des traitements non prévus par le language initial, un peu à la manière des macros Scheme/Lisp, bien que plus complexe pour le développeur de "macros". On peut aussi comparer aux développements Java basés sur des annotations et l'introspection.

La syntaxe est un peu déroutante. on est habitué à f(g(x,y),z) et non f (g x y) z... Mais le pattern matching est utile dès que l'on a des types de données algébriques.

En tant que compilateur, le résultat est très efficace, https://benchmarksgame-team.pages.de...ry-charts.html donne un temps 3 fois supérieur à C, ce qui est pas mal pour un langage de haut niveau. Il faut aussi relativiser : certaines proposition en C utilisent des instructions SSE pour optimiser. Ce n'est pas très représentatif de fonctions C normales. Et un interpréteur est disponible pour des essais interactifs.

En tant qu'écosystème, il y a un gestionnaire de compilation (dune) qui gère les chemins d'accès et simplifie la compilation dès qu'il y a des bibliothèques ou préprocesseurs à charger, et un gestionnaire de paquets (opam) qui gère la récupération de bibliothèques, leur compilation et leur installation. On trouve de tout.

Que manque t-il ? Actuellement, je cherche à intégrer Gtk sous Windows. C'est normalement prévu (bibliothèque lablgtk), mais l'installation ne marche pas (manque le pkg-config...). Sur le forum, on m'invite à patienter en attendant opam 2.2 mieux intégré à Windows... patience ! J'ai l'impression que les environnements livrés sous forme binaires (Java, Python...) posent moins de problèmes. (Et ce type d'environnement propose d'emblée un ensemble très fourni). L'installation de l'environnement Ocaml Diskuv - pour Windows - prend beaucoup de temps lié à la compilation des éléments.
0  0 
Avatar de floyer
Membre averti https://www.developpez.com
Le 23/12/2022 à 14:07
Visiblement, cela sert bien pour des applications réelles https://ocaml.org/industrial-users

Ceci-dit, pour des applications qui ont besoin de performances mais aussi de sécurité et de constructions de haut niveau (types algébriques, généricité…), Rust semble prometteur. Reste à intégrer le principe RAII, et les notions associées.
0  0 
Avatar de Pyramidev
Expert éminent https://www.developpez.com
Le 23/12/2022 à 15:02
Citation Envoyé par floyer Voir le message
Ceci-dit, pour des applications qui ont besoin de performances mais aussi de sécurité et de constructions de haut niveau (types algébriques, généricité…), Rust semble prometteur. Reste à intégrer le principe RAII, et les notions associées.
Rust a repris le RAII du C++ et en a même poussé plus loin la logique.

Par exemple, alors que, en C++, certains objets dans un moved-from state sont encore accessibles sans que cela ne génère une erreur de compilation, en Rust, quand on fait un mouvement, la portée de la variable d'origine s'arrête bien là où le mouvement a lieu.

Le RAII en Rust est aussi renforcé par le borrow checker. Un exemple intéressant est la gestion des mutex. En Rust, std::sync::Mutex contient à la fois le mutex et la donnée et sa fonction lock permet de récupérer un std::sync::MutexGuard. Ce dernier est un pointeur intelligent qui permet d'accéder à la donnée et son destructeur débloque le mutex. Quand on accède à la référence vers la donnée, le borrow checker empêche cette référence de vivre plus longtemps que le std::sync::MutexGuard, donc on ne peut plus y accéder après le déblocage du mutex. En C++, on peut coder une API similaire, mais le niveau de garantie sera moins élevé car, dès qu'on peut accéder à l'adresse d'un objet, on peut potentiellement stocker cette adresse où on veut, y compris à un endroit qui vit après la fermeture du mutex voire même après la destruction de l'objet d'origine.

En Rust, le RAII a fini par être renommé OBRM (Ownership Based Resource Management), mais la documentation de la bibliothèque standard utilise encore le terme RAII.
0  0 
Avatar de Pyramidev
Expert éminent https://www.developpez.com
Le 23/12/2022 à 15:50
Citation Envoyé par bbalet Voir le message
Je me suis toujours demandé si ocaml avait une autre utilité que la torture des étudiants de L3.
De mon côté, je n'ai pas appris OCaml. Le seul moment où cette lacune m'a gêné est quand j'avais lu l'article Implementing, and Understanding Type Classes.

C'est un article très intéressant sur comment implémenter les type classes en Haskell, mais l'article utilise OCaml que je ne connais pas, donc j'ai galéré lors de la lecture.

Dans les langages les plus utilisés en entreprise, le polymorphisme au runtime est single dispatch, mais c'est à cause de la manière à laquelle ce polymorphisme est implémenté. Par exemple, en C++ orienté objet et en Java, le pointeur vers la table virtuelle est stocké à l'intérieur de l'objet. Une autre solution aurait été de passer les pointeurs vers tables virtuelles en tant que paramètres cachés des fonctions dont les paramètres non cachés sont des objets polymorphes. L'article que je cite illustre cela dans la partie Dictionary passing (les tables virtuelles y sont appelées des dictionnaires). Cela offre pas mal de liberté sur la conception du système de type.

Le problèmes des développeurs trop enfermés dans la programmation orientée objet version Java est que, dès qu'ils entendent parler d'un nouveau langage dont le système de type est plus puissant (à la fois plus de contrôle à la compilation et plus de puissance d'abstraction) que ce qu'ils ont l'habitude d'utiliser, ils se disent "mais pourquoi cherchent-ils à faire différent au lieu d'adopter le paradigme objet (version Java), comme tout le monde ?"

Pour qu'ils fassent moins de résistance au changement, il est donc important d'ouvrir leurs esprits, ce que les écoles essaient de faire, mais je n'ai pas l'impression qu'elles y arrivent. C'est probablement ce qu'elles essaient de faire avec OCaml mais, comme je ne connais pas ce langage, je ne saurais pas dire s'il est pertinent pour remplir ce rôle. À l'époque où je m'étais instruit à la programmation fonctionnelle pendant mon temps libre, je m'étais directement attaqué à Haskell.
0  0 
Avatar de selmanjo
Membre régulier https://www.developpez.com
Le 24/12/2022 à 19:10
Ocaml est un puissant langage ! Le fait de savoir comprendre l'Ocaml et le maîtriser
s'avère rendre les choses faciles sauf sa syntaxe presque inhabituelle.
Son principal paradigme est incroyable mais presque
incontournable quand il s'agit de lourde projet.

Les nouveaux features d'Ocaml ouvrent bien évidemment des voies et de la,
la découverte de nouveaux concepts Ocaml n'est pas prête à freiner.

C'est un langage auquel je conseille de tester, de pratiquer, de faire des projets avec
et même d'essayer de le maîtriser le plus possible.
0  0 
Avatar de bbalet
Membre actif https://www.developpez.com
Le 29/12/2022 à 7:15
C'est vrai que c'est une bonne ouverture d'esprit et que la plupart des langages deviennent multi paradigmes en reprenant des concepts mis au point avec ces langages universitaires. Mais la syntaxe est vraiment très particulière et pour trouver des développeurs pour un projet d'entreprise bon courage.
0  0