309 votes

Quelle est la différence entre la programmation procédurale et la programmation fonctionnelle ?

J'ai lu les articles de Wikipedia pour les deux programmation procédurale y programmation fonctionnelle mais je suis toujours un peu confus. Quelqu'un pourrait-il en faire l'essentiel ?

0 votes

Wikipedia implique que la PF est un sous-ensemble (c'est-à-dire qu'elle est toujours) de la programmation déclarative, mais que n'est pas vrai et confond la taxonomie de l'IP et du DP. .

177voto

Konrad Rudolph Points 231505

Un langage fonctionnel (idéalement) permet d'écrire une fonction mathématique, c'est-à-dire une fonction qui prend n arguments et renvoie une valeur. Si le programme est exécuté, cette fonction est évaluée logiquement selon les besoins. 1

Un langage procédural, en revanche, effectue une série de séquentiel étapes. (Il existe une façon de transformer la logique séquentielle en logique fonctionnelle appelée poursuite du style de passe .)

En conséquence, un programme purement fonctionnel produit toujours la même valeur pour une entrée, et l'ordre d'évaluation n'est pas bien défini ; ce qui signifie que les valeurs incertaines comme les entrées utilisateur ou les valeurs aléatoires sont difficiles à modéliser dans des langages purement fonctionnels.


1 Comme tout le reste dans cette réponse, c'est une généralisation. Cette propriété, qui consiste à évaluer un calcul lorsque son résultat est nécessaire plutôt que séquentiellement lorsqu'il est appelé, est connue sous le nom de "paresse". En fait, tous les langages fonctionnels ne sont pas universellement paresseux, et la paresse ne se limite pas à la programmation fonctionnelle. La description donnée ici fournit plutôt un "cadre mental" pour penser aux différents styles de programmation qui ne sont pas des catégories distinctes et opposées mais plutôt des idées fluides.

10 votes

Les valeurs incertaines comme les entrées utilisateur ou les valeurs aléatoires sont difficiles à modéliser dans les langages purement fonctionnels, mais c'est un problème résolu. Voir les monades.

0 votes

" étapes consécutives où le programme fonctionnel serait imbriqué" signifie qu'il faut prévoir la séparation des préoccupations en mettre l'accent sur la composition des fonctions c'est-à-dire la séparation des dépendances entre les sous-calculs d'un calcul déterministe.

0 votes

Cela semble erroné - les procédures peuvent aussi être imbriquées, les procédures peuvent avoir des paramètres

106voto

Brad Gilbert Points 12724

En fait, les deux styles sont comme le Yin et le Yang. L'un est organisé, tandis que l'autre est chaotique. Dans certaines situations, la programmation fonctionnelle est le choix le plus évident, et dans d'autres, la programmation procédurale est le meilleur choix. C'est pourquoi il y a au moins deux langages qui sont sortis récemment avec une nouvelle version, qui embrasse les deux styles de programmation. ( Perl 6 y D 2 )

Procedural:

  • La sortie d'une routine n'a pas toujours une corrélation directe avec l'entrée.
  • Tout est fait dans un ordre précis.
  • L'exécution d'une routine peut avoir des effets secondaires.
  • Tendance à mettre l'accent sur la mise en œuvre de solutions de façon linéaire.

## Perl 6 ##

sub factorial ( UInt:D $n is copy ) returns UInt {

  # modify "outside" state
  state $call-count++;
  # in this case it is rather pointless as
  # it can't even be accessed from outside

  my $result = 1;

  loop ( ; $n > 0 ; $n-- ){

    $result *= $n;

  }

  return $result;
}

## D 2 ##

int factorial( int n ){

  int result = 1;

  for( ; n > 0 ; n-- ){
    result *= n;
  }

  return result;
}

Fonctionnel:

  • Souvent récursif.
  • Renvoie toujours la même sortie pour une entrée donnée.
  • L'ordre d'évaluation est généralement indéfini.
  • Doit être sans état, c'est-à-dire qu'aucune opération ne peut avoir d'effets secondaires.
  • Bonne adaptation à l'exécution parallèle
  • Tendance à privilégier l'approche "diviser pour mieux régner".
  • Peut avoir la fonction d'évaluation paresseuse.

## Haskell ## ( copié à partir de Wikipedia ) ;

fac :: Integer -> Integer

fac 0 = 1
fac n | n > 0 = n * fac (n-1)

ou en une seule ligne :

fac n = if n > 0 then n * fac (n-1) else 1

## Perl 6 ##

proto sub factorial ( UInt:D $n ) returns UInt {*}

multi sub factorial (  0 ) { 1 }
multi sub factorial ( $n ) { $n * samewith $n-1 } # { $n * factorial $n-1 }

## D 2 ##

pure int factorial( invariant int n ){
  if( n <= 1 ){
    return 1;
  }else{
    return n * factorial( n-1 );
  }
}

Side note:

Factorial est en fait un exemple courant pour montrer à quel point il est facile de créer de nouveaux opérateurs en Perl 6 de la même manière que vous créeriez un sous-programme. Cette fonctionnalité est tellement ancrée dans Perl 6 que la plupart des opérateurs de l'implémentation Rakudo sont définis de cette manière. Elle vous permet également d'ajouter vos propres candidats multiples aux opérateurs existants.

