Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Débats sur le développement - Le Best Of Discussion :

Pourquoi la programmation fonctionnelle n’est-elle pas la norme de l’industrie du code ?


Sujet :

Débats sur le développement - Le Best Of

  1. #81
    Inactif  
    Citation Envoyé par floyer Voir le message
    Indirectement, c’est important, puisque cela conditionne les performances. Ainsi, lorsque je trace une figure, autant que les fonctions de tracé (driver graphique), ne vérifient pas le type des paramètres à chaque pixel ce qui ferait tout ralentir. Mais effectivement c’est le résultat qui compte.

    Pour le programme appelant, cela dépend si ses performances sont importantes (une IHM qui répond en 0,01s ou 0,02s ne fera pas la différence), et sont conditionnées par les bibliothèques (90% du temps dans BLAS ou FFTW rendrait peu pertinent une optimisation au niveau des procédures appelantes. Un 10% dans les bibliothèques et on peut s’intéresser à optimiser le code ou prendre un meilleur langage).
    Tout à fait d'accord.

    Après le langage va conditionner les performances optimales que tu serais en droit d'attendre, mais on est bien d'accord que cela ne te donne aucune garantie de performances.

    Notamment quand tu parles d'optimiser le code ou de prendre un meilleur langage, je pense que les facteurs principaux à prendre en compte sont les appels systèmes, les I/O, la complexité des algorithmes, les mauvaises pratiques, etc. et que rien qu'avec cela je pense qu'on couvre une grande proportion des besoins d'optimisations.

  2. #82
    Expert confirmé
    Citation Envoyé par Neckara Voir le message
    L'implémentation semble être itérative, en simulant la récursivité via une stack (ce qui est assez commun) :
    L'implémentation de gnu oui. Celle de bsd non : https://github.com/freebsd/freebsd/b...stdlib/qsort.c

    Citation Envoyé par Neckara Voir le message
    D'ailleurs question stupide, pour un langage fonctionnel, comment les récursions sont gérées en interne ?
    Il passent comme des appels de fonctions avec tout ce que cela implique au niveau des registres CPU/la pile, ou c'est transformé dans une version itérative via une stack ?
    Il y a une pile d'appel mais en pratique la question ne se pose pas vraiment car on écrit généralement des tail recursions et le compilateur sait les optimiser sans avoir à stocker les appels récursifs.

    Citation Envoyé par Neckara Voir le message
    Ben prend n'importe quel classement des langages TIOBE, popularité, utilisation github, t'as pas beaucoup de langages fonctionnels dans le top.
    Le but de l'éducation supérieur c'est aussi de former à ce que les étudiants seront le plus probablement amené à utiliser.

    Ce n'est pas le rôle de l'éducation supérieur de prendre parti et de décider qu'il faut faire du fonctionnel parce que c'est le paradigme que j'aime.
    Déjà qu'on a pas le temps de creuser en détails tous les bon principes de développement (e.g. ssémantique d'entité/de valeur).
    En ce qui concerne l'université, son rôle n'est pas de former des experts dans quelques technos à la mode qui seront obsolètes deux ans plus tard, et les étudiants avec. Elle doit justement donner une culture plus génerale, de la réflexion et des concepts qui permettront aux étudiants de s'adapter et d'être créatif.
    Le fonctionnel est une discipline importante de l'informatique, au même titre que, par exemple, l'architecture des ordinateurs. Tout le monde ne manipule pas des registres CPU au quotidien mais c'est important de l'avoir au moins étudié.

  3. #83
    Expert confirmé
    Merci pour le lien. Cette implémentation est astucieuse. À chaque étape, après avoir décomposé le tableau en deux sous-tableaux, c'est le couple (pointeur de début, pointeur de fin) du sous-tableau le plus grand qui est ajouté dans la variable stack et l'algo continue sur l'autre sous-tableau. Du coup, on en déduit que le nombre d'éléments de stack ne dépassera pas le logarithme de base 2 de la taille du tableau à trier. Et comme la taille du tableau à trier ne peut pas dépasser une certaine valeur (car c'est un entier de taille fixe), on peut choisir de représenter stack sous la forme d'un tableau avec une taille fixe suffisamment grande (CHAR_BIT * sizeof(size_t) dans le code source actuel) pour qu'il n'y ait pas de risque d'overflow quand on ajoute un élément dans stack.

    Citation Envoyé par Neckara Voir le message
    D'ailleurs question stupide, pour un langage fonctionnel, comment les récursions sont gérées en interne ?
    Il passent comme des appels de fonctions avec tout ce que cela implique au niveau des registres CPU/la pile, ou c'est transformé dans une version itérative via une stack ?
    Dans le cas particulier de la récursion terminale, le compilateur peut optimiser pour remplacer la récursion par une simple boucle while, sans encombrer la mémoire d'une "stack". Dans plusieurs langages comme Scheme et Haskell, cette optimisation est obligatoire pour être conforme au langage.

  4. #84
    Inactif  
    Citation Envoyé par SimonDecoline Voir le message
    L'implémentation de gnu oui. Celle de bsd non : https://github.com/freebsd/freebsd/b...stdlib/qsort.c
    C'est marrant parce qu'elle fait à la fois du récursif, et (je suppose, plus rarement) de l'itératif si d1 > d2 && d2 <= es && d1 > es (ligne 193).
    Je présume que es est "element size". d1 et d2 la taille des deux bouts du tableau (?).

    Citation Envoyé par SimonDecoline Voir le message
    Il y a une pile d'appel mais en pratique la question ne se pose pas vraiment car on écrit généralement des tail recursions et le compilateur sait les optimiser sans avoir à stocker les appels récursifs.
    Citation Envoyé par Pyramidev Voir le message
    Dans le cas particulier de la récursion terminale, le compilateur peut optimiser pour remplacer la récursion par une simple boucle while, sans encombrer la mémoire d'une "stack". Dans plusieurs langages comme Scheme et Haskell, cette optimisation est obligatoire pour être conforme au langage.
    Merci pour vos réponses.

    En recherchant un peu plus sur Google, je vois que le remplacement des tail recursions/récursion terminale par une simple boucle n'est pas supporté par tous les langages/interpréteurs/compilateurs.

    Je vais dire une bêtise, mais ne serait-il pas une bonne pratique d'éviter en général les fonctions récursives et d'écrire directement leur équivalent itératif ?
    Notamment parce qu'on a aucune garantie que la fonction récursive qu'on a écrit soit transformées, que ce soit à cause du non-support de cette fonctionnalité sur certains langages/interpréteurs/compilateurs, ou plus bêtement parce qu'on n'a pas écrit une fonction récursive terminale, à cause, e.g. d'un petit +1 qui s'est rajouté en fin.

    Ce que je veux dire c'est que le compilateur/intépréteur ne va a priori pas nous engueuler (ou lancer un warning) si la fonction récursive qu'on aura écrite n'est pas terminale ?

    Ou si je reformule, si les langages fonctionnels peuvent éventuellement encourager à la récursion, est-ce qu'ils ont des mécanismes pour s'assurer que la récursion sera transformée en itération ou d'insulter de développeur sinon ?

    Citation Envoyé par SimonDecoline Voir le message
    En ce qui concerne l'université, son rôle n'est pas de former des experts dans quelques technos à la mode qui seront obsolètes deux ans plus tard, et les étudiants avec.
    Enfin quand même.

    Si tu regardes les tops, c'est loin d'être des langages "à la mode" "obsolètes deux ans plus tard".
    C/C++, Python, Java, C#, JavaScript, R, HTML/CSS, PHP, SQL, shell, font parti des tops, pourtant ils sont là depuis un bon paquet d'années.

    Citation Envoyé par SimonDecoline Voir le message
    Elle doit justement donner une culture plus génerale, de la réflexion et des concepts qui permettront aux étudiants de s'adapter et d'être créatif.
    Je suis d'accord.

    Citation Envoyé par SimonDecoline Voir le message
    Le fonctionnel est une discipline importante de l'informatique, au même titre que, par exemple, l'architecture des ordinateurs. Tout le monde ne manipule pas des registres CPU au quotidien mais c'est important de l'avoir au moins étudié.
    J'ai envie de dire, l'ASM c'est une excuse pour étudier le fonctionnement hardware des ordinateurs.

    Pour le fonctionnel s'il n'est pratiquement pas utilisé en comparaison des autres langages/paradigmes, quel intérêt de le faire apprendre à la masse des étudiants ?
    Les quelques rares qui en auront besoin se spécialiseront et apprendront sur le tas.


    Déjà qu'on a un temps limité pour tout faire apprendre, et que tout n'est pas nécessairement retenu/maîtrisé.

    EDIT: Tiens si ça peut te rassurer, on a vu XSLT en ingé.
    Bon, cela nous a un peu traumatisé, mais on l'a vu.

    D'ailleurs ça me fait penser qu'on avait pas vu LaTeX, et que j'ai dû apprendre sur le tas à l'utiliser.
    À l'université, il y avait des rapports à rendre en LaTeX, mais il ne me semble pas qu'il y avait de cours LaTeX.

  5. #85
    Expert confirmé
    Citation Envoyé par Neckara Voir le message
    En recherchant un peu plus sur Google, je vois que le remplacement des tail recursions/récursion terminale par une simple boucle n'est pas supporté par tous les langages/interpréteurs/compilateurs.

    Je vais dire une bêtise, mais ne serait-il pas une bonne pratique d'éviter en général les fonctions récursives et d'écrire directement leur équivalent itératif ?
    Notamment parce qu'on a aucune garantie que la fonction récursive qu'on a écrit soit transformées, que ce soit à cause du non-support de cette fonctionnalité sur certains langages/interpréteurs/compilateurs, ou plus bêtement parce qu'on n'a pas écrit une fonction récursive terminale, à cause, e.g. d'un petit +1 qui s'est rajouté en fin.

    Ce que je veux dire c'est que le compilateur/intépréteur ne va a priori pas nous engueuler (ou lancer un warning) si la fonction récursive qu'on aura écrite n'est pas terminale ?

    Ou si je reformule, si les langages fonctionnels peuvent éventuellement encourager à la récursion, est-ce qu'ils ont des mécanismes pour s'assurer que la récursion sera transformée en itération ou d'insulter de développeur sinon ?
    Effectivement tous les compilateurs n'optimisent pas la tail recursion mais c'est quand même assez fréquent. Et comme le dit Pyramidev, certains langages (notamment fonctionnels) l'impose dans leur spec.
    Concernant le risque de transformer une tail recursion en non-tail recursion, c'est très peu probable car généralement les fonctions sont légèrement différentes : la version tail récursive a souvent un paramétre supplémentaire qui sert à accumuler les résultats au cours des appels successifs.
    Et encore une fois, en pratique on utilise souvent des fonctions de plus haut niveau comme map ou reduce, donc on a rarement à se préoccuper de ce genre de problème.


    Citation Envoyé par Neckara Voir le message
    Si tu regardes les tops, c'est loin d'être des langages "à la mode" "obsolètes deux ans plus tard".
    C/C++, Python, Java, C#, JavaScript, R, HTML/CSS, PHP, SQL, shell, font parti des tops, pourtant ils sont là depuis un bon paquet d'années.
    Oui, et justement ces langages sont beaucoup enseignés. Personnellement, je pense que c'est important d'enseigner les concepts (OO, fonctionnel...) plus que les technos. Je ne trouve pas très utile d'enseigner à la fois C# et Java; c'est important d'en connaitre un mais on arrivera à apprendre l'autre même si on ne l'a pas vu en cours.

    Citation Envoyé par Neckara Voir le message
    Pour le fonctionnel s'il n'est pratiquement pas utilisé en comparaison des autres langages/paradigmes, quel intérêt de le faire apprendre à la masse des étudiants ?
    Les quelques rares qui en auront besoin se spécialiseront et apprendront sur le tas.
    Justement non, à avis. Les concepts sont différents et c'est plus difficile d'apprendre le fonctionnel soi-même que de passer de C# à Java par exemple. En plus les principes du fonctionnels sont de plus en plus courants, même dans les langages "classiques". Enfin, le potentiel même du paradigme est un intérêt suffisant. Sinon, ce serait comme dire que l'objet ne sert à rien car le fortran des années 60 fait le job.

  6. #86
    Expert confirmé
    Citation Envoyé par Neckara Voir le message
    Je vais dire une bêtise, mais ne serait-il pas une bonne pratique d'éviter en général les fonctions récursives et d'écrire directement leur équivalent itératif ?
    Notamment parce qu'on a aucune garantie que la fonction récursive qu'on a écrit soit transformées, que ce soit à cause du non-support de cette fonctionnalité sur certains langages/interpréteurs/compilateurs, ou plus bêtement parce qu'on n'a pas écrit une fonction récursive terminale, à cause, e.g. d'un petit +1 qui s'est rajouté en fin.

    Ce que je veux dire c'est que le compilateur/intépréteur ne va a priori pas nous engueuler (ou lancer un warning) si la fonction récursive qu'on aura écrite n'est pas terminale ?

    Ou si je reformule, si les langages fonctionnels peuvent éventuellement encourager à la récursion, est-ce qu'ils ont des mécanismes pour s'assurer que la récursion sera transformée en itération ou d'insulter de développeur sinon ?
    Pour les langages qui ne garantissent pas l'optimisation de la récursivité terminale, il faut généralement privilégier l'itératif au récursif pour éviter les dépassements de pile. Les quelques cas où on utilise quand même la récursivité se limitent alors à quand l'équivalent en non récursif compliquerait le code, par exemple en manipulant une pile à la main, ce qui revient généralement plus ou moins à faire de la récursivité à la main.

    En pratique, même dans un langage fonctionnel, on n'écrit pas souvent soi-même de fonction récursive : on passe généralement par des fonctions de plus haut niveau dont les plus connues sont map, filter et reduce (parfois appelée fold). Dans un langage fonctionnel où l'optimisation de la récursivité terminale est obligatoire, ces fonctions de haut niveau seront typiquement implémentées sous forme de récursivité terminale. Dans d'autres langages, ces fonctions peuvent être implémentées de manière itérative.

    Citation Envoyé par Neckara Voir le message
    Pour le fonctionnel s'il n'est pratiquement pas utilisé en comparaison des autres langages/paradigmes, quel intérêt de le faire apprendre à la masse des étudiants ?
    Les quelques rares qui en auront besoin se spécialiseront et apprendront sur le tas.
    Le paradigme fonctionnel devient de moins en moins méconnu.

  7. #87
    Inactif  
    Merci pour vos réponses.


    Je comprends que le fonctionnel redevienne un peu à la mode ces temps ci, mais je ne suis pas sûr qu'il ai encore atteint un niveau suffisant pour justifier son enseignement dans le supérieur.
    Après je ne dis pas que dans 5 ou 10 ans il ne sera pas enseigné dans le supérieur, mais actuellement, je doute de l'intérêt de la chose.

    Vous voyez peut-être très bien l'intérêt du fonctionnel, mais vous ne semblez pas être très nombreux si on s'en réfère aux multiples classements de langages.


    Après pour le Java/C#, je ne sais pas si beaucoup de formations proposent les deux. Pour moi c'était C# (rapidement) à l'IUT et Java (rapidement aussi) en ingé.
    Ensuite, il faut bien se rappeler que le niveau des étudiants est très disparate et qu'on a un temps très limité pour tout leur apprendre.

  8. #88
    Expert confirmé
    Citation Envoyé par Neckara Voir le message
    Je comprends que le fonctionnel redevienne un peu à la mode ces temps ci, mais je ne suis pas sûr qu'il ai encore atteint un niveau suffisant pour justifier son enseignement dans le supérieur.
    Après je ne dis pas que dans 5 ou 10 ans il ne sera pas enseigné dans le supérieur, mais actuellement, je doute de l'intérêt de la chose.

    Vous voyez peut-être très bien l'intérêt du fonctionnel, mais vous ne semblez pas être très nombreux si on s'en réfère aux multiples classements de langages.
    C'est une analyse tout à fait valable mais qu'on peut développer. Les classements de langages sont une vision très partielle de la situation. Le fonctionnel n'est pas qu'un début de mode qui sera utilisable dans 10 ans, il est déjà bien présent. Par exemple, R et JavaScript s'inspirent de Scheme et quelqu'un qui vient du fonctionnel comprendra rapidement leur façon de gérer les fonctions, les arrows, les closures, reduce... De même, beaucoup de langages modernes sont clairement influencé par le fonctionnel : Scala, Rust, Julia... Et de plus en plus d'entreprise investissent dans le fonctionnel, par exemple OCaml a été repris par microsoft (avec F#) et par facebook (avec Reasonml); facebook a même du code Haskell et du code Erlang en production.

  9. #89
    Futur Membre du Club
    "mettent en avant le support du style fonctionnel en avant"
    "mettent en avant le support du style fonctionnel en avant" Qui publie encore sans se relire ?

  10. #90
    Expert éminent sénior
    Citation Envoyé par Neckara Voir le message
    (.../...)
    Enfin tout cela pour dire que, bien que la performance puisse être relativement importante en fonction du contexte, la différence de performances entre python/C++ (ou d'autres langages) n'est pas forcément aussi grosse.
    Sachant que si le client est très "radin", il va, je présume, aussi regarder le prix que vous lui proposez, or le temps de développement et compétences requises influencent ce prix.

    Donc je suis d'accord que la performance globale de ton programme importe, cependant, je ne suis pas sûr que le langage utilisé soit le facteur le plus impactant.
    Tout à fait. J'ai cité ce point de mon job actuel juste pour souligner que la performance est essentielle dans certains contextes. Après, on est sur un marché vraiment bizarre : officiellement, on vend du progiciel; dans les faits, il n'y a pas deux hôpitaux (à part les tous petits) qui ont la même version. On vend du sur-mesure au prix du "sur l'étagère", avec un peu de consulting par dessus. Tout le monde perd de l'argent, sauf aux USA, et sur certains contrats énormes. A terme, le marché va s'éclaircir. Il y avait 14 concurrents à nos appels d'offre(en France) en 2016. Il y en aura 3 en 2020. Le client paye le produit, pas le service derrière. Si le produit est meilleur mais les serveurs sous l'eau, alors il change de fournisseur.

    (je sais, ce marché n'a aucun sens. Mais c'est bien l'état du marché, hors USA, encore une fois. Et peut-être Japon, mais on est pas présents, alors je sais pas).

    Citation Envoyé par Neckara Voir le message
    Totalement d'accord. Il faut optimiser les "bottle neck" en suivant la loi de Pareto.

    Par contre, il faut quand même regarder la complexité si l'algo a pour objectif d'être scalable. Notamment éviter les complexité trop grandes (exponentielles ou factorielles ) qui vont très vite exploser si on augmente le nombre d'entrée.
    Par chance, une augmentation de la volumétrie se ferait par augmentation du nombre d'agents - donc linéairement. Par définition du problème, encore une fois. Sur d'autres problèmes, similaires, mais non découpables, j'aurais eu des problèmes plus graves, en effet.

    Citation Envoyé par Neckara Voir le message
    Je ne saurais pas trop me prononcer sur ce point, je ne sais pas exactement ce que tu fais.

    Par exemple, est-ce qu'en procédural il n'y aurait pas des bibliothèques dédiées à ce que tu fais, est-ce qu'il y aurait des astuces tricky en procédural, ou est-ce que tu n'avais pas d'autres solutions ?
    Après, c'est peut-être possible en procédural, mais demanderait un temps de développement bien trop important (e.g. 5 ans) pour se rapprocher de ta solution que tu auras codé relativement rapidement (e.g. 1 mois).

    Bref, comme je ne sais pas ce que tu fais, je ne saurais trop quoi en dire.
    Des bibliothèques. En COBOL. Dans une grande banque Française obsédée par le contrôle de son code. Comment dire. Je te pardonne parce-que tu ne connais pas cet environnement, mais c'est une hypothèse inconcevable. Non, la seule alternative, c'était de faire du DB2(le SQL favori des grands comptes, à l'époque), et les lourdeurs administratives pour avoir le droit de créer une nouvelle table nous auraient conduits bien trop loin en terme de délais. Au final, j'ai passé 3 semaines à définir la solution exacte avec l'expert métier sur mes genoux, une loooongue journée à coder après avoir tout préparé(j'avais amené mon sandwich sur le bureau à 8h30 en arrivant, ce que je ne fais jamais), puis une grosse semaine à fignoler l'ensemble avec les retours de l'expert.

    C'était moins gros que ce que tu imagines, donc. Mais le dessin de l'algo ne tenait pas sur une page, malgré tout, un beau bébé quand même. D'habitude, je ne fait jamais ça, je code direct, et ça passe, j'ai assez de maîtrise, je peux improviser si je sais à peu près ou je vais. Mais là, non, je ne pouvais pas me permettre d'improviser, tout était préparé à l'avance.

    Mais si j'ai pu le fair en une journée, en effet, c'est bel et bien parce-que j'ai totalement ignoré les performances, et en termes de conception, c'était un algo de goret. C'est l'algo auquel nous sommes arrivés après 3 semaines de gribouillages pour trouver une solution qui réponde à son problème. Et il était à la puissance 4. Je me demandais combien de temps ça allait prendre, ma hantise, c'était de devoir faire des optimisations. Au final, il n'y a pas eu besoin. Un sacré soulagement. Si ça n'avait pas été le cas.....

    Citation Envoyé par fredoche Voir le message
    (j'ai parlé de scripts fonctionnels)
    Mais enfin je ne vais pas me battre là dessus. C'est l'esprit de chacun et sa capacité à appréhender ces concepts.

    En Cobol de toute façon pas de fonctionnel n'est-ce pas ?
    ah, désolé, ma formule était ambiguë. Fonctionnel dans le sens de métier, pas de programmation fonctionnelle. Je garnis la donnée, je la rapproche d'une autre, je garnis une autre donnée.....

    Citation Envoyé par Neckara Voir le message
    Après le langage va conditionner les performances optimales que tu serais en droit d'attendre, mais on est bien d'accord que cela ne te donne aucune garantie de performances.

    Notamment quand tu parles d'optimiser le code ou de prendre un meilleur langage, je pense que les facteurs principaux à prendre en compte sont les appels systèmes, les I/O, la complexité des algorithmes, les mauvaises pratiques, etc. et que rien qu'avec cela je pense qu'on couvre une grande proportion des besoins d'optimisations.
    Ce qui me fait penser... Les 5h30 d'I/O qu'on avait, si j'y avais pensé(au lieu de repomper l'existant en l'adaptant), j'aurais été chercher le fichier plat généré par les gens du référentiel, j'aurais fait une rupture entre mon fichier en entrée et ce référentiel, et ça aurait mis tout au plus quelques minutes en temps d'execution. Mais bon, quand on y pense des années après, ça ne compte pas. Ca m'aurait sans doute coûte une semaine de dev - assez vite rentabilisée à la maintenance. (oui, c'est une méthode fréquente en COBOL. Non, ça n'est pas de la programmation moderne. Oui ça marche. Non ça n'est pas beau. Oui c'est très, très performant. Non, je ne pense pas que j'aurais l'occasion de le refaire).
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  11. #91
    Inactif  
    Merci pour ta réponse.

    Citation Envoyé par el_slapper Voir le message
    Des bibliothèques. En COBOL. Dans une grande banque Française obsédée par le contrôle de son code. Comment dire. Je te pardonne parce-que tu ne connais pas cet environnement, mais c'est une hypothèse inconcevable. Non, la seule alternative, c'était de faire du DB2(le SQL favori des grands comptes, à l'époque), et les lourdeurs administratives pour avoir le droit de créer une nouvelle table nous auraient conduits bien trop loin en terme de délais. Au final, j'ai passé 3 semaines à définir la solution exacte avec l'expert métier sur mes genoux, une loooongue journée à coder après avoir tout préparé(j'avais amené mon sandwich sur le bureau à 8h30 en arrivant, ce que je ne fais jamais), puis une grosse semaine à fignoler l'ensemble avec les retours de l'expert.
    Donc les perfs ne sont pas liées directement au paradigme utilisé comme tu le disais précédemment, mais au contraintes très fortes que t'impose ton client ?
    Citation Envoyé par el_slapper
    A ce niveau, la puissance de la machine n'importe plus du tout. Un milliard de minutes, même en rajoutant du CPU, euh... Et justement, en utilisant des standards ensemblistes optimisés(genre SQL), on retombe sur des choses gérables en termes de performances. J'aurais eu bien du mal, avec du procédural, à approcher leurs performances, comme fredoche le dit si bien.

    Citation Envoyé par el_slapper Voir le message
    Ce qui me fait penser... Les 5h30 d'I/O qu'on avait, si j'y avais pensé(au lieu de repomper l'existant en l'adaptant), j'aurais été chercher le fichier plat généré par les gens du référentiel, j'aurais fait une rupture entre mon fichier en entrée et ce référentiel, et ça aurait mis tout au plus quelques minutes en temps d'execution.
    Tiens ça me fait penser que j'avais un collègue qui avait un code qui s'exécutait en 1 semaine.
    Je regarde, il fait constamment la lecture des mêmes fichiers, presque ligne par ligne.

    Je lui dit de tout lire les fichiers d'un coup et de garder en mémoire… paff 2 minutes d'exécutions.

  12. #92
    Membre expert
    Citation Envoyé par Neckara Voir le message

    Tiens ça me fait penser que j'avais un collègue qui avait un code qui s'exécutait en 1 semaine.
    Dis-moi pas qu'il passe un doctorat

  13. #93
    Membre confirmé
    Citation Envoyé par el_slapper Voir le message
    Pour faire presque aussi trollesque : la programmation fonctionnelle ne s'est jamais imposée parce-que c'est une bouse illisible par quiconque n'est pas son auteur.

    C'est triste parce-que c'est quand même carrément puissant, comme paradigme de programmation. Mais il faut une agilité intellectuelle exceptionnelle(ainsi qu'un entrainement spécifique) pour arriver à en tirer la substance. C'est bien plus exigeant que l'objet ou le procédural. Le programmeur moyen n'est pas armé pour faire face à un code en fonctionnel - alors qu'il peut être productif dans les autres paradigmes. C'est pourquoi la programmation fonctionnelle est vouée à rester une niche. Une niche surpuissante, mais une niche quand même. C'est bien d'avoir du fonctionnel en natif dans un langage - mais ça ne servira pas à la majorité.
    Je rejoins ton point de vue sur l'agilité intellectuelle requise. Quand j'ai commencé à programmer j'étais franchement incapable de comprendre le fonctionnel. J'avais déjà du mal à bien comprendre la prog de manière générale.
    Depuis l'arrivée de Java 8 et après quelques années d'expérience en POO je me rends de plus en compte de l'intérêt de la prog fonctionnelle. J'apprécie beaucoup la concision et de la simplicité qu'elle apporte. C'est ultra puissant, sécurisé, mais parfois compliqué voire impossible à mettre en oeuvre pour des cas très complexes. Mais pour moi ca demande quand même une certaine expérience et une vision clair du code qu'on souhaite atteindre. Je me rends compte que même en procédural, certaines personnes ne sont pas capables d'aller à l'essentiel : découpage correct des fonctions, algo correct mais parfois trop compliqué, et ce même pour des personnes qui sont compétentes. Je m'en rends compte en refatorant du code fait par ces personnes, parfois on cherche à faire compliqué au lieu de faire simple. De mon point de vue la prog fonctionnelle permet de faire simple du premier coup. C'est un peu plus long, mais quand c'est fait il ne reste que l'essentiel.

    Comme disait De Vinci : "La simplicité est la sophistication suprême"

  14. #94
    Inactif  
    Citation Envoyé par fredoche Voir le message
    Dis-moi pas qu'il passe un doctorat
    Je ne te dirais pas qu'il passe un doctorat.

    Je ne te parlerais pas non plus de la qualité de code d'un autre de mes collègue, à faire un bloc de 20 lignes qui prennent tout l'écran, pour un truc qui se réécrivait simplement en 2 lignes.

  15. #95
    Expert éminent sénior
    Citation Envoyé par Neckara Voir le message
    (.../...)Je ne te parlerais pas non plus de la qualité de code d'un autre de mes collègue, à faire un bloc de 20 lignes qui prennent tout l'écran, pour un truc qui se réécrivait simplement en 2 lignes.
    Et là, je vais te faire une réponse d'ingénieur : ça dépend. Ca dépend des 20 lignes et ça dépend des 2 lignes. Si sur les deux lignes tu as un empilement d'appels, de boucles, et d'opérateurs ternaires, je préfère encore les 20 lignes. Si les 20 lignes ressemblent à l'exemple suivant, c'est différent(code réellement vu, j'étais dans le métier depuis une poignée de mois, et je savais déjà que c'était atroce), et je compatis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    For i = 1 to 3
        Call TraitementNumerique(i)
    Next i
    For i = 4 to 6
        Call TraitementAlpha(i)
    Next i
    '(.../...)et on continue et on continue
    For i = 100 to 102
        Call TraitementNumerique(i)
    Next i
    For i = 103 to 105
        Call TraitementAlpha(i)
    Next i
    (et en fait, j'ai mis un call pour que l'exemple soit plus lisible, mais en vrai, c'était les mêmes 4 lignes du traitement numérique - ou les mêmes 5 lignes du traitement alpha - qui étaient tout le temps répétées - de toutes façons, de bêtes formules EXCEL auraient fait mieux.....).

    Quand on a fait face à ce genre de "professionnels", on comprend mieux la réaction de JackJnr : des gens qui pondent ça ne sont pas au niveau pour faire du fonctionnel. Ce qui est terrible, c'est que les 600 lignes que j'ai imitées marchaient et faisaient le boulot. Si VBA avait été purement fonctionnel, jamais ces gens n'auraient réussi à triturer leurs données comme ils avaient besoin. Mais toi qui parlait de scalabilité au dessus, je ne te fais pas un dessin sur la scalabilité de ce monstre.
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  16. #96
    Inactif  
    Citation Envoyé par el_slapper Voir le message
    Et là, je vais te faire une réponse d'ingénieur : ça dépend. Ca dépend des 20 lignes et ça dépend des 2 lignes. Si sur les deux lignes tu as un empilement d'appels, de boucles, et d'opérateurs ternaires, je préfère encore les 20 lignes.
    Non, c'était deux lignes très simples, pas d'appels de fonctions, pas de ternaires.

    Un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if(cond1)
        c = n;
    else if(cond2)
        d = m;
    else
        c = m;
        d = n;
    
    liste1.add([max(a, b), value])
    x = (c+d*e)/(f+1)
    liste2.add([x, value])
    Le problème c'est que ce code était initialement c/c 3 fois, avec un if/else pour chaque bloc au lieu du max et des lignes à rallonge :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    if(cond1)
        if(a > b)
             liste1.add([a, value])
         else
             liste1.add([b, value])
         x = (c+d*e)/(f+1)
         liste2.add([x, value])
    else if(cond2)
        if(a > b)
             liste1.add([a, value])
         else
             liste1.add([b, value])
        liste1.add([max(a, b), value])
         x = (c+d*e)/(f+1)
         liste2.add([x, value])
    else
        if(a > b)
             liste1.add([a, value])
         else
             liste1.add([b, value])
        liste1.add([max(a, b), value])
         x = (c+d*e)/(f+1)
         liste2.add([x, value])
    Le tout avec des variables à rallonge comme xMoyMinCpt[maVariable][CompteurMachin][0], avec 3 par lignes ça te rempli ton écran.

    Impossible de comprendre ce que le code faisait en le lisant.
    J'ai réussi à la simplifier, c'est plus clair, mais toujours pas parfaitement compréhensible, par exemple comme je ne sais pas ce qu'il faisait les noms de variables que j'ai choisi ne sont pas assez explicite, et je pense que l'algorithme en lui-même pourrait être simplifié.

  17. #97
    Expert éminent sénior
    Je vois.

    au final, ça rejoint ma conclusion : certaines personnes ont l'esprit trop embrouillé pour faire du fonctionnel.
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  18. #98
    Membre habitué
    Je serais enclin à considérer que la programmation fonctionnelle s’applique bien dans certains cas (usage de fonctions ayant un/des fonctions en paramètres : map, filter...), mais pas dans d’autres. Si je résume l’algorithme de recherche d’envelope convexe, c’est 1/ rechercher le point qui minimise un critère (angle depuis le segment précédent), 2/ ajout de ce point à la liste, 3/ recommencer. Le 2/ est typiquement non «*fonctionnel*», (un ajout d’un point à la liste, le marquer pour qu’il ne soit pas choisi à nouveau : donc deux modifications) et en Haskell, langage fonctionnel pur, il me faudrait typiquement passer par des monades et son opérateur >>= j’en devine beaucoup qui seraient largués. (Et que dire de l’algorithme Dancing Link de Knuth qui ne procède que par des modifications de listes doublement chainées).

    Du coup, un langage avec plusieurs paradigmes me semble préférable : la programmation fonctionnelle pour ce qui s’y applique bien, et la programmation procédurale ou objet pour ce qui s’y applique. Je note que des langages objets ont convergé vers le fonctionnel depuis quelques temps si ce n’est déjà fait depuis la genèse (Java 8, C++ 14). Le C# avait des delegate depuis le début. Pour les lambda functions, je ne sais pas depuis quand cela date.

    Au delà des lambda functions, la programmation fonctionnelle nécessite les bonnes bibliothèques. Typiquement les méthodes map, filter et autres. Même si en théorie, ont peut les redéfinir.

  19. #99
    Inactif  
    Question stupide :

    En quoi maListe.count_if( x -> x = 2 ); serait plus de la programmation fonctionnelle que de la programmation orienté objet ?

  20. #100
    Membre habitué
    Citation Envoyé par Neckara Voir le message
    Question stupide :

    En quoi maListe.count_if( x -> x = 2 ); serait plus de la programmation fonctionnelle que de la programmation orienté objet ?
    La programmation fonctionnelle se définit par l'usage de fonction comme valeur utilisable au même titre que 2 ou 42 (comme ici x -> x = 2), mais surtout, une approche sans effet de bord (modification de variable par exemple. Dans l'exemple, il n'y en a pas).

    Un for (auto elem : maListe) { if(elem == 2) count++; } fonctionne avec un effet de bord est n'est pas une approche fonctionnelle.

    Cependant, ici, le count_if est porté par la liste (classe List), il peut y avoir du polymorphisme. La méthode choisie pouvant dépendre du type de la classe (ArrayList, LinkedList…). On aurait bien une approche objet.

    Du coup, on peut très bien avoir une expression multiparadigme. Inutile de chercher si cela tient plus de l'un que de l'autre.

    (En Java, on a maListe.stream().filter(x -> x==2).collect(Collectors.counting()); )

    Après, il faut voir l'ensemble du programme. Avec des structures modifiables (tableaux, dictionnaires, etc...), Java oriente la programmation vers une approche qui n'est pas fonctionnelle, même si Java 8 a ajouté des approches fonctionnelles. Ainsi, les structures Java sont modifiables, ce qui n'est pas le cas des list et des Map d'Ocaml par exemple dont la fonction d'addition retourne une nouvelle Map. Ainsi, un IntMap.(empty |> add 42 "hello") ne va pas modifier la constante empty (heureusement !). C'est donc une différence importante de l'environnement (plus que du langage, on pourrait créer un objet Java équivalent à Map).

###raw>template_hook.ano_emploi###