# Composition

**URL:** <https://www.debian-fr.org/t/composition/16986>\
**Category:** Programmation\
**Created:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986 "2016-02-20T18:38:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![fran.b](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/d78d45/32.png) [@fran.b](https://www.debian-fr.org/u/fran.b)\
**Post date:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986/1 "2016-02-20T18:38:03Z")

</div>

En fait en Caml, on fait simplement la composition

```auto

```

h = (compose f g) est la fonction x-\>f(g(x)).  
Je me demandais comment faire ça simplement en C, je vois bien comment faire une fonction

`int compose(f,g,x)
int (*f)();
int (*g)();
int x;
{
   return((*f)((*g)(x)));
}
`  
mais sauf à faire une structure un peu compliquée, je ne vois pas comment faire simplement une fonction h valant fog,  
h=compose(f,g);  
Sauf à faire une structure arborescente et une sytème d’évaluation adaptée, je ne crois pas que ça soit faisable, je me trompe?

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986/2 "2016-02-20T18:38:15Z")

</div>

C’est un mécanisme qui me fait vachement penser à de l’objet.

Tu déclare une classe qui possède deux données membres (tes pointeurs sur fonctions) et un fonction qui va simplement exécuter l’une après l’autre chacune de tes deux première fonction.

Ensuite à la déclaration de chaque objet tu lui donne tes deux fonctions et tu appelle ta fonction membre sur tes entiers/réelles/etc.

Donc je sais que c’est possible en C++ (avec de la généricité tu dois encore pouvoir améliorer la chose. Probablement en Objective-C.

Mais en C, mis à part avec un functor (que je connais très mal), je ne vois pas.

---

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986/3 "2016-02-20T18:38:17Z")

</div>

j’ai réflechi aussi à une directive préprocesseur, mais il faut aussi la variable dans la formule:

```auto

```

---

<div class="post-metadata">

**Author:** ![fran.b](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/d78d45/32.png) [@fran.b](https://www.debian-fr.org/u/fran.b)\
**Post date:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986/4 "2016-02-20T18:38:22Z")

</div>

Il est possible de faire une structure:

`structure fonction {
int type;
struct *fonction;
int (*f)();
}
 `

si g est une telle structure, si g.type=0, eval(g,x) renvoit x sinon eval(g,x) renvoit (g-\>f)(eval(g-\>fonction,x)), ça marche mais ça n’est pas terrible, c’est mon usine à gaz… Je ne pense pas qu’il y ait plus simple.

---

<div class="post-metadata">

**Author:** ![Tycho\_Brahe](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/ec9cab/32.png) [@Tycho\_Brahe](https://www.debian-fr.org/u/Tycho_Brahe)\
**Post date:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986/5 "2016-02-20T18:38:31Z")

</div>

Salut,

Ce genre de soucis m’intéresse également et je me suis donc renseigné de mon côté. L’on m’a conseillé de stocker les pointeurs sur fonction dans une structure, j’en ai tiré ceci. C’est sans doute plus long mais l’utilisation me semble relativement simple.

[code]typedef struct s\_comp  
{  
int (\*f)();  
int (\*g)();  
} t\_comp;

void set\_compose(t\_comp \*c, int (\*f)(), int (\*g)())  
{  
c-\>f = f;  
c-\>g = g;  
}

int do\_compose(t\_comp \*c, int i)  
{  
return (c-\>f(c-\>g(i)));  
}[/code]

Et un petit exemple d’utilisation pour la route :

[code]int f(int i)  
{  
return (++i);  
}

int g(int i)  
{  
return (i + 5);  
}