sub postfix:< ! > ( UInt:D $n --> UInt )
  is tighter(&infix:<*>)
  { [*] 2 .. $n }

say 5!; # 120

Cet exemple montre également la création de plages ( 2..$n ) et le méta-opérateur de réduction de liste ( [ OPERATOR ] LIST ) combiné avec l'opérateur de multiplication numérique infixe. ( * )
Cela montre aussi que vous pouvez mettre --> UInt dans la signature au lieu de returns UInt après elle.

( Vous pouvez vous en sortir en commençant la gamme avec 2 en tant qu'"opérateur" multiple retournera 1 lorsqu'il est appelé sans aucun argument )

0 votes

Bonjour, pouvez-vous s'il vous plaît fournir un exemple pour les 2 points suivants mentionnés pour "procédural" en considérant l'exemple de l'implémentation factorielle en Perl 6. 1) La sortie d'une routine n'a pas toujours une corrélation directe avec l'entrée. 2) L'exécution d'une routine peut avoir des effets secondaires.

0 votes

sub postfix:<!> ($n) { [*] 1..$n }

0 votes

@BradGilbert No operation can have side effects Pouvez-vous nous en dire plus ?

97voto

Omnimike Points 336

Je n'ai jamais vu cette définition donnée ailleurs, mais je pense qu'elle résume assez bien les différences données ici :

Fonctionnel La programmation est axée sur expressions

Procédure La programmation est axée sur déclarations

Les expressions ont des valeurs. Un programme fonctionnel est une expression dont la valeur est une séquence d'instructions à exécuter par l'ordinateur.

Les déclarations n'ont pas de valeurs et modifient plutôt l'état d'une machine conceptuelle.

Dans un langage purement fonctionnel, il n'y aurait pas d'énoncés, dans le sens où il n'y a aucun moyen de manipuler l'état (il pourrait toujours y avoir une construction syntaxique appelée "énoncé", mais à moins qu'elle ne manipule l'état, je ne l'appellerais pas un énoncé dans ce sens). Dans un langage purement procédural, il n'y aurait pas d'expressions, tout serait une instruction qui manipule l'état de la machine.

Haskell serait un exemple de langage purement fonctionnel car il n'y a aucun moyen de manipuler l'état. Le code machine serait un exemple de langage purement procédural, car tout dans un programme est une instruction qui manipule l'état des registres et de la mémoire de la machine.

La partie déroutante est que la grande majorité des langages de programmation contiennent ambos des expressions et des déclarations, ce qui vous permet de mélanger les paradigmes. Les langages peuvent être classés comme plus fonctionnels ou plus procéduraux en fonction de la mesure dans laquelle ils encouragent l'utilisation des instructions par rapport aux expressions.

Par exemple, le C serait plus fonctionnel que le COBOL parce qu'un appel de fonction est une expression, alors que l'appel d'un sous-programme en COBOL est une instruction (qui manipule l'état des variables partagées et ne renvoie pas de valeur). Python serait plus fonctionnel que C car il permet d'exprimer la logique conditionnelle sous forme d'expression en utilisant une évaluation en circuit court (test && path1 || path2 par opposition aux instructions if). Scheme serait plus fonctionnel que Python parce que tout dans Scheme est une expression.

Vous pouvez toujours écrire dans un style fonctionnel dans un langage qui encourage le paradigme procédural et vice versa. Il est simplement plus difficile et/ou plus délicat d'écrire dans un paradigme qui n'est pas encouragé par le langage.

3 votes

La meilleure et la plus succincte explication que j'ai vue sur le web, bravo !

1 votes

Le C dispose également d'expressions booléennes

0 votes

Très bonne explication. Commentaires : "Python serait plus fonctionnel que C parce qu'il permet d'exprimer la logique conditionnelle sous forme d'expression en utilisant une évaluation en circuit court (test && chemin1 || chemin2 par opposition aux instructions if)" En C, vous pouvez également faire test && path1 || path2 . "Les déclarations n'ont pas de valeurs et modifient plutôt l'état d'une machine conceptuelle." Difficile de trouver un exemple pour celui-ci, à moins que je ne comprenne mal cette définition. Par exemple return Je considère qu'il s'agit d'une déclaration, mais qu'à elle seule, elle ne modifie pas l'état.

85voto

54voto

jmfsg Points 18246

En informatique, la programmation fonctionnelle est un paradigme de programmation qui traite le calcul comme l'évaluation de fonctions mathématiques et évite l'état et les données mutables. Elle met l'accent sur l'application de fonctions, contrairement au style de programmation procédurale qui met l'accent sur les changements d'état.

4 votes

Bien que cette explication soit celle qui m'a le plus aidé, le concept de programmation fonctionnelle est encore flou pour moi. Je cherche un style de programmation qui ne dépend pas de la référence à des objets externes pour fonctionner (tout ce dont la fonction a besoin pour fonctionner doit être passé en paramètre). Par exemple, je ne mettrais jamais GetUserContext() dans la fonction, le contexte de l'utilisateur serait transmis. Est-ce de la programmation fonctionnelle ? Merci d'avance.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X