Cet atelier n'est pas réservé aux développeurs mais s'ouvre également à tous ceux qui souhaitent découvrir un langage facile et agréable pour développer leurs petits outils en cas de besoin. Quelques rappels historiques ainsi que les grandes familles de langages actuels seront évoqués. En plus du langage Ruby, l'accent sera mis sur des concepts généraux de programmation et de factorisation de code.
L'atelier se déroulera dans la salle Reaj au dernier étage du 4 bis (grand bâtiment vitré près du métro charles de Gaulle).
Afin de profiter au mieux de cet atelier, il vous est recommandé d'apporter vos machines.
Aller plus loin
- Actux (0 clic)
- Agenda du libre en mai (1 clic)
# Petite erreur dans le texte de la dépêche
Posté par Sylvain Blandel . Évalué à 1.
« Le prochain atelier de l'association rennaise Actux se déroulera le mardi 19 mars »
J'imagine qu'il est plutôt question du mois de mai. :-)
[^] # Re: Petite erreur dans le texte de la dépêche
Posté par DitOuQueMon . Évalué à 2.
Cet atelier n'est pas réservé aux développeurs mais s'ouvre également à tous ceux qui souhaitent découvrir un langage facile et agréable pour développeur leurs petits outils (...)
Je supposes que l'auteur voulait dire « développer » :)
En même temps, qu'est-ce que signifie « fonctionnel » dans le contexte ? Un langage présentant des fonctions ? Un langage qui fonctionne ?
[^] # Re: Petite erreur dans le texte de la dépêche
Posté par Damien (site web personnel) . Évalué à 4.
[^] # Re: Petite erreur dans le texte de la dépêche
Posté par lasts . Évalué à 9.
L'idée de base, c'est que les fonctions sont des valeurs dans ce type de langage (à titre de comparaison, on a l'habitude en programmation de pouvoir manipuler des nombres, des chaînes de caractères, des tableaux, et parfois même des regexs comme des valeurs --- mais plus rarement des fonctions). C'est un style qui est assez jouissif à utiliser, parce qu'il permet de mieux factoriser son code et de le rendre plus sémantique (plus expressif).
L'exemple typique pour illustrer l'aspect sémantique, c'est la fonction map() qui applique une fonction à chaque élément d'une collection (un tableau, une liste). Dans les langages impératifs, on utilise une boucle for pour ce genre de tâches :
for (int i = 0; i < tab.length; ++i)
tab[i] = f(tab[i]);
Et on ne voit aucune raison de factoriser deux lignes de code... sauf qu'en pratique, l'exemple précédent ne se présente pas comme ça, mais plutôt comme :
for (int i = 0; i < tab.length; ++i) {
// plusieurs
// lignes
// de
// code
}
Et il devient alors plus difficile de comprendre ce qui se passe, parce qu'un tas de facteurs peuvent influer dans le corps de la boucle (on peut modifier la valeur de l'itérateur, on peut décider de ne pas modifier à chaque fois le tableau, ou de faire d'autres opérations, ...).
Bref, la boucle for est générale, mais un peu trop pour faciliter la compréhension. Ce qu'il faudrait, c'est une boucle plus sémantique qui dit au programmeur "alors là tu vois, je vais mettre à jour toutes les cases du tableau", ce qui permet d'éviter de nombreux bugs (et on peut appliquer le même principe aux autres sortes de boucles que l'on retrouve souvent). Bref, on construit des briques expressives qui décrivent une action.
En ruby,
irb(main):001:0> tab = [1,2,3]
irb(main):002:0> tab.map { |x| x * x }
=> [1, 4, 9]
Un exemple plus concret, c'est pour les GUIs : Lorsque l'on crée un bouton, il faut pouvoir spécifier son comportement lors d'un clic. La solution pseudo-OO serait de faire hériter son bouton de la classe Button et de redéfinir la méthode on_click() et finalement de l'instancier... mais c'est un peu lourd de faire ça pour chaque bouton (à mon goût).
À comparer avec le code suivant :
input = Textarea.new
bouton = Button.new
bouton.on(:click) do
puts input.value
end
Un autre exemple, pour les fanas d'algorithmie : Si l'on a un graphe que l'on souhaite parcourir en largeur (pour chercher un élément, ou autre), le code de parcours est assez général (c'est l'action sur chaque élément qui diffère). On peut donc souhaiter programmer une seule fois le parcours et laisser libre le choix de l'action au programmeur ensuite.
Un exemple d'utilisation :
def has_value(graph, x)
graph.dfs do |value|
return true if x == value
end
return false
end
Bref, les possibilités offertes par le paradigme fonctionnel sont très riches et ouvrent de nouvelles opportunités. Entre autre, je pense que c'est un style qui permet de mieux éviter les erreurs parce qu'il permet une meilleure découpe des différents composants (dans l'exemple du dfs, par exemple, si une erreur est décelée, il est facile de voir que has_value() n'est pas à remettre en cause -- et que l'erreur se trouve dans la méthode dfs()). Le code tend à être plus "simple" (mais c'est relatif, car il est aussi plus abstrait).
Il ouvre également des portes pour les optimisations : Par exemple, pour map(), puisque l'on sait que chaque case du tableau va être mise à jour indépendamment des autres, il est possible de paralléliser trivialement les calculs sur plusieurs bécanes. Oui oui, le map dans MapReduce (de google) vient de là (et le reduce correspond à un autre type de boucle).
Finalement, l'arrivée du fonctionnel dans les langages comme C++, C# et les différents langages de script populaires (Ruby, Python, Lua...) montrent bien qu'il s'agit d'un concept intéressant.
Remarque: les langages implémentent plus ou moins bien le(s) paradigme(s) sur le(s)quel(s) ils reposent (par exemple, Java n'est pas suffisamment OO à mon goût). Ruby est "assez" fonctionnel dans le sens qu'il supporte l'idée, mais pas aussi bien que des vrais langages fonctionnels. Je recommande donc OCaml si vous voulez vous essayer à ce style langage :) .
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.