Fonction curryfieea

Signaler
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
-
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
-
Bonjour

Suite a un troll assez etonnant (ocaml vs C), j'ai pose comme defis a quelqu'un de coder la fonction : add de ocaml (+) en C...
en ocaml, on la defini comme ca :
# let add x y = x+y;;
val add : int -> int -> int = <fun>
Cette fonction est curryfiee :
# let increment = add 1;;
val increment : int -> int = <fun>

en C, j'ai beau y reflechir, je ne vois pas comment je pourrais definir une fonction add qui prenne comme parametres un entier, et qui renvoie une fonction qui prend comme parametre un entier et qui renvoie la somme des deux entiers...
/**
* @author coucou747 <coucou747@hotmail.com>
* @see irc://cominweb.uni-irc.net/#programmation
*/

7 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
15
Salut,


Je connais rien aux chameaux (Je sors...) et j'ai rien compris.


Le caml évaluera "increment 12" comme ceci ? :
increment 12
add 1 12
1 + 12


Le C, c'est pas du fonctionnel, donc stupidement :
int add(int x, int y) { return x+y; }
int increment(int x) { return add(x, 1); }


Ma solution passe par des macros :
#include <stdio.h>

#define add(x, y) x + y
#define increment(x) add(x, 1)

int main(int argc, char** argv)
{
printf("%d\n", increment(12));
return 0;
}
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
15
Pour ce qui est du troll, je dirais que l'on peut traduire n'importe
quel code caml en C, même si on perd l'esprit, la lisibilité ou la
densité du code au passage.


Par contre, je ne pense pas que l'on puisse traduire n'importe quel code C en caml (Même sans le connaître).


Par exemple, je suppose que le caml ne soit pas de ceux qui permettent ça (Adressage directe) :
#include <stdio.h>

int main(int argc, char** argv)
{
int * a;
a = (int *)12;
printf("%d\n", *a);
return 0;
}


Rarement utile, certe, mais parfois...
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
42
en ocaml t'as ce genre de trucs, t'en fais pas :)

la fonction que tu as donnee n'a rien d'une fonction curryfiee, en gros, en js, ca donne :

function add (x) {
    return function (y){
       return x+y;
    }
}

increment = add(1);

en C, tu peux renvoyer un pointeur sur fonction, mais pas en definissant le premier parametre... faut faire un chapot pour ca, mais entre un chapot et un truc curryfie, t'as une marge...

/**
* @author coucou747 <coucou747@hotmail.com>
* @see irc://cominweb.uni-irc.net/#programmation
*/
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
15
[citation]

en ocaml t'as ce genre de trucs, t'en fais pas :)

/citation


[citation de la doc]

Similarly, there is no
explicit handling of pointers: the Caml compiler silently introduces
pointers where necessary.

de la doc


Donc si tu pouvais s'il te plaît me faire une petite traduction... Sans link avec du C bien sûr.


Pour la curryfication en C, je vais approfondir un peu, mais je crois que je suis effectivement vaincu.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
42
personellement, je me suis concentre sur la partie fonctionelle du langage, les pointeurs, c'est quelquechose de parfaitement imperatif, mais j'avais deja vu ref dans le manuel :

http://www.ocaml-tutorial.org/the_structure_of_ocaml_programs

ici t'as des choses du genre, c'est pas la partie specialement interessante du langage...

le debat c'etait un truc genre : "est-ce-qu'en C, on peut faire tout ce que ocaml fait ?"

en C, on a ni types construits, ni pattern matching, on peut faire des fake trucs, mais ca n'aura ni la syntaxe, ni la philosophie du langage...

regarde l'exemple en ocaml ici :
http://www.codyx.org/snippet_interpolation-polynomiale_549.aspx

je l'ai refaite, de facon plus "libre", en ne me fixant pas a des int (la tu peux te dire "ok, en C tu fais des define dans un .h et tu peux aussi, c'est gore mais tu peux, en Cpp tu ferais des templates")

type 'a poly =
    Zero |
    Un |
    X |
    Add of 'a poly * 'a poly |
    Mult of 'a poly * 'a poly |
    Scal of 'a poly * 'a;;
