Il y a des adeptes d'Erlang ici? J'ai acheté le livre écrit par Joe Armstrong "Programming Erlang" et c'est très bon! J'ai quelques commentaires négatifs à propos du langage, mais son support pour la concurrence est si simple et si puissant!
Il y a des adeptes d'Erlang ici? J'ai acheté le livre écrit par Joe Armstrong "Programming Erlang" et c'est très bon! J'ai quelques commentaires négatifs à propos du langage, mais son support pour la concurrence est si simple et si puissant!
Simple question : pourquoi as-tu acheté un bouquin sur Erlang ? Par besoin, par curiosité ?
Tu pourrais dire ce que tu en penses, les reproches que tu ferais au langage, etc. ? Ça m'intéresserait d'avoir ton avis.
J'avais déjà regardé un peu le langage. De ce que j'ai vu, il y a du pattern matching, des tuples, des listes, du typage dynamique... Et en effet, ça a l'air plutôt pas mal pour la programmation concurrente et distribuée.
Envoyé par LLB
ce serait cool si tu pouvais une critique de ce livre... un peu sur ce modèle http://algo.developpez.com/livres/#L2100058878
perso, je me suis intéressé à Erlang, et surtout à son utilisation dans ejabberd... mais je n'ai pas tenté de programmer avec (je ne fais pas assez de distribué )
Ben... il a été fait pour, comme tout le monde sait !Envoyé par GnuVince
Jamais essayé pour ma part...
C'est du PI-calcul ?Envoyé par GnuVince
http://fr.wikipedia.org/wiki/Erlang_%28langage%29
Apparemment il y a les listes-en-compréhension, mais wikipédia n'est pas très bavard sur le modèle de concurrence.
Pour ma part, j'ai découvert Erlang en 2004 grace au bouquin en français (le seul à ma connaissance) "Erlang Programmation". Je me demandais à l'époque comment un langage aussi bien foutu pouvait rester à ce point dans un relatif anonymat. Je dis "relatif" parce que quelques plus ou moins grosses start-up spécialisées n'ont pas hésité à faire leur business basé sur ce langage et en faire leur principal atout face à la concurrence (commerciale, celle-ci).
Bossant dans le domaine des réseaux de télécoms, le domaine dont vient Erlang, ce langage s'est avéré me convenir parfaitement.
Exit l'impératif et la POO qui faisait que la programmation me rebutait jusque-là.
Je viens de recevoir le bouquin qui est sorti il y a quelques jours, en anglais, par Joe Armstrong, un des créateurs du langage, et il est vraiment trés bien écrit. La progression est trés bien pensée : il couvre les aspects nécessaires à un débutant (en tenant compte de ceux venant d'autres langages), en commencant par la programmation séquencielle, puis concurrente, mais il aborde aussi les sujets assez avancés et permet assez rapidement de se mettre à écrire des applications complexes.
Concernant le modèle de concurrence d'Erlang, il s'agit d'acteurs (de processes) ayant chacun leur propre mémoire et n'échangeant des informations que par envoi et réception de messages. Par analogie avec la POO ou le bloc élémentaire de construction est l'objet, en Erlang, c'est le process qui est la brique de base.
On peut voir un process Erlang comme un thread mais en beaucoup, beaucoup plus léger (env. 300 octets de heap à la création) et beaucoup, beaucoup plus rapide à créer (de l'odre d'une dizaine de µs). Ils peuvent donc se compter par centaines de milliers, voire millions.
Les process Erlang s'éxécutent dans une VM. Et les VM s'éxecutant sur différentes machines peuvent communiquer de manière transparente (mécanisme de distribution). La VM Erlang peut également répartir l'éxécution des différents process sur plusieurs processeurs/coeurs de la même machine sans l'intervention du programmeur et ainsi utiliser le maximum de puissance de calcul disponible.
L'ensemble des bibliothèques de base, nommé OTP, est assez complet. Il permet de structurer l'organisation de son appli et d'utiliser de manière optimale les mécanismes de distribution, de supervision des processes, de tolérance aux pannes ...
La syntaxe est plutôt simple, mais puissante : on écrit beaucoup moins de lignes de code pour faire la même chose en Erlang qu'en C (du fait, je pense, du typage dynamique, mais surtout du "pattern matching").
Pour quelqu'un venant d'un autre langage, il faut se faire à l'assignation unique des variables, et s'habituer à "penser concurrence" pour découper correctement son appli en processes. C'est une chose assez naturelle pour le cerveau humain, mais qui vient plus difficillement pour quelqu'un habitué à d'autres paradigmes que pour un débutant tout frais
Quels sont-ils ?J'ai quelques commentaires négatifs à propos du langage
Envoyé par igwan
si tu pouvais nous en faire une petite critique de ces livres, ce serait cool... surtout pour la rubrique fonctionnelle en plein essor
C'est pas grand chose:
1. Le support pour les chaînes de caractères. latin-1? On pourrait avoir du UTF-8 S.V.P? Et ce qui vient avec, upper(), lower(), etc.
2. On peut pas avoir la documentation d'une fonction directement dans l'interpréteur. J'aime bien que dans Python je puisse faire <tt>help(foo)</tt> et avoir la définition et documentation pour l'objet foo.
3. Encore par rapport à l'interpréteur, on peut pas utiliser tout les "constructs" d'Erlang. Particulièrement, on peut pas définir des fonctions (non-anonymes) directement.
4. Je suis pas fou de comment on démarre une application Erlang. Je détesterais pas une fonction main/1 qui serait le point d'entrée.
Pour l'instant, rien du langage ne m'a vraiment fait lever le coeur. Peut-être que ça viendra, mais pour l'instant je suis très exité par ce que je lis sur Erlang Quelqu'un voudrait faire un craqueur de mots de passes distribué? ;-)
Vincent
Effectivement, c'est un point qui est assez souvent évoqué sur la mailing-list. Les chaînes en Erlang sont des listes d'entiers, donc rien n'empeche d'y caser des caractères UTF-8. Pour manipuler l'UTF-8, il y a des librairies qui trainent (celle intégrée à ejabberd notamment), mais ce serai interressant de l'avoir directement dans les bibliothèques de base, totallement d'accord.Envoyé par GnuVince
Je n'y avais jamais pensé. Il y a l'auto-complétion des noms de modules et fonctions, c'est déjà pas mal2. On peut pas avoir la documentation d'une fonction directement dans l'interpréteur. J'aime bien que dans Python je puisse faire <tt>help(foo)</tt> et avoir la définition et documentation pour l'objet foo.
Point soulevé également et il semble que ça soit à l'étude. En pratique, les fontions anonymes se révèlent suffisantes pour tester de petites fonctions dans le shell. Enfin c'est un avis personnel : je me vois pas éditer un module dans l'interpréteur, et je bosse toujours éditeur ouvert.3. Encore par rapport à l'interpréteur, on peut pas utiliser tout les "constructs" d'Erlang. Particulièrement, on peut pas définir des fonctions (non-anonymes) directement.
Tu parles d'une application à la mode OTP ?4. Je suis pas fou de comment on démarre une application Erlang. Je détesterais pas une fonction main/1 qui serait le point d'entrée.
Tu peux la nommer comme tu veux, ta fonction de démarrage :
Les mécanismes OTP, comme le serveur qui démarre/arrête les applications, peuvent paraître superflus, mais il n'en est rien. C'est lui qui permet entre autres de faire du failover/takeover automatique entre plusieurs machines faisant tourner ton appli, de détecter qu'une application dont dépends la tienne n'a pas été démarrée, etc... La VM Erlang est un véritable petit OS distribué
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 main() -> application:start(mon_appli).
Et puis utiliser OTP n'est pas obligatoire du tout. D'ailleurs, "Programming Erlang" n'en parle pas avant le chapitre 16 ... en t'en ayant précedemment fait presque réinventer tous les mécanismes (gen_server, event_handler, supervisor ...) pour en comprendre l'utilité
Je ne doute pas qu'il faudra peu de temps avant de voir fleurir tout type d'utilisations plus ou moins recommandables.Pour l'instant, rien du langage ne m'a vraiment fait lever le coeur. Peut-être que ça viendra, mais pour l'instant je suis très exité par ce que je lis sur Erlang Quelqu'un voudrait faire un craqueur de mots de passes distribué? ;-)
Pour le dernier en date, je veux bien. Pour celui en français je n'en ai qu'un vague souvenir et pas le temps de me replonger dedans.Envoyé par gorgonite
Comment fait-on ?
igwan: pour démarrer une application, je parle plutôt de:
Disons que quelque chose de simple ./a.out comme dans C, Haskell, etc. serait pas mauvais. Remarque, un simple script en bash peut arranger le problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 {1:03}[vince@vincent: prog/erlang]% erl -noshell -s program main -s init stop Hello, world {1:03}[vince@vincent: prog/erlang]%
Sinon, il y a escript, à la manière des scripts shell :Envoyé par GnuVince
Sans oublier un petit chmod +x
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 #!/usr/bin/env escript %% -*- mode: erlang -*- main([In]) -> X = list_to_integer(In), N = factorial(X), io:format("factorial ~w = ~w~n", [X, N]). factorial(0) -> 1; factorial(N) -> N * factorial(N - 1).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 $ ./factorial 25 factorial 25 = 15511210043330985984000000
igwan: tu fais du Erlang professionellement?
Professionellement : oui, mais pas sur des postes de développeur jusqu'à présent. Plutôt comme une aide à mon métier (admin et supervision d'eqpt télécoms).Envoyé par GnuVince
J'ai commencé à lire l'ouvrage de Joe Armstrong qui vient de sortir.
Je suis du monde impératif, objet. Ayant quelques bases en fonctionnel avec Lisp et Scheme, effectivement la syntaxe est bien différente. Mais je suis quand même sur le Q. Tout comme GnuVince, j'avais quelques questions auquelles igwan est venu y répondre.
Je découvre donc Erlang depuis hier après midi et effectivement c'est un outil vraiment très puissant, les exemples de l'ouvrage sont bien foutu et correctement expliqué, mais je trouve qu'il manque des commentaires dans le code source de ceux-ci afin d'avoir plus simple à les relires.
J'ai fait mon premier programme concurrent hier (j'ai pas eu beaucoup de temps pour jouer avec Erlang.) Je vais le poster ce soir. C'est pas très avancé, ça calcule la somme des fibonacci de 1 à 40, mais comme l'algorithme récursif est très lent, c'était une bonne façon de voir si en utilisant deux CPU ça allait plus vite. Résultat: 1 CPU prend environ 40 secondes, 2 CPUs prennent environ 24 secondes
Dit "l'algorithme récursif le plus naïf prend 40s", sinon tu vas colporter l'idée fausse que la récursion est forcément lente.
Ceci est instantané :
tout comme ceci :
Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 fibs = 1:1: zipWith (+) fibs (tail fibs) main = print $ sum $ take 40 $ fibs
Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 fib = snd . mfib where mfib 0 = (undefined, 1) mfib 1 = (1, 1) mfib n = let (a, b) = mfib (n-1) in (b, a+b) main = print $ sum $ map fib [0..39]
--
Jedaï
Jedai: en effet. Il faut par contre que les gens distinguent la différence entre une fonction qui utilise la récursivité et les algorithmes récursifs et itératifs.
Exemple: voici une fonction récursive d'un algorithme récursif:
Pourquoi dit-on que cet algorithme est récursif? Voici la transformation de add_rec(4, 3):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 incr(N) -> N + 1. decr(N) -> N - 1. add_rec(N, 0) -> N; add_rec(N, M) -> incr(add_rec(N, decr(M))).
Tous les appels à incr sont en suspens: ils attendent la fin d'une autre fonction avant de s'exécuter. Quand on atteint notre cas de base (dans ce cas-ci, M == 0), on revient en arrière.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 add_rec(4, 3). incr(add_rec(4, 2)). incr(incr(add_rec(4, 1))). incr(incr(incr(add_rec(4, 0)))). incr(incr(incr(4))). incr(incr(5)). incr(6). 7.
Voici maintenant la même fonction, mais qui utilise un algorithme itératif et sa transformation. Notez que la récursivité est quand même utilisée:
Voyez la différence. On utilise la récursivité aussi, mais la fonction n'attend rien. C'est beaucoup plus efficace. On appelle ça de la "tail recursion". Les bon compilateurs vont l'optimiser en la transformant en une instruction JMP. Erlang et Haskell font cette optimisation.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 add_iter(N, 0) -> N; add_iter(N, M) -> add_iter(incr(N), decr(M)). add_iter(4, 3). add_iter(5, 2). add_iter(6, 1). add_iter(7, 0). 7.
J'espère que mes explications ont été assez claires.
Pour les gens d'Erlang, voici un algorithme fibonacci plus efficace; on conserve les nombres calculés dans un dict (un hash en termes Perl):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 fib(N) when N >= 0 -> fib(dict:from_list([{0, 0}, {1, 1}]), N, 2). fib(_Dict, N, _Current) when N < 2 -> N; fib(Dict, N, Current) when Current =< N -> Fib1 = dict:fetch(Current - 1, Dict), Fib2 = dict:fetch(Current - 2, Dict), fib(dict:store(Current, Fib1 + Fib2, Dict), N, Current + 1); fib(Dict, N, _Current) -> dict:fetch(N, Dict).
Je ne suis pas d'accord, les deux algorithmes sont parfaitement récursifs, la seule différence c'est que le deuxième code se prête à une optimisation classique ('tail call' ou 'appel terminal') qui évite une explosion de la pile lors de la récursion, mais c'est l'affaire du compilateur, la fonction, elle, est bien écrite de manière récursive.
Par ailleurs, ton amélioration de fib en Erlang n'est pas géniale : en effet tu retiens l'intégralité des éléments alors que deux suffisent, ta fonction est en O(n) en complexité spatiale (sans parler du fait que les dictionnaires ont souvent un facteur constant assez fort) alors que pour fibonacci du O(1) en complexité spatiale suffit. Enfin ça n'a pas une importance énorme sauf si tu calcule fib 50000 ... (Par curiosité, combien de temps ça te prend de calculer fib 50000 avec cette fonction ?)
--
Jedaï
Ma définition d'algorithme récursif vs itératif vient du cours SICP. Regarde les vidéos, ils en parlent dans le... 3e ou 4e vidéo. Je suis plus certain.
75,896,385 microsecondes avec mon code original;
446,333 microsecondes en conservant seulement 2 valeurs.
Merci pour l'optimisation
Nouveau code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 fib(N) when N >= 0 -> fib({0, 1}, N, 2). fib(_Tuple, N, _Current) when N < 2 -> N; fib(Tuple, N, Current) when Current =< N -> {Fib1, Fib2} = Tuple, fib({Fib2, Fib1 + Fib2}, N, Current + 1); fib({_, Answer}, _N, _Current) -> Answer.
Hello, je découvre Erlang depuis peu, je me suis acheté un bon livre (Programmer en Erlang chez Person), je suis un peu les tutos présents sur le web mais deux questions restent sans réponses pour le moment :
erreur 1 : pourquoi j'ai toujours cette erreur :
par exemple dans la fonction suivante :syntax error before: '->'
erreur 2 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 a() -> b(). b() -> c(). c() -> 3 = 4.
Je n'arrive pas à créer un module tel que :
-module(mysets.erl).
-export([a/0]).
qui me retourne cette erreur :
Par contre, des scripts comme celui-ci fonctionnent quant à eux très bien :** exception error: undefined shell command module/1
ex :
J'ai envie de dire pourquoi.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 JoeAttributeList= [{shoeSize,42},{pets, [pets,[{cat, zorro}, {cat,daisy}]]}, {children,[{thomas,21}, {claire,17}]}]. JoeTuple = {person, "joe", "armstrong", JoeAttributeList}. MikeAttributeList= [{shoeSize,41},{likes, [boats,wine]}]. MikeTuple= {person, "Mike", "Williams", MikeAttributeList}. People= [JoeTuple,MikeTuple].
A noter : j'ai créé un fichier demo.beam dans un répertoire quelquonque. J'ai ensuite créé dans ce même répertoire un fichier mysets.erl.
Puis j'ai ouvert demo.beam avec werl. ma version de erlang est erts-5.8.1.1
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager