D'accord, si je comprends bien ce qui distingue une fonction d'une macro c'est le mode d'évalution des paramètres : pour une fonction ils sont passés par valeur, là où pour une macro ils sont passés par nom (dans ce cas l'évaluation est-elle paresseuse, i.e évalué une seule fois à la première utilisation du terme, ou recalculer à chaque usage du terme ?).
Par curiosité, dans ton exemple en OCaml tu écris ça :
(* je code le test if-then-else en fonctionnel pure *)letiffbe1e2=ifbthene1elsee2
Dans un langage comme Java ça ne marche pas parce que les expressions e1 et e2 seraient évaluées systématiquement avant d'être passées en paramètre à la fonction iff.
En Common Lisp ça marche si iff est une macro, ce qui permet de ne pas évaluer systématiquement les deux expressions avant de choisir le résultat à renvoyer.
En OCaml ça marche parce que le langage est purement fonctionnel et que le compilateur va se débrouiller pour n'évaluer que les expressions nécessaires ? Ou tu as fait un exemple simplifié ?
Comme l'a dit anaseto, en OCaml les paramètres sont passés par valeur, ils sont évalués par l'appelant avant d'être passés à la fonction appelée (à la manière des fonctions Lisp et non des macros). La seule exception concerne les opérateurs sur les booléens : && (et) et || (ou) qui sont évalués de gauche à droite et de façon paresseuse. Cela étant en Comme Lisp if est une macro ou une fonction ?
Comme l'a aussi précisé anaseto, il est possible de faire de l'évaluation paresseuse en OCaml via le module Lazy. Le même exemple (factoriel) avec iff en mode macro :
letle=(<=)andmul=(*)andminus=(-);;valle:'a->'a->bool=<fun>valmul:int->int->int=<fun>valminus:int->int->int=<fun>(* maintenant iff n'évalue que e1 ou que e2 suivant la valeur du booléen *)letiffbe1e2=ifbthenLazy.forcee1elseLazy.forcee2valiff:bool->'alazy_t->'alazy_t->'a=<fun>letrecfactorial?(acc=1)n=(iff(len1)(lazyacc)(lazy(factorial~acc:(mulaccn)(minusn1))))(* on pourrait utiliser (pred n) au lieu de (minus n 1) *)valfactorial:?acc:int->int->int=<fun>factorial5;;-:int=120
Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.
[^] # Re: C'est bien dommage
Posté par kantien . En réponse au journal C++17 est sur les rails. Évalué à 1.
D'accord, si je comprends bien ce qui distingue une fonction d'une macro c'est le mode d'évalution des paramètres : pour une fonction ils sont passés par valeur, là où pour une macro ils sont passés par nom (dans ce cas l'évaluation est-elle paresseuse, i.e évalué une seule fois à la première utilisation du terme, ou recalculer à chaque usage du terme ?).
Comme l'a dit anaseto, en OCaml les paramètres sont passés par valeur, ils sont évalués par l'appelant avant d'être passés à la fonction appelée (à la manière des fonctions Lisp et non des macros). La seule exception concerne les opérateurs sur les booléens : && (et) et || (ou) qui sont évalués de gauche à droite et de façon paresseuse. Cela étant en Comme Lisp
ifest une macro ou une fonction ?Comme l'a aussi précisé anaseto, il est possible de faire de l'évaluation paresseuse en OCaml via le module
Lazy. Le même exemple (factoriel) aveciffen mode macro :Sapere aude ! Aie le courage de te servir de ton propre entendement. Voilà la devise des Lumières.