(*On definit une fonction d'evaluation des polynomes*)let evaluation zero un add fois x polynome    let rec e function
        | Zero -> zero
        | Un -> un
        | X -> x
        | Add(a,b) -> add (e a) (e b)
        | Mult(a,b) -> fois (e a) (e b)
        | Scal(a,b) -> fois (e a) b
    in e polynome;
;;
(*On l'applique aux reels*)
let eval = evaluation 0. 1. (+.) ( *.);;

tu vois la fonction a la fin... eval = evaluation 0. 1. (+.) (  *.) ca applique l'evaluation aux floats...

en C, tu peux passer des pointeurs de fonctions, et des void pour 0 et 1... mais ca commence a devenir franchement atroce comme code... En Cpp, t'es sauve par les templates et l'overloading d'operateur, mais ca ne te fait pas tout... exemple. si plutot que d'additionner, je voulais multiplier, et plutot que de multiplier, je voulais additionner, en ocaml, je peux.... pas en Cpp, parce-qu'on ne passe pas encore de fonctions dans les templates...

/**
* @author coucou747 <coucou747@hotmail.com>
* @see irc://cominweb.uni-irc.net/#programmation
*/
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
15
Je vais t'exposer un peu plus mon avis sur la question, même si je sais
bien que je vais pas te convaincre de quoi que ce soit, et je t'en
voudrais pas de pas lire ce que j'ai écrit.


Pour moi en software, on peut faire tout ce que l'on veut dans les
limites du hardware. On peut pas demander à un PC de faire du café. On
peut pas demander à un PC de faire des calculs plus vite que son
horloge processeur.


Partant de là, le langage permettant de tout faire est l'assembleur.
Peu importe le niveau d'abstraction que l'on ajoute au dessus, le
résultat final est toujours une suite d'instructions executées par le
processeur, donc traduisible en un programme assembleur.  Donc à
la question "est-ce-qu'en ASM, on peut faire tout ce que ocaml fait ?",
je répondrais oui sans hésiter. Le source serait peut être 5000 fois
plus moche en ASM, que ce n'est pas mon problème. Il PEUT le faire.


Par contre, à la question "est-ce-qu'en C, on peut faire tout ce que le
ASM fait ?", je répondrais non. Car il y a des instructions ASM qui ne
sont pas reproduisible en pur C (sysenter, rdtsc, cpuid...).


Finalement je trouve qu'il y a deux problèmes : le peut et le aussi jolie.


Par exemple en C, on incrémente un pointeur simplement : i++.

On entend souvent dire que l'on ne peut pas en Delphi.

On peut :

i:= Pointer(Integer(i) + SizeOf(Integer));

Mais c'est loin d'être aussi jolie.

Par contre, l'ASM généré est strictement identique, et le créateur de
Delphi peut tout à fait argumenté sur les raisons pour lesquelles il
nous oblige à faire ça.


A l'inverse, en Java, on ne peut pas (A ma connaissance) traduire le code que je t'ai proposé de traduire.

Ce code est beaucoup plus bourrin que ce qui est fait habituellement
avec les pointeurs : on attribue directement une valeur au pointeur :
12. Autrement dit, le pointeur pointe sur le 12ième octet de
l'adressage virtuel du processus. Autrement dit sur une zone ou l'on a
certainement pas le droit ni de lire ni d'écrire.

Aussi jolie ou pas, là n'est pas la question : on ne peut
matériellement pas le faire en Java. Ce type de limitation est souvent
vécu comme une intense frustration. On sait que le hardware le permet,
mais le langage pas. On est dans une impasse, peu importe le temps que
l'on y passe et les moyens qu'on y mette. On ne peut pas forcer le
compilo Java à générer un code qui fera que la machine virtuelle Java
ira chercher ce douzième octet de la mémoire.


Donc pour reprendre le sujet...


"est-ce-qu'en C, on peut faire tout ce que ocaml fait ?"

Ma réponse est a priori oui.


Car du peu que j'ai vu du caml, l'ensemble des combinaisons
instructions ASM générable par ce langage est inclus dans l'ensemble de
celles générables via le C.

(Je ne crois pas que la réciproque soit vrai, mais c'est vrai que c'est un autre débat)


Mais à la question :

"est-ce-qu'en C, on peut faire tout ce que ocaml fait et de manière aussi jolie ?"

Ma réponse est non, et bien sûr que non.


C'est ce qui fait les charmes des langages par rapport à l'ASM. Ils
permettent d'écrire de manière plus jolie, ou disont plutôt différente
(Jolie est fort subjectif) certains algos ou l'ASM est "moins à l'aise".


C'est ce qui fait le charme de tous les langages les uns par rapport aux autres.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
42
c'etait pas tellement le C peut-il produire le meme resultat car la, evidement, je repond oui (mis a part que le ocaml peut se compiler en .class java mais c'est une autre histoire)

bref, la question etait plutot cote paradigme fonctionel : peut-on apprendre le fonctionnel en C...

/**
* @author coucou747 <coucou747@hotmail.com>
* @see irc://cominweb.uni-irc.net/#programmation
*/