int main()  
{  
int i;  
t\_comp c;

i = 0;  
set\_compose(&c, &f, &g);  
printf(“i=%d\nfog(i)=%d\n”, i, do\_compose(&c, i));  
return (0);  
}[/code]

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:38 UTC](https://www.debian-fr.org/t/composition/16986/6 "2016-02-20T18:38:52Z")

</div>

@Tycho Brahe\> C’est marrant c’est la version non-objet de ce que je proposais 🙂

---

<div class="post-metadata">

**Author:** ![Tycho\_Brahe](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/ec9cab/32.png) [@Tycho\_Brahe](https://www.debian-fr.org/u/Tycho_Brahe)\
**Post date:** [Février 20, 2016, 6:39 UTC](https://www.debian-fr.org/t/composition/16986/7 "2016-02-20T18:39:04Z")

</div>

> [@](#):
>
> @Tycho Brahe\> C’est marrant c’est la version non-objet de ce que je proposais 🙂

En effet, la seule différence est dans la conclusion 😛 Je devais être sacrément crevé pour oublier un post en quelques heures.

---

<div class="post-metadata">

**Author:** ![fran.b](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/d78d45/32.png) [@fran.b](https://www.debian-fr.org/u/fran.b)\
**Post date:** [Février 20, 2016, 6:39 UTC](https://www.debian-fr.org/t/composition/16986/8 "2016-02-20T18:39:08Z")

</div>

Voilà ce que donne un peu de programmation fonctionnel en C mais c’est du bricolage, recursif(estnul,fact\_zero,moins\_un,ex\_fact,n) calcul n! uniquement à l’aide des 4 fonctions utile pour la récursion, eval(compose(moins\_un,&Moins\_un),15) calcule la composée de moins\_un avec moins\_un sur 15. Quand on voit la facilité avec laquelle ça s’écrit en Caml, on voit la différence entre les langages…

[code]#include \<stdio.h\>  
#include \<unistd.h\>  
#include \<malloc.h\>

/\* structure d’une fonction \*/

struct fonction {  
int type; /\* si = 1, c’est f, sinon c’est f o suite \*/  
struct fonction \*suite;  
int (\*f)();  
};

/\* fonctions définissant factorielle \*/  
int estnul(x)  
int x;  
{  
return(x==0);  
}

int fact\_zero(x)  
int x;  
{  
return(1);  
}

int moins\_un(x)  
int x;  
{  
return(x-1);  
}

int ex\_fact(x,y)  
int x;  
int y;  
{  
return(x\*y);  
}

/\* evaluation d’une fonction en x \*/  
int eval(g,x)  
struct fonction \*g;  
int x;  
{  
if (g-\>type) return((g-\>f)(x));  
else return((g-\>f)(eval((g-\>suite),x)));  
}

/\* composition \*/  
struct fonction \*compose(f,g)  
int (\*f)();  
struct fonction \*g;  
{  
struct fonction \*res;  
res=(struct fonction \*)malloc(sizeof(struct fonction));  
res-\>type=0;  
res-\>suite=g;  
res-\>f=f;  
return(res);  
}

/\* fabrication d’une fonction récursive avec les 4 fonctions \*/  
int recursif(t,g,h,ex,x)  
int (\*t)();  
int (\*g)();  
int (\*h)();  
int (\*ex)();  
int x;  
{  
if ((\*t)(x)) return((\*g)(x));  
else return((\*ex)(x,recursif(t,g,h,ex,(\*h)(x))));  
}

/\* essai \*/  
main(argc,argv)  
int argc;  
char \*\*argv;  
{  
struct fonction Moins\_un;  
struct fonction Estnul;  
struct fonction Fact\_zero;

Moins\_un.type=1;  
Moins\_un.f=moins\_un;

Estnul.type=1;  
Estnul.f=estnul;

Fact\_zero.type=1;  
Fact\_zero.f=fact\_zero;  
printf("%d\n",eval(compose(moins\_un,&Moins\_un),15));  
printf("%d\n",recursif(estnul,fact\_zero,moins\_un,ex\_fact,10));  
}  
[/code]  
reste plus qu’à dérécursifier en utilisant la structure, un peu pénible en fait…

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/9 "2016-02-20T18:40:16Z")

</div>

C’est bien pour ça qu’il existe différent langages.

J’en profite pour vous montrer une technique que j’ai appris cette semaine pour calculer un factoriel n! quand le n est connu à la compilation (je vous donne directement le lien) : [Métaprogrammation avec des patrons](http://fr.wikipedia.org/wiki/M%C3%A9taprogrammation_avec_des_patrons#Calcul_de_constantes)

Je trouve ça vachement intéressant, même si je ne suis pas sur que beaucoup de langages permettent ce genre de technique.

---

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/10 "2016-02-20T18:40:21Z")

</div>

finalement, c’est quand même tellement mieux, le perl:

[code]#!/usr/bin/perl

sub compose {  
my ($f,$g,@reste)=@_;  
my $O = sub { return &$f(&$g(@_)); };  
return @reste ?  
compose($O, @reste) :  
$O;  
}

$presente = sub { return "le resultat est ".shift; };  
$ident = sub { return shift; };  
$carre = sub { my $arg = shift; return $arg\*$arg; };

$f = compose($ident,$ident);  
$g = compose($presente,$carre,$carre);

print “f(10) : “.&$f(10).”\n”;  
print “g(10) : “.&$g(10).”\n”;[/code][quote]roc@ROC:~$ ./test.pl  
f(10) : 10  
g(10) : le resultat est 10000[/quote]

---

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/11 "2016-02-20T18:40:21Z")

</div>

et il y a aussi des templates: [perldoc.perl.org/perlref.html#Function-Templates](http://perldoc.perl.org/perlref.html#Function-Templates)

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/12 "2016-02-20T18:40:22Z")

</div>

L’une des idées de la metaprogrammation c’est que le calcul est fait à la compilation du coup l’exécution du programme est plus rapide.

---

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/13 "2016-02-20T18:40:22Z")

</div>

Mouais. De nos jours, la diffèrence compilé/pcode/interprèté n’est pas forcément super sensible.  
Et parfois on préfère un programme lisible moins rapide qu’un code obscur compilé.

J’ajouterais que je ne vois pas à quoi peut servir une fonction de composition, si ce n’est pas pour composer des fonctions fournies (et interprètées) à l’exécution. Sinon, tu codes directement ta fonction composée, tu ne t’amuse pas à l’objetiser.

Et j’ajouterais: tu codes comment en C la composition d’une fonction qui caste n’importe quoi en chaine avec une fonction numérique ?

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/14 "2016-02-20T18:40:35Z")

</div>

La composition est une notion mathématiques. On considère des nombre en fonction des programmes tu prendras des entiers ou des nombres à virgules flottante. Son utilité peut se ressentir quand tu veut faire un programme qui réalise un calcule mathématiques et que pour des raison de lisibilité ( ![:mrgreen:](https://www.debian-fr.org/uploads/default/original/1X/cc83e9b583138e48ff45f96609046b06d06c7f9d.gif "Mr. Green") ) tu veut garder la sémantique initiale. Ou alors si à l’écriture du programme tu ne connais pas les deux fonctions de ta composition.

Le fait que la différence entre code compilé vers du langage machine, du byte code ou juste à temps ne se fait pas sentir dans des petits programmes, n’indique pas que tu n’es pas le résultat d’un calcul très lourd dont tu te sers un grand nombre de fois dans le programme, trop complexe ou trop long à calculer à la main et que le passage par des variables globales pose des problèmes dans une optique multitâche bridant encore d’avantage les performances globales du programme. En tout cas j’avais montré ça juste pour le fun parce que c’est rigolo de voir une méthode très différentes de ce que l’on trouve habituellement.

> [@](#):
>
> Et j’ajouterais: tu codes comment en C la composition d’une fonction qui caste n’importe quoi en chaine avec une fonction numérique ?

En C++ tu peut rendre ta composition générique à fin de spécialiser les traitement en fonction du type de variable traité. En C tu te réécris ta fcomposition pour qu’elle puisse gérer les NTCTS.

Je ne crois pas que le Caml soit objet donc tu devrais parler d’une “fonctionalisation”.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/15 "2016-02-20T18:40:35Z")

</div>

Dis moi matt, tu ne serais pas un sectaire du C et du perl à tout hasard ?

---

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/16 "2016-02-20T18:40:36Z")

</div>

[quote=“MisterFreez”]Dis moi matt, tu ne serais pas un sectaire du C et du perl à tout hasard ?[/quote] Non non, je bouffe à tous les rateliers. Ceux là et bien d’autres.  
Mais c’est vrai qu’en ce moment je mange essentiellement du perl, couplé avec du code C génèré avec du XML (XSLT) qui exploite une lib particulière en C pur ( [grep.be/articles/gnodbify](http://grep.be/articles/gnodbify) ), mais c’est fini de débuguer cette couche là et ce n’est pas moi qui en ai produit le code, c’est mon collègue Wouter. Je suis arrivé pour produire les interfaces WEB en CGI, parceque malgré sa compètence, se prendre la tête à génèrer du HTML/Javascript était vraiment au dessus de ses forces (et je le comprend, c’est la mort le HTML et le dom).

---

<div class="post-metadata">

**Author:** ![fran.b](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/d78d45/32.png) [@fran.b](https://www.debian-fr.org/u/fran.b)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/17 "2016-02-20T18:40:47Z")

</div>

[quote=“mattotop”]Mouais. De nos jours, la diffèrence compilé/pcode/interprèté n’est pas forcément super sensible.  
Et parfois on préfère un programme lisible moins rapide qu’un code obscur compilé.

J’ajouterais que je ne vois pas à quoi peut servir une fonction de composition, si ce n’est pas pour composer des fonctions fournies (et interprètées) à l’exécution. Sinon, tu codes directement ta fonction composée, tu ne t’amuse pas à l’objetiser.

Et j’ajouterais: tu codes comment en C la composition d’une fonction qui caste n’importe quoi en chaine avec une fonction numérique ?[/quote]

La composition peut avoir plusieurs intérêts en elle même (l’objection sur la fin n’a aucune possibilité d’arriver dans un langage fortement typé), mais c’est surtout pour illustrer que dans un langage fonctionnel, les fonctiosn sont identiques aux objets:

```auto

```

compose n’importe quel type de fonctions. Un programme peut évoluer. C’est encore plus simple en Lisp mais le langage n’est pas typé.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/18 "2016-02-20T18:40:50Z")

</div>

> [@](#):
>
> (l’objection sur la fin n’a aucune possibilité d’arriver dans un langage fortement typé)

Pourquoi ? La généricité le permet, non ?

---

<div class="post-metadata">

**Author:** ![fran.b](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/f/d78d45/32.png) [@fran.b](https://www.debian-fr.org/u/fran.b)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/19 "2016-02-20T18:40:56Z")

</div>

Non:

`#let compose f g = function x -> f (g x);;
compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
#`  
compose ne compose que des fonctions à un argument: g envoyant du type `c sur du type`a, puis `f envoyant du type`a vers du type `b et produit une fonction 'c -\> 'b:

[code]  
#let add3 = add\_int 3;;  
add3 : int -\> int =   
#add3 4;;

- : int = 7  
#compose add3;;
- : (’\_a -\> int) -\> '\_a -\> int =   
#let concat s = s^“rajout”;;  
concat : string -\> string =   
#concat “matt”;;
- : string = “mattrajout”  
#compose add3 concat;;  
Toplevel input:

> compose add3 concat;;  
> ^^^^^^  
> This expression has type string -\> string,  
> but is used with type string -\> int.  
> #[/code]  
> Voilà ce que ça donne…

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 20, 2016, 6:40 UTC](https://www.debian-fr.org/t/composition/16986/20 "2016-02-20T18:40:58Z")

</div>

C’est donc possible avec de la généricité.

[code]template\<typename A, typename R\>  
R fonction1(A var){  
// premier traitement  
}

template\<typename A, typename R\>  
R fonction2(A var){  
// second traitement  
}[/code]  
Avec le type de retour du premier en type, d’argument du second.  
A la compilation, il y a vérification que tes types soient valides et utilisés correctement.

[Page suivante](https://www.debian-fr.org/t/composition/16986.md?page=2